com.nridge.core.base.std.StrUtl.java Source code

Java tutorial

Introduction

Here is the source code for com.nridge.core.base.std.StrUtl.java

Source

/*
 * NorthRidge Software, LLC - Copyright (c) 2019.
 *
 * This program 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 com.nridge.core.base.std;

import com.nridge.core.base.field.Field;
import org.apache.commons.lang3.StringUtils;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Date;

/**
 * The StrUtl class provides utility methods for manipulating and
 * evaluating <i>String</i> objects. The goal of this class is to
 * centralize commonly used string manipulation methods and to
 * encourage code re-use.
 * <p>
 * The Apache Commons has a number of good utility methods for string
 * values.
 * http://commons.apache.org/proper/commons-lang/index.html
 * </p>
 * @author Al Cole
 * @version 1.0 Jan 2, 2014
 * @since 1.0
 */
@SuppressWarnings("UnusedDeclaration")
public class StrUtl {

    // The following constants are defined to aid in code documentation.

    public static final char CHAR_AT = '@';
    public static final char CHAR_DOT = '.';
    public static final char CHAR_COLON = ':';
    public static final char CHAR_PIPE = '|';
    public static final char CHAR_PLUS = '+';
    public static final char CHAR_SPACE = ' ';
    public static final char CHAR_COMMA = ',';
    public static final char CHAR_EQUAL = '=';
    public static final char CHAR_POUND = '#';
    public static final char CHAR_HYPHEN = '-';
    public static final char CHAR_DOLLAR = '$';
    public static final char CHAR_PERCENT = '%';
    public static final char CHAR_LESSTHAN = '<';
    public static final char CHAR_GREATERTHAN = '>';
    public static final char CHAR_AMPERSAND = '&';
    public static final char CHAR_QUESTMARK = '?';
    public static final char CHAR_UNDERLINE = '_';
    public static final char CHAR_SGLQUOTE = '\'';
    public static final char CHAR_DBLQUOTE = '"';
    public static final char CHAR_ASTERISK = '*';
    public static final char CHAR_SEMICOLON = ';';
    public static final char CHAR_BACKSLASH = '\\';
    public static final char CHAR_LEFTBRACKET = '[';
    public static final char CHAR_RIGHTBRACKET = ']';
    public static final char CHAR_FORWARDSLASH = '/';
    public static final char CHAR_PAREN_OPEN = '(';
    public static final char CHAR_PAREN_CLOSE = ')';
    public static final char CHAR_BRACKET_OPEN = '[';
    public static final char CHAR_BRACKET_CLOSE = ']';

    public static final String STRING_EQUAL = "=";
    public static final String STRING_HYPHEN = "-";
    public static final String STRING_AMPERSAND = "&";
    public static final String STRING_LESSTHAN = "<";
    public static final String STRING_GREATTHAN = ">";
    public static final String STRING_SGLQUOTE = "'";
    public static final String STRING_DBLQUOTE = "\"";
    public static final String STRING_NO = "no";
    public static final String STRING_YES = "yes";
    public static final String STRING_TRUE = "true";
    public static final String STRING_FALSE = "false";
    public static final String STRING_PAREN_OPEN = "[";
    public static final String STRING_PAREN_CLOSE = "]";
    public static final String STRING_BRACKET_OPEN = "[";
    public static final String STRING_BRACKET_CLOSE = "]";

    //http://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html

    public static final String CHARSET_UTF_8 = "UTF-8";
    public static final String CHARSET_UTF_16 = "UTF-16";
    public static final String CHARSET_US_ASCII = "US-ASCII";
    public static final String CHARSET_ISO_8859_1 = "ISO-8859-1";

    // Password related constants.

    public static final int STRUTL_PASSWORD_SIZE = 24;
    private static final int STRUTL_ROT13PW_SIZE = 25; // Net 24 characters
    private static final char STRUTL_CHAR_PWBEGIN = '<';
    private static final char STRUTL_CHAR_PWFINISH = '>';

    // Size in bytes to human readable format constants

    public static final double SIZE_IN_KB = 1024;
    public static final double SIZE_IN_MB = 1024 * SIZE_IN_KB;
    public static final double SIZE_IN_GB = 1024 * SIZE_IN_MB;
    public static final double SIZE_IN_TB = 1024 * SIZE_IN_GB;

