/* * Encog(tm) Core v3.4 - Java Version * http://www.heatonresearch.com/encog/ * https://github.com/encog/encog-java-core * Copyright 2008-2016 Heaton Research, Inc. * * 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. * * For more information on Heaton Research copyrights, licenses * and trademarks visit: * http://www.heatonresearch.com/copyright */ package org.encog.util.obj; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.encog.EncogError; import org.encog.util.file.ResourceInputStream; /** * This class includes some utilities to be used with reflection. This are * mostly used by the Encog generic persistence classes. */ public final class ReflectionUtil { /** * A map between short class names and the full path names. */ private static Map<String, Class<?>> classMap = new HashMap<String, Class<?>>(); /** * Find the specified field, look also in superclasses. * * @param c * The class to search. * @param name * The name of the field we are looking for. * @return The field. */ public static Field findField(final Class<?> c, final String name) { final Collection<Field> list = ReflectionUtil.getAllFields(c); for (final Field field : list) { if (field.getName().equals(name)) { field.setAccessible(true); return field; } } if (c.getSuperclass() != null) { return findField(c.getSuperclass(), name); } return null; } /** * Get all of the fields from the specified class as a collection. * * @param c * The class to access. * @return All of the fields from this class and subclasses. */ public static Collection<Field> getAllFields(final Class<?> c) { final List<Field> result = new ArrayList<Field>(); ReflectionUtil.getAllFields(c, result); return result; } /** * Get all of the fields in the specified class and super classes. * * @param c * The class to check. * @param fields * A collection to hold the classes. */ public static void getAllFields(final Class<?> c, final Collection<Field> fields) { for (final Field field : c.getDeclaredFields()) { fields.add(field); } final Class<?> s = c.getSuperclass(); if (s != null) { ReflectionUtil.getAllFields(s, fields); } } /** * Determine if one class is an instance of the other class. * * @param class1 * The class to check. * @param class2 * Is class1 an instance of class 2. * @return True if class 1 is an instance of class 2. */ public static boolean isInstanceOf(final Class<?> class1, final Class<?> class2) { // same class? if (class1.equals(class2)) { return true; } // implements interface for (final Class<?> clazz : class1.getInterfaces()) { if (clazz.equals(class1)) { return true; } } if (class1.getSuperclass() == null) { return false; } else { return ReflectionUtil.isInstanceOf(class1.getSuperclass(), class2); } } /** * Determine if the specified object is a primitive. * * @param obj * The object to check. * @return True if this object is primitive. */ public static boolean isPrimitive(final Object obj) { return (obj instanceof Character) || (obj instanceof Integer) || (obj instanceof Short) || (obj instanceof Float) || (obj instanceof Double) || (obj instanceof Boolean) || (obj instanceof Long); } /** * Determine if an object is "simple", that is it should be persisted just * with a .tostring. * * @param obj * The object to check. * @return True if the object is simple. */ public static boolean isSimple(final Object obj) { return (obj instanceof File) || (obj instanceof String); } /** * Load the classmap file. This allows classes to be resolved using just the * simple name. */ public static void loadStandardClassmap() { String currentClass = null; try { InputStream is = ResourceInputStream.openResourceInputStream("org/encog/data/classes.txt"); final BufferedReader reader = new BufferedReader( new InputStreamReader(is)); String line; while ((line = reader.readLine()) != null) { if (line.trim().length() != 0) { currentClass = line; final Class<?> c = Class.forName(line); ReflectionUtil.classMap.put(c.getSimpleName(), c); } } is.close(); } catch (final IOException e) { throw new EncogError(e); } catch (final ClassNotFoundException e) { throw new EncogError("Unknown class: " + currentClass); } } /** * Load the classmap file. This allows classes to be resolved using just the * simple name. */ public static void loadClassmap() { String currentClass = null; try { InputStream is = ResourceInputStream.openResourceInputStream("org/encog/data/classes.txt"); final BufferedReader reader = new BufferedReader( new InputStreamReader(is)); String line; while ((line = reader.readLine()) != null) { if (line.trim().length() != 0) { currentClass = line; final Class<?> c = Class.forName(line); ReflectionUtil.classMap.put(c.getSimpleName(), c); } } is.close(); } catch (final IOException e) { throw new EncogError(e); } catch (final ClassNotFoundException e) { throw new EncogError("Unknown class: " + currentClass); } } /** * Resolve an encog class using its simple name. * * @param name * The simple name of the class. * @return The class requested. */ public static Class<?> resolveEncogClass(final String name) { synchronized (ReflectionUtil.classMap) { if (ReflectionUtil.classMap.size() == 0) { ReflectionUtil.loadClassmap(); } } return ReflectionUtil.classMap.get(name); } /** * Private constructor. */ private ReflectionUtil() { } /** * Resolve an enumeration. * @param field The field to resolve. * @param value The value to get the enum for. * @return The enum that was resolved. */ public static Object resolveEnum(final Field field, final String value) { final Class<?> type = field.getType(); Object[] objs = type.getEnumConstants(); for (Object obj : objs) { if (obj.toString().equals(value)) { return obj; } } return null; } /** * Generate a hash code for an object. Return 0 for null objects. * @param <T> The type of object to generate for. * @param o The object to generate. * @return The hash code. */ public static <T> int safeHashCode(final T o) { if (o == null) { return 0; } else { return o.hashCode(); } } }