Java tutorial
/* * 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; } }