    /**
     * Given a lowercase name, this method will make it a proper
     * name by capitalizing the first character.
     *
     * @param aName Lowercase name.
     *
     * @return Proper name.
     */
    public static String firstCharToUpper(String aName) {
        String properName = StringUtils.EMPTY;

        if (StringUtils.isNotEmpty(aName))
            properName = aName.substring(0, 1).toUpperCase() + aName.substring(1);

        return properName;
    }

    /**
     * Given a <i>boolean</i> value, return a string object representation of
     * its value.
     *
     * @param aFlag A boolean flag value.
     * @return <code>StrUtl.STRING_TRUE</code> or <code>StrUtl.STRING_FALSE</code>
     */
    public static String booleanToString(boolean aFlag) {
        if (aFlag)
            return StrUtl.STRING_TRUE;
        else
            return StrUtl.STRING_FALSE;
    }

    /**
     * Given a <i>String</i> object representing a boolean value of
     * <code>StrUtl.STRING_TRUE</code> or <code>StrUtl.STRING_FALSE</code>
     * it will return <i>true</i> or <i>false</i>.
     *
     * @param aString A non-empty string value.
     * @return <i>true</i> or <i>false</i> depending on <i>String</i>
     * value.
     */
    public static boolean stringToBoolean(String aString) {
        if (StringUtils.isNotEmpty(aString)) {
            if ((aString.equalsIgnoreCase(StrUtl.STRING_YES)) || (aString.equalsIgnoreCase(StrUtl.STRING_TRUE))
                    || (aString.equals("1")))
                return true;
        }
        return false;
    }

    /**
     * Remove all references to a character from a string.
     *
     * @param aString A source string.
     * @param aChar Identifies the character to remove.
     * @return A newly constructed  <i>String</i> object with all
     * the characters removed.
     */
    public static String removeAllChar(String aString, char aChar) {
        char ch;
        int strLength;
        StringBuilder strBuilder;

        if (StringUtils.isEmpty(aString))
            return aString;
        else {
            strLength = aString.length();
            strBuilder = new StringBuilder();
            for (int i = 0; i < strLength; i++) {
                ch = aString.charAt(i);
                if (ch != aChar)
                    strBuilder.append(ch);
            }

            return strBuilder.toString();
        }
    }

    /**
     * Removes a duplicate character (meaning it repeats two more more times)
     * from the string.
     *
     * @param aString A source string.
     * @param aChar A repeating character.
     *
     * @return Update string.
     */
    public static String removeDuplicateChar(String aString, char aChar) {
        int strLength;
        char prevChar, nextChar;
        StringBuilder strBuilder;

        if (StringUtils.isEmpty(aString))
            return aString;
        else {
            prevChar = 0;
            strLength = aString.length();
            strBuilder = new StringBuilder();
            for (int i = 0; i < strLength; i++) {
                nextChar = aString.charAt(i);
                if (nextChar == aChar) {
                    if (nextChar != prevChar)
                        strBuilder.append(nextChar);
                } else
                    strBuilder.append(nextChar);
                prevChar = nextChar;
            }

            return strBuilder.toString();
        }
    }

    /**
     * Trims the last character from the string.
     *
     * @param aString A source string.
     *
     * @return Trimmed string.
     */
    public static String trimLastChar(String aString) {
        char ch;
        int strLength;
        StringBuilder strBuilder;

        if (StringUtils.isEmpty(aString))
            return aString;
        else {
            strLength = aString.length();
            return aString.substring(0, strLength - 1);
        }
    }

    /**
     * Replaces all references to a character with a string.
     *
     * @param aSource A source string.
     * @param aChar Identifies the character to replace.
     * @param aReplacement A replacement string for the matching character.
     * @return A newly constructed  <i>String</i> object with all
     * the characters replaced.
     */
    public static String replaceCharWithString(String aSource, char aChar, String aReplacement) {
        char ch;
        int strLength;
        StringBuilder strBuilder;

        if (StringUtils.isEmpty(aSource))
            return aSource;
        else {
            strLength = aSource.length();
            strBuilder = new StringBuilder();
            for (int i = 0; i < strLength; i++) {
                ch = aSource.charAt(i);
                if (ch == aChar)
                    strBuilder.append(aReplacement);
                else
                    strBuilder.append(ch);
            }

            return strBuilder.toString();
        }
    }

