illab.nabal.util.Util.java Source code

Java tutorial

Introduction

Here is the source code for illab.nabal.util.Util.java

Source

/*
 * Copyright (C) 2013-2014 Tan Jung
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package illab.nabal.util;

import illab.nabal.exception.SystemException;
import illab.nabal.proxy.Delegate;
import illab.nabal.proxy.FacebookDelegate;
import illab.nabal.proxy.TwitterDelegate;
import illab.nabal.proxy.WeiboDelegate;
import illab.nabal.settings.SystemProperties;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;
import java.util.TimeZone;

import org.json.JSONObject;

import android.util.Base64;
import android.util.Log;

/**
 * Various utilities.
 * 
 * @version 1.0, 02/10/14
 * @author <a href="mailto:tanito.jung@gmail.com">Tan Jung</a>
 */
public final class Util {

    /**
      * Private constructor of this class. 
     */
    private Util() {
    }

    /**
     * Extract Base64-encoded string from file content.
     * 
     * @param photoPath absoulte system path of photo
     * @param maxSize max file size in kilobytes
     * @return Base64-encoded string of file content
     * @throws Exception
     */
    public static String extractBase64StringFromFile(String photoPath, int maxSize) throws Exception {

        String imageContent = "";

        File file = new File(photoPath);

        if (file.length() > maxSize * 1024) {
            throw new SystemException("File size must be less than " + maxSize + " kilobytes.");
        }

        byte[] buffer = new byte[(int) file.length()];
        InputStream ios = null;
        try {
            ios = new FileInputStream(file);
            if (ios.read(buffer) == -1) {
                throw new IOException("EOF reached while trying to read the whole file");
            }
        } finally {
            try {
                if (ios != null)
                    ios.close();
            } catch (IOException e) {
            }
        }
        imageContent = Base64.encodeToString(buffer, Base64.DEFAULT);
        //Log.d(TAG, "imageContent :\n" + imageContent);

        return imageContent;
    }

    /**
     * Add more elements to an array.
     * 
     * @param targetArray
     * @param elements
     * @return an array with more elements added
     */
    public static <T> T[] addToArray(T[] targetArray, T... elements) {
        if (elements != null && elements.length > 0) {
            return concatArrays(targetArray, elements);
        }
        return targetArray;
    }

    /**
     * Concat two arrays.
     * 
     * @param firstArray
     * @param secondArray
     * @return an array containing values from both firstArray and secondArray
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] concatArrays(T[] firstArray, T[] secondArray) {

        // try not to reassign parameters
        T[] leftSideArray = firstArray;
        T[] rightSideArray = secondArray;

        // defend against null or empty array
        if (leftSideArray == null || leftSideArray.length == 0) {
            leftSideArray = (T[]) new Object[0];
        }

        // defend against null or empty array
        if (rightSideArray == null || rightSideArray.length == 0) {
            rightSideArray = (T[]) new Object[0];
        }

        final int firstArrayLength = leftSideArray.length;
        final int secondArrayLength = rightSideArray.length;

        final T[] result = (T[]) java.lang.reflect.Array.newInstance(leftSideArray.getClass().getComponentType(),
                firstArrayLength + secondArrayLength);

        System.arraycopy(leftSideArray, 0, result, 0, firstArrayLength);
        System.arraycopy(rightSideArray, 0, result, firstArrayLength, secondArrayLength);

        return result;
    }

    /**
     * Concat multiple arrays at once.
     * 
     * @param firstArray
     * @param restArrays
     * @return an array containing values from all given arrays
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] concatAllArrays(T[] firstArray, T[]... restArrays) {

        // try not to reassign parameters
        T[] leftSideArray = firstArray;

        // defend against null or empty array
        if (leftSideArray == null || leftSideArray.length == 0) {
            leftSideArray = (T[]) new Object[0];
        }

        int totalLength = leftSideArray.length;
        for (T[] array : restArrays) {
            if (array != null && array.length > 0) {
                totalLength += array.length;
            }
        }

        // avoid using Arrays#copyOf for backward compatibility
        //T[] result = Arrays.copyOf(leftSideArray, totalLength);

        // instead of using Arrays#copyOf, use below 3 lines
        Class<?> type = leftSideArray.getClass().getComponentType();
        T[] result = (T[]) Array.newInstance(type, totalLength);
        System.arraycopy(leftSideArray, 0, result, 0, leftSideArray.length);

        int offset = leftSideArray.length;
        for (T[] array : restArrays) {
            if (array != null && array.length > 0) {
                System.arraycopy(array, 0, result, offset, array.length);
                offset += array.length;
            }
        }

        return result;
    }

    /**
     * Get an array of keys extracted from given JSON.
     * 
     * @param json
     * @return an array of keys extracted from given JSON
     */
    public static String[] getKeysFromJsonObject(JSONObject json) {

        String[] keys = null;

        if (json != null) {
            @SuppressWarnings("unchecked")
            Iterator<String> i = json.keys();
            while (i.hasNext()) {
                keys = addToArray(keys, i.next().toString());
            }
        }

        return keys;
    }

