/******************************************************************************* * Australian National University Data Commons * Copyright (C) 2013 The Australian National University * * This file is part of Australian National University Data Commons. * * Australian National University Data Commons is free software: you * can redistribute it and/or modify it under the terms of the GNU * General Public License as published by the Free Software Foundation, * either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package au.edu.anu.datacommons.util; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URLDecoder; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import au.edu.anu.datacommons.properties.GlobalProps; /** * Util * * Australian National University Data Commons * * Utility class * * JUnit coverage: None * * <pre> * Version Date Developer Description * 0.2 19/03/2012 Genevieve Turner (GT) Added isNotEmpty function. * 0.3 26/04/2012 Genevieve Turner (GT) Added convertArrayValueToList * 0.4 4/05/2012 Rahul Khanna (RK) Added generatePassword. * 0.5 24/07/2012 Genevieve Turner (GT) Added listToStringWithNewline * </pre> */ public final class Util { static final Logger LOGGER = LoggerFactory.getLogger(Util.class); public static void writeXmlToWriter(Document inDoc, Writer xmlWriter) { Transformer transformer; try { transformer = TransformerFactory.newInstance().newTransformer(); DOMSource source = new DOMSource(inDoc); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.METHOD, "xml"); transformer.transform(source, new StreamResult(xmlWriter)); } catch (TransformerConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (TransformerFactoryConfigurationError e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (TransformerException e) { // TODO Auto-generated catch block e.printStackTrace(); } return; } public static String getXmlAsString(Document inDoc) { StringWriter stringWriter = new StringWriter(); writeXmlToWriter(inDoc, stringWriter); return stringWriter.toString(); } /** * isNotEmpty * * Sets the options elements of the item * * Version Date Developer Description 0.1 13/03/2012 Genevieve Turner Initial build * * @param value * The value to check if the field is empty * @return Returns true if the value is not blank */ public static boolean isNotEmpty(String value) { if (value == null) { return false; } if (value.trim().equals("")) { return false; } return true; } /** * convertArrayValueToList * * Converts a map with a string array as a value to a list of strings * * <pre> * Version Date Developer Description * 0.3 26/04/2012 Genevieve Turner (GT) Initial add * </pre> * * @param map * A map to convert * @return The converted map */ public static Map<String, List<String>> convertArrayValueToList(Map<String, String[]> map) { Map convertedMap = new HashMap<String, List<String>>(); for (String key : map.keySet()) { String[] value = map.get(key); convertedMap.put(key, Arrays.asList(value)); } return convertedMap; } /** * generatePassword * * Australian National University Data Commons * * Generates a password of a specified length using characters specified in global properties. * * <pre> * Version Date Developer Description * 0.1 4/05/2012 Rahul Khanna (RK) Initial * </pre> * * @param length * Number of characters in password. * * @return Password as String. */ public static String generateRandomString(int length) { Random rand = new Random(); StringBuilder password = new StringBuilder(); // Get valid list of characters from global properties that the password can comprise of. char[] passwordChars = GlobalProps.getProperty(GlobalProps.PROP_PASSWORDGENERATOR_CHARS).toCharArray(); // Pick a random character from the character array and add it to the password until desired password length is reached. for (int i = 0; i < length; i++) password.append(passwordChars[rand.nextInt(passwordChars.length)]); return password.toString(); } /** * decodeUrlEncoded * * Decodes a url encoded string for example 'test%3a92' would return 'test:92' * * <pre> * Version Date Developer Description * 0.5 08/05/2012 Genevieve Turner (GT) Initial * </pre> * * @param encoded * Encoded string * @return Decoded string */ public static String decodeUrlEncoded(String encoded) { String decoded = null; try { decoded = URLDecoder.decode(encoded, "UTF-8"); } catch (UnsupportedEncodingException e) { LOGGER.error("Error urldecoding string: {}. Error: {}", encoded, e.getMessage()); } return decoded; } /** * listToStringWithNewline * * Converts a list of strings to a single string with a newline as a seperator * * <pre> * Version Date Developer Description * 0.5 24/07/2012 Genevieve Turner(GT) Initial * </pre> * * @param messages * @return */ public static String listToStringWithNewline(List<String> messages) { StringBuffer stringBuffer = new StringBuffer(); for (String message : messages) { stringBuffer.append(message); stringBuffer.append("\n"); } return stringBuffer.toString(); } /** * Returns a human-readable version of the file size, where the input represents a specific number of bytes. * Attempts to fix the following bug where a 1.99 GB file was returned as a 1 GB file. The logic below tries to * return 3 significant digits e.g. 123 MB, 12.3 MB or 1.23 MB. * * @see <a href="https://issues.apache.org/jira/browse/IO-226">https://issues.apache.org/jira/browse/IO-226</a> * @param size * size of file * @return human-readable file size as String */ public static String byteCountToDisplaySize(BigInteger size) { String displaySize; final BigDecimal sizeBD = new BigDecimal(size); if (size.divide(FileUtils.ONE_EB_BI).compareTo(BigInteger.ZERO) > 0) { displaySize = getThreeSigFigs(sizeBD.divide(new BigDecimal(FileUtils.ONE_EB_BI))) + " EB"; } else if (size.divide(FileUtils.ONE_PB_BI).compareTo(BigInteger.ZERO) > 0) { displaySize = getThreeSigFigs(sizeBD.divide(new BigDecimal(FileUtils.ONE_PB_BI))) + " PB"; } else if (size.divide(FileUtils.ONE_TB_BI).compareTo(BigInteger.ZERO) > 0) { displaySize = getThreeSigFigs(sizeBD.divide(new BigDecimal(FileUtils.ONE_TB_BI))) + " TB"; } else if (size.divide(FileUtils.ONE_GB_BI).compareTo(BigInteger.ZERO) > 0) { displaySize = getThreeSigFigs(sizeBD.divide(new BigDecimal(FileUtils.ONE_GB_BI))) + " GB"; } else if (size.divide(FileUtils.ONE_MB_BI).compareTo(BigInteger.ZERO) > 0) { displaySize = getThreeSigFigs(sizeBD.divide(new BigDecimal(FileUtils.ONE_MB_BI))) + " MB"; } else if (size.divide(FileUtils.ONE_KB_BI).compareTo(BigInteger.ZERO) > 0) { displaySize = getThreeSigFigs(sizeBD.divide(new BigDecimal(FileUtils.ONE_KB_BI))) + " KB"; } else { displaySize = String.valueOf(size) + (size.compareTo(BigInteger.ONE) != 0 ? " bytes" : " byte"); } return displaySize; } /** * Returns a human-readable version of the file size, where the input represents a specific number of bytes. * Attempts to fix the following bug where a 1.99 GB file was returned as a 1 GB file. The logic below tries to * return 3 significant digits e.g. 123 MB, 12.3 MB or 1.23 MB. * * @see <a href="https://issues.apache.org/jira/browse/IO-226">https://issues.apache.org/jira/browse/IO-226</a> * @param size * size of file * @return human-readable file size as String */ public static String byteCountToDisplaySize(long size) { return byteCountToDisplaySize(BigInteger.valueOf(size)); } private static String getThreeSigFigs(BigDecimal size) { String number = size.toString(); StringBuffer trimmedNumber = new StringBuffer(); int cnt = 0; boolean hasDecimal = false; for (final char digit : number.toCharArray()) { if (cnt < 3 || !hasDecimal) { trimmedNumber.append(digit); } if (digit == '.') { hasDecimal = true; } else { cnt++; } } String displaySize = trimmedNumber.toString(); if (hasDecimal) { while (displaySize.endsWith("0")) { displaySize = displaySize.substring(0, displaySize.length() - 1); } if (displaySize.endsWith(".")) { displaySize = displaySize.substring(0, displaySize.length() - 1); } } else { displaySize += ".00"; } return displaySize; } }