    /**
     * Given a string and a desired width (think console presentation), this
     * method will pad the string with the appropriate number of space characters.
     *
     * @param aString A non-empty string.
     * @param aWidth The width of the presentation console (e.g. 80 characters).
     * @return A newly constructed  <i>String</i> object with the original
     * text centered for the <i>aWidth</i> value.
     */
    public static String centerSpaces(String aString, int aWidth) {
        StringBuilder strBuilder;
        int strLength, middleOffset;

        if (StringUtils.isEmpty(aString))
            return aString;
        else {
            strLength = aString.length();
            middleOffset = (aWidth / 2) - (strLength / 2);

            if ((strLength > 0) && (middleOffset > 0) && (strLength < aWidth)) {
                strBuilder = new StringBuilder();
                for (int i = 0; i < middleOffset; i++)
                    strBuilder.append(CHAR_SPACE);
                strBuilder.append(aString);
            } else
                strBuilder = new StringBuilder(aString);

            return strBuilder.toString();
        }
    }

    /**
     * Given a string and a starting offset position (within the string),
     * this method will identify the position (character offset) where
     * the last word in the string can be found.
     *
     * @param aString A non-empty string of words.
     * @param aPosition Starting offset to evaluate from.
     * @return The offset where the last word can be found or the value of
     * <i>-1</i> to signify that there were no space seperated words left in the
     * string.
     */
    public static int lastWordIndex(String aString, int aPosition) {
        int i;
        boolean isFound;

        if (StringUtils.isEmpty(aString))
            return -1;
        else {
            isFound = false;
            i = Math.min(aString.length(), aPosition) - 1;

            while ((!isFound) && (i >= 0)) {
                if (aString.charAt(i) == CHAR_SPACE)
                    isFound = true;
                else
                    i--;
            }

            if (isFound)
                return i;
            else
                return -1;
        }
    }

    /**
     * Given a string with a paragraph of words, a left margin pad size,
     * the width of the console or report page and an output stream, this
     * method will break the string into a formatted paragraph.
     *
     * @param aString A collection of words.
     * @param aLeftMargin Each line will be padded with this many spaces.
     * @param aLineWidth Identifies where characters should be wrapped.
     * @param aStream An output stream where each line will be written to.
     */
    public static void wrapToStream(String aString, int aLeftMargin, int aLineWidth, PrintStream aStream) {
        String subStr;
        boolean isDone;
        StringBuilder strBuilder;
        int strPos, wrapPos, startPos, strLength;

        if ((StringUtils.isEmpty(aString)) || (aStream == null))
            return;

        strLength = aString.length();
        aLineWidth = Math.max(10, aLineWidth);
        aLeftMargin = Math.max(0, aLeftMargin);

        strPos = 0;
        isDone = false;

        while ((!isDone) && (strPos < strLength)) {
            subStr = aString.substring(strPos);

            strBuilder = new StringBuilder();
            for (int i = 0; i < aLeftMargin; i++)
                strBuilder.append(CHAR_SPACE);

            startPos = 0;
            while (subStr.charAt(startPos) == CHAR_SPACE)
                startPos++;

            strBuilder.append(subStr.substring(startPos));

            if (strBuilder.length() < aLineWidth) {
                aStream.printf("%s%n", strBuilder.toString());
                isDone = true;
            } else {
                wrapPos = lastWordIndex(strBuilder.toString(), aLineWidth);
                if (wrapPos == -1)
                    break; // exception condition
                else {
                    aStream.printf("%s%n", strBuilder.substring(0, wrapPos));
                    strPos += wrapPos;
                }
            }
        }
    }

    /**
     * Uses a simple Caesar-cypher encryption to replace each English letter
     * with the one 13 places forward or back along the alphabet, so that
     * "The butler did it!" becomes "Gur ohgyre qvq vg!".   major advantage
     * of rot13 over rot(N) for other N is that it is self-inverse, so the
     * same code can be used for encoding and decoding.
     *
     * @param aString A plain text string to encode.
     * @return An encrypted <i>String</i> object.
     */
    public static String simple13Rotation(String aString) {
        char ch, chUp;
        int strLength;
        StringBuilder strBuilder;

        if (StringUtils.isEmpty(aString))
            return aString;
        else {
            strBuilder = new StringBuilder();

            strLength = aString.length();
            for (int i = 0; i < strLength; i++) {
                ch = aString.charAt(i);
                if (Character.isLetter(ch)) {
                    chUp = Character.toUpperCase(ch);
                    if ((chUp >= 'A') && (chUp <= 'M'))
                        ch += 13;
                    else
                        ch -= 13;
                }
                strBuilder.append(ch);
            }

            return strBuilder.toString();
        }
    }