    /**
     * Get system locale setting.
     * 
     * @return Locale
     */
    public static Locale getSystemLocale() {
        return Locale.getDefault();
    }

    /**
     * Get system timezone setting.
     * 
     * @return TimeZone
     */
    public static TimeZone getSystemTimeZone() {
        return TimeZone.getTimeZone(TimeZone.getDefault().getID());
    }

    /**
     * Get ISO 8601 date and time format.
     * 
     * @return DateFormat
     * @throws Exception
     */
    public static DateFormat getIso8601DateFormat(TimeZone timeZone, Locale locale) throws Exception {

        // check timezone parameter
        if (timeZone == null)
            throw new SystemException("Invalid timezone parameter.");

        // check locale parameter
        if (locale == null)
            throw new SystemException("Invalid locale parameter.");

        DateFormat iso8601Format = new SimpleDateFormat(SystemProperties.ISO_8601_DATE_FORMAT, locale);
        iso8601Format.setTimeZone(timeZone);

        return iso8601Format;
    }

    /**
     * Get current time in UNIX seconds.
     * 
     * @return current time in UNIX seconds
     */
    public static long getCurrentUnixTime() {
        return System.currentTimeMillis() / 1000L;
    }

    /**
     * Get time in UNIX seconds.
     * 
     * @param date
     * @return time in UNIX seconds
     */
    public static long getUnixTime(Date date) {
        return date.getTime() / 1000L;
    }

    /**
     * Get current time in ISO 8601 format.
     * 
    * @param timeZone {@link TimeZone} 
     * @return string representing current time in ISO 8601 format
     * @throws Exception
     */
    public static String getCurrentIso8601Time(TimeZone timeZone, Locale locale) throws Exception {
        return getIso8601Time(new Date(), timeZone, locale);
    }

    /**
     * Get time in ISO 8601 format.
     * 
    * @param timeZone {@link TimeZone} 
     * @return string representing current time in ISO 8601 format
     * @throws Exception
     */
    public static String getIso8601Time(Date date, TimeZone timeZone, Locale locale) throws Exception {
        return getIso8601DateFormat(timeZone, locale).format(date);
    }

    /**
     * Convert UNIX time to ISO-8601-formatted date string.
     * 
     * @param unixSeconds
     * @param timeZone
     * @param locale
     * @return ISO-8601-formatted date string corresponding to given UNIX time
     * @throws Exception
     */
    public static String getIso8601TimeFromUnixTime(long unixSeconds, TimeZone timeZone, Locale locale)
            throws Exception {
        return getIso8601Time(new Date(unixSeconds * 1000L), timeZone, locale);
    }

    /**
     * Convert ISO-8601-formatted date string to UNIX time.
     * 
     * @param iso8601Time
     * @param locale
     * @return UNIX time corresponding to given ISO-8601-formatted date string
     * @throws Exception
     */
    public static long getUnixTimeFromIso8601Time(String iso8601Time, Locale locale) throws Exception {
        return new SimpleDateFormat(SystemProperties.ISO_8601_DATE_FORMAT, locale).parse(iso8601Time).getTime()
                / 1000L;
    }

