/** * Copyright Red Hat, Inc, and individual contributors. * * 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 com.feedhenry.sdk.sync; import android.util.Log; import java.util.Date; import java.util.Random; import org.json.fh.JSONArray; import org.json.fh.JSONObject; import com.feedhenry.sdk.sync.FHSyncDataRecord; import com.feedhenry.sdk.sync.FHSyncPendingRecord; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; public class FHTestUtils { private static final String TAG = FHTestUtils.class.getSimpleName(); public static JSONObject generateJSON() throws Exception { JSONObject ret = new JSONObject(); ret.put("testStringKey", genRandomString(10)); ret.put("testNumberKey", new Random().nextInt()); JSONArray arr = new JSONArray(); arr.put(genRandomString(10)); arr.put(genRandomString(10)); ret.put("testArrayKey", arr); JSONObject dict = new JSONObject(); dict.put(genRandomString(10), genRandomString(10)); dict.put(genRandomString(10), genRandomString(10)); ret.put("testDictKey", dict); return ret; } private static String genRandomString(int pLength) { Random r = new Random(); String letter = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; StringBuffer sb = new StringBuffer(); for (int i = 0; i < pLength; i++) { sb.append(letter.charAt(r.nextInt(1000000) % (letter.length()))); } return sb.toString(); } public static FHSyncDataRecord generateRadomDataRecord() throws Exception { JSONObject json = generateJSON(); return new FHSyncDataRecord(json); } public static FHSyncPendingRecord generateRandomPendingRecord() throws Exception { FHSyncPendingRecord pending = new FHSyncPendingRecord(); pending.setInFlightDate(new Date()); pending.setInFlight(true); pending.setCrashed(false); pending.setAction("create"); pending.setTimestamp(new Date().getTime()); pending.setUid(genRandomString(10)); pending.setPreData(generateRadomDataRecord()); pending.setPostData(generateRadomDataRecord()); return pending; } public static <T> T instanciatePrivateInnerClass(String className, Object outerInstance, Object... params) { try { Class<T> innerClass = findClass(className, outerInstance.getClass().getDeclaredClasses()); Constructor<T> innerClassConstructor = findConstructor(innerClass, outerInstance.getClass(), params); innerClassConstructor.setAccessible(true); params = prependTo(outerInstance, params); return innerClassConstructor.newInstance(params); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { Log.e(TAG, "Error creating inner class " + className, ex); throw new IllegalArgumentException(ex); } } private static <T> Class<T>findClass(String className, Class<?>[] declaredClasses) { for (Class<?> klass : declaredClasses) { if (klass.getSimpleName().matches(className)) { return (Class<T>) klass; } } throw new IllegalArgumentException(String.format("Class name %s not found ", className)); } private static <T> Constructor<T> findConstructor(Class<T> innerClass, Class<?> outerClassType, Object[] params) { try { Class<?>[] paramsKlasses = new Class[params.length + 1]; paramsKlasses[0] = outerClassType; for (int i = 0; i < params.length; i++) { paramsKlasses[i + 1] = params[i].getClass(); } Constructor<T>[] constructors = (Constructor<T>[]) innerClass.getDeclaredConstructors(); for (Constructor<T> constructor : constructors) { Class<?>[] constructorParams = constructor.getParameterTypes(); if (constructorParams.length == paramsKlasses.length) { boolean found = true; for (int i = 0; i < params.length; i++) { if (!constructorParams[i].isAssignableFrom(paramsKlasses[i])) { found = false; break; } } if (found) { return constructor; } } } Log.e(TAG, "No Constructor."); throw new IllegalArgumentException("Could not find a constructor for " + params.toString()); } catch (SecurityException ex) { Log.e(TAG, "Error finding constructor.", ex); throw new IllegalArgumentException(ex); } } private static <T> T[] prependTo(T outerInstance, T[] params) { ArrayList<T> paramsList = new ArrayList<>(params.length + 1); paramsList.add(outerInstance); for (T param : params) { paramsList.add(param); } return paramsList.toArray(params); } /** * * Will scan source and its super classes for fields with a type of value. * All instances will be replaced by value * * @param source the target object to have value injected into * @param value the value to override */ public static void injectInto(Object source, Object value) { injectInto(source, source.getClass(), value); } private static void injectInto(Object source, Class<? extends Object> sourceClass, Object value) { Field[] fields = sourceClass.getDeclaredFields(); for (Field field : fields) { if (field.getType().isAssignableFrom(value.getClass())) { try { field.setAccessible(true); field.set(source, value); } catch (IllegalArgumentException | IllegalAccessException ex) { Log.e(TAG, ex.getMessage(), ex); throw new RuntimeException(ex); } } } if (sourceClass.getSuperclass() != Object.class) { injectInto(source,sourceClass.getSuperclass(), value); } } static Object getPrivateField(Object client, String fieldName) { try { Class<? extends Object> klass = client.getClass(); Field field = klass.getDeclaredField(fieldName); field.setAccessible(true); return field.get(client); } catch (IllegalAccessException | IllegalArgumentException | NoSuchFieldException | SecurityException ex) { Log.e(FHTestUtils.class.getName(), ex.getMessage(), ex); throw new RuntimeException(ex); } } }