    /**
     * Uses a simple Caesar-cypher encryption to replace each English letter
     * with the one 13 places forward or back along the alphabet, so that
     * "The butler did it!" becomes "Gur ohgyre qvq vg!".   major advantage
     * of rot13 over rot(N) for other N is that it is self-inverse, so the
     * same code can be used for encoding and decoding.
     * <p>
     * <i>Note: The returned string will be wrapped with the less-than and
     * greater-than characters to signify that they were encrypted by this method.
     * These wrappers will be expected when the string is recovered.</i>
     * </p>
     *
     * @param aStringPlain A plain text string to encode.
     * @return An encrypted <i>String</i> object.
     */
    public static String hidePassword(String aStringPlain) {
        char ch;
        boolean isAllUpper;
        StringBuilder strBuilder;
        int strLength, someNumber;

        if (StringUtils.isEmpty(aStringPlain))
            return aStringPlain;
        else {
            strBuilder = new StringBuilder();
            strLength = aStringPlain.length();
            if (strLength > STRUTL_ROT13PW_SIZE)
                strLength = STRUTL_ROT13PW_SIZE - 1;

            isAllUpper = true;

            for (int i = 0; i < strLength; i++) {
                ch = aStringPlain.charAt(i);
                if (Character.isLowerCase(ch)) {
                    isAllUpper = false;
                    break;
                }
            }

            strBuilder.append(STRUTL_CHAR_PWBEGIN);

            if (isAllUpper)
                ch = 'A';
            else
                ch = 'a';
            ch += strLength;
            strBuilder.append(ch);

            if (strLength > STRUTL_ROT13PW_SIZE)
                strBuilder.append(aStringPlain, 0, STRUTL_ROT13PW_SIZE);
            else
                strBuilder.append(aStringPlain);

            someNumber = 2;
            for (int i = strLength; i < STRUTL_ROT13PW_SIZE; i++) {
                if (isAllUpper)
                    ch = 'A';
                else
                    ch = 'a';
                ch += i;
                if ((NumUtl.isEven(i)) && (!isAllUpper))
                    ch = Character.toLowerCase(ch);
                else if ((i % 3) == 0) {
                    ch = '1';
                    ch += someNumber;
                    someNumber++;
                }
                strBuilder.append(ch);
            }

            strBuilder.append(STRUTL_CHAR_PWFINISH);

            return simple13Rotation(strBuilder.toString());
        }
    }

    /**
     * Determines if the string has been encrypted to hide is contents.
     *
     * @param aString A simple string value.
     *
     * @return <i>true</i> if hidden (encrypted) and <i>false</i> otherwise.
     */
    public static boolean isHidden(String aString) {
        if (StringUtils.isNotEmpty(aString)) {
            int strLength = aString.length();
            if (strLength > 1) {
                char chStart = aString.charAt(0);
                char chEnd = aString.charAt(strLength - 1);
                if ((chStart == STRUTL_CHAR_PWBEGIN) && (chEnd == STRUTL_CHAR_PWFINISH))
                    return true;
            }
        }
        return false;
    }

    /**
     * Recovers a previously encrypted <code>hidePassword</code> string
     * and returns it in its original form.
     * <p>
     * <b>Note:</b> The input string must be wrapped with the less-than and
     * greater-than characters to signify that they were previously
     * encrypted by the <code>hidePassword</code> method.
     * </p>
     *
     * @param aStringPassword An encrypted password string.
     *
     * @return A decrypted <i>String</i> object.
     */
    public static String recoverPassword(String aStringPassword) {
        char chStart, chEnd;
        String plainPassword;
        int strLength, pwSize;

        if (StringUtils.isEmpty(aStringPassword))
            return aStringPassword;
        else {
            strLength = aStringPassword.length();
            if (strLength > 1) {
                chStart = aStringPassword.charAt(0);
                chEnd = aStringPassword.charAt(strLength - 1);
                if ((chStart != STRUTL_CHAR_PWBEGIN) && (chEnd != STRUTL_CHAR_PWFINISH))
                    return aStringPassword;
            } else
                return aStringPassword;

            plainPassword = simple13Rotation(aStringPassword.substring(1));
            strLength = plainPassword.length();
            plainPassword = plainPassword.substring(0, strLength - 1);

            chStart = Character.toUpperCase(plainPassword.charAt(0));
            pwSize = (chStart - 'A') + 1;
            if ((pwSize <= 0) || (pwSize > STRUTL_ROT13PW_SIZE))
                return aStringPassword;

            return plainPassword.substring(1, pwSize);
        }
    }