    /**
     * Get UNIX time from given date string representing UNIX time or ISO 8601 time.
     * 
     * @param dateString string token representing UNIX time or ISO 8601 time
     * @param locale
     * @return long
     * @throws Exception
     */
    public static long getUnixTime(String dateString, Locale locale) throws Exception {

        // check date string
        if (StringHelper.isEmpty(dateString) == true) {
            throw new SystemException("Invalid date string.");
        }

        long unixTime;

        // if created date is ISO-8601-formatted
        if (dateString.indexOf("-") > -1) {
            unixTime = getUnixTimeFromIso8601Time(dateString, locale);
        }

        // if created date is already UNIX time
        else {
            unixTime = Long.parseLong(dateString);
        }

        return unixTime;
    }

    /**
     * Get ISO 8601 time from given date string representing UNIX time or ISO 8601 time.
     * 
     * @param dateString string token representing UNIX time or ISO 8601 time
     * @param timeZone
     * @param locale
     * @return String
     * @throws Exception
     */
    public static String getIso8601Time(String dateString, TimeZone timeZone, Locale locale) throws Exception {

        // check date string
        if (StringHelper.isEmpty(dateString) == true) {
            throw new SystemException("Invalid date string.");
        }

        // check timezone
        if (timeZone == null) {
            throw new SystemException("Invalid timezone.");
        }

        String iso8601Time;

        // if created date is already ISO-8601-formatted
        if (dateString.indexOf("-") > -1) {
            long unixTime = getUnixTimeFromIso8601Time(dateString, locale);
            iso8601Time = getIso8601TimeFromUnixTime(unixTime, timeZone, locale);
        }

        // if created date is UNIX time
        else {
            iso8601Time = getIso8601TimeFromUnixTime(Long.parseLong(dateString), timeZone, locale);
        }

        return iso8601Time;
    }

    /**
     * Make the current thread (on which this method executes) wait 
     * for given amount of time.
     * 
     * @param seconds number of seconds to wait
     * @throws InterruptedException
     */
    private static void threadSleep(int seconds) throws InterruptedException {
        Thread.sleep(seconds * 1000L);
    }

    /**
     * Make the current thread (on which this method executes) wait 
     * for given amount of time.
     * 
     * @param seconds number of seconds to wait
     * @throws InterruptedException
     */
    public static void sleep(int seconds) {
        try {
            Log.d("Util", "sleeping for " + seconds + "...");
            threadSleep(seconds);
        } catch (InterruptedException e) {
            // DO NOTHING
        }
    }

    /**
     * Get how many APIs given network delegate has.
     * 
     * @param networkDelegate
     * @return how many APIs given network delegate has 
     */
    public static int getHowManyApis(Delegate networkDelegate) {

        // method names to be exculded when counting 
        String[] excludedMethodNames = {
                // inherited from JDK
                "equals", "getClass", "hashCode", "notify", "notifyAll", "toString", "wait"
                // inherited from Delegate
                , "isSessionValid", "fetchSession", "purgeSession", "hasNoJobs", "getBitmapFromUrl" };

        // determine which socail network this delegate class represents
        Delegate delegate = networkDelegate;
        Class<? extends Delegate> thisClass = null;
        if (networkDelegate instanceof FacebookDelegate) {
            thisClass = ((FacebookDelegate) delegate).getClass();
        } else if (networkDelegate instanceof TwitterDelegate) {
            thisClass = ((TwitterDelegate) delegate).getClass();
        } else if (networkDelegate instanceof WeiboDelegate) {
            thisClass = ((WeiboDelegate) delegate).getClass();
        }

        // get max of method index
        int maxMethodIndex = 0;
        String thisClassName = thisClass.getName();
        ClassLoader classLoader = thisClass.getClassLoader();
        try {
            for (Method method : classLoader.loadClass(thisClassName).getMethods()) {
                if (Arrays.asList(excludedMethodNames).contains(method.getName()) == false) {
                    //Log.v(TAG, "indexing... " + method.getName() + " : added");
                    maxMethodIndex++;
                } else {
                    //Log.v(TAG, "indexing... " + method.getName() + " : pass");
                }
            }
        } catch (ClassNotFoundException e) {
            // if error occurrs let's set 100 to prevent the shortage of the index
            maxMethodIndex = 100;
        }
        return maxMethodIndex;
    }

}