    /**
     * Determines if the last character in the string matches.
     *
     * @param aString A source string.
     * @param aChar Identifies the character to match.
     *
     * @return <code>true</code> if character exists or <code>false</code>
     */
    public static boolean endsWithChar(String aString, char aChar) {
        if (StringUtils.isEmpty(aString))
            return false;
        else {
            int strLength = aString.length();
            return (aString.charAt(strLength - 1) == aChar);
        }
    }

    /**
     * Appends the character to the string if it is missing.
     *
     * @param aString A source string.
     * @param aChar Identifies the character to append (if missing).
     *
     * @return The updated string if the character was missing.
     */
    public static String appendCharIfMissing(String aString, char aChar) {
        if (StringUtils.isNotEmpty(aString)) {
            if (!endsWithChar(aString, aChar))
                return aString + aChar;
        }

        return aString;
    }

    /**
     * Escape <code>aCharToEscape</code> in the string
     * with a Java escape character (backslash).
     *
     * @param aString String to process.
     * @param aCharToEscape The character to be escaped.
     *
     * @return An escaped string
     */
    public static String escapeStringWithBackslash(String aString, char aCharToEscape) {
        char curChar;

        if (StringUtils.isEmpty(aString))
            return StringUtils.EMPTY;

        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < aString.length(); i++) {
            curChar = aString.charAt(i);

            if (curChar == aCharToEscape)
                stringBuilder.append(CHAR_BACKSLASH);

            stringBuilder.append(curChar);
        }

        return stringBuilder.toString();
    }

    /**
     * Unescape <code>aCharToEscape</code> in the string recognizing
     * a Java escape character (backslash).
     *
     * @param aString String to process.
     * @param aCharToEscape The character to be escaped.
     *
     * @return An escaped string
     */
    public static String unEscapeStringWithBackslash(String aString, char aCharToEscape) {
        char curChar, nextChar;

        if (StringUtils.isEmpty(aString))
            return StringUtils.EMPTY;

        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < aString.length(); i++) {
            curChar = aString.charAt(i);
            if ((i + 1) < aString.length()) {
                nextChar = aString.charAt(i + 1);
                if ((curChar == CHAR_BACKSLASH) && (nextChar == aCharToEscape))
                    continue;
            }
            stringBuilder.append(curChar);
        }

        return stringBuilder.toString();
    }

    /**
     * Collapses the list of strings down to one string.
     * Each value is separated by a delimiter character.
     *
     * @param aStrings List of strings to process.
     * @param aDelimiterChar Delimiter character.
     *
     * @return A collapsed string.
     */
    public static String collapseToSingle(final ArrayList<String> aStrings, char aDelimiterChar) {
        StringBuilder stringBuilder = new StringBuilder();

        if ((aStrings != null) && (aStrings.size() > 0)) {
            for (String strValue : aStrings) {
                if (stringBuilder.length() == 0)
                    stringBuilder.append(escapeStringWithBackslash(strValue, aDelimiterChar));
                else {
                    stringBuilder.append(aDelimiterChar);
                    stringBuilder.append(escapeStringWithBackslash(strValue, aDelimiterChar));
                }
            }
        }

        if (stringBuilder.length() == 0)
            return StringUtils.EMPTY;
        else
            return stringBuilder.toString();
    }

    /**
     * Expand the string into a list of individual values
     * using the delimiter character to identify each one.
     *
     * @param aString One or more values separated by a
     *                delimiter character.
     * @param aDelimiterChar Delimiter character.
     *
     * @return An ArrayList of String instances.
     */
    public static ArrayList<String> expandToList(final String aString, char aDelimiterChar) {
        ArrayList<String> stringList = new ArrayList<String>();

        if (StringUtils.isNotEmpty(aString)) {
            String delimiterString = Character.toString(aDelimiterChar);
            if (aDelimiterChar == StrUtl.CHAR_PIPE)
                delimiterString = String.format("%c%c", StrUtl.CHAR_BACKSLASH, aDelimiterChar);
            String regExPattern = String.format("(?<!\\\\)%s", delimiterString);

            String[] valueArray = aString.split(regExPattern);
            for (String strValue : valueArray)
                stringList.add(unEscapeStringWithBackslash(strValue, aDelimiterChar));
        }

        return stringList;
    }

    /**
     * Convenience method that converts a generic ArrayList of
     * Objects into an array of string values.
     *
     * @param anArrayList Array of value object instances.
     *
     * @return An array of values extracted from the array list.
     */
    public static String[] convertToMulti(ArrayList<?> anArrayList) {
        if ((anArrayList == null) || (anArrayList.size() == 0)) {
            String[] emptyList = new String[1];
            emptyList[0] = StringUtils.EMPTY;
            return emptyList;
        }

        int offset = 0;
        String[] multiValues = new String[anArrayList.size()];

        for (Object arrayObject : anArrayList) {
            if (arrayObject instanceof Integer) {
                Integer integerValue = (Integer) arrayObject;
                multiValues[offset++] = integerValue.toString();
            } else if (arrayObject instanceof Long) {
                Long longValue = (Long) arrayObject;
                multiValues[offset++] = longValue.toString();
            } else if (arrayObject instanceof Float) {
                Float floatValue = (Float) arrayObject;
                multiValues[offset++] = floatValue.toString();
            } else if (arrayObject instanceof Double) {
                Double doubleValue = (Double) arrayObject;
                multiValues[offset++] = doubleValue.toString();
            } else if (arrayObject instanceof Date) {
                Date dateValue = (Date) arrayObject;
                multiValues[offset++] = Field.dateValueFormatted(dateValue, Field.FORMAT_DATETIME_DEFAULT);
            } else
                multiValues[offset++] = arrayObject.toString();
        }

        return multiValues;
    }

    /**
     * Determines if the patten (with one or more wildcards) matches
     * the string.
     *
     * @param aString String to evaluate.
     * @param aPattern Wildcard pattern.
     *
     * @return <i>true</i> or <i>false</i>
     */
    public static boolean isWildcardMatch(String aString, String aPattern) {
        if ((StringUtils.isEmpty(aString)) || ((StringUtils.isEmpty(aPattern))))
            return false;
        else {
            int offset = aPattern.indexOf(CHAR_ASTERISK);
            if (offset == -1)
                return StringUtils.equals(aString, aPattern);
            else {
                String subString = aString;
                String[] patternStrings = aPattern.split("\\*");
                for (String patternString : patternStrings) {
                    offset = subString.indexOf(patternString);
                    if (offset == -1)
                        return false;
                    else
                        subString = subString.substring(offset + patternString.length());
                }
                return true;
            }
        }
    }

    /**
     * Formats the size (in bytes) in a human readable string of
     * bytes, KB, MB, GB and TB.
     *
     * @param aSizeInBytes Size in bytes.
     *
     * @return Formatted string.
     */
    public static String bytesToString(long aSizeInBytes) {
        NumberFormat numberFormat = new DecimalFormat();
        numberFormat.setMaximumFractionDigits(2);

        try {
            if (aSizeInBytes < SIZE_IN_KB)
                return numberFormat.format(aSizeInBytes) + " Byte(s)";
            else if (aSizeInBytes < SIZE_IN_MB)
                return numberFormat.format(aSizeInBytes / SIZE_IN_KB) + " KB";
            else if (aSizeInBytes < SIZE_IN_GB)
                return numberFormat.format(aSizeInBytes / SIZE_IN_MB) + " MB";
            else if (aSizeInBytes < SIZE_IN_TB)
                return numberFormat.format(aSizeInBytes / SIZE_IN_GB) + " GB";
            else
                return numberFormat.format(aSizeInBytes / SIZE_IN_TB) + " TB";
        } catch (Exception e) {
            return aSizeInBytes + " Byte(s)";
        }
    }
}