com.legstar.coxb.util.ClassUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of legstar-coxbapi Show documentation
Show all versions of legstar-coxbapi Show documentation
Cobol Transformers Application Programming Interface.
The newest version!
/*******************************************************************************
* Copyright (c) 2015 LegSem.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* LegSem - initial API and implementation
******************************************************************************/
package com.legstar.coxb.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
/**
* A helper class for dynamic class loading.
*
*/
public final class ClassUtil {
/** Utility class. */
private ClassUtil() {
}
/**
* Rather than using the Class.forName mechanism first, this uses
* Thread.getContextClassLoader instead. In a Servlet context such as
* Tomcat, this allows JAXB classes for instance to be loaded from the web
* application (webapp) location while this code might have been loaded from
* shared/lib. If Thread.getContextClassLoader fails to locate the class
* then we give a last chance to Class.forName.
*
* @param packageName the package containing the class
* @param className the class name
* @return the class
* @throws ClassNotFoundException if class is not accessible from any class
* loader
*/
public static Class < ? > loadClass(final String packageName,
final String className) throws ClassNotFoundException {
return loadClass(toQualifiedClassName(packageName, className));
}
/**
* Rather than using the Class.forName mechanism first, this uses
* Thread.getContextClassLoader instead. In a Servlet context such as
* Tomcat, this allows JAXB classes for instance to be loaded from the web
* application (webapp) location while this code might have been loaded from
* shared/lib. If Thread.getContextClassLoader fails to locate the class
* then we give a last chance to Class.forName.
*
* @param qualifiedClassName the class name to load
* @return the class
* @throws ClassNotFoundException if class is not accessible from any class
* loader
*/
public static Class < ? > loadClass(final String qualifiedClassName)
throws ClassNotFoundException {
ClassLoader contextClassLoader = Thread.currentThread()
.getContextClassLoader();
if (contextClassLoader == null) {
return Class.forName(qualifiedClassName);
}
try {
return contextClassLoader.loadClass(qualifiedClassName);
} catch (ClassNotFoundException e) {
return Class.forName(qualifiedClassName);
}
}
/**
* Dynamically create an instance of a java class. This assumes the classes
* are available on the classpath and returns a new instance.
*
* @param packageName the package containing the class
* @param className the class name
* @return a java object
* @throws ClassLoadingException if object cannot be instantiated
*/
public static Object newObject(final String packageName,
final String className) throws ClassLoadingException {
return newObject(toQualifiedClassName(packageName, className));
}
/**
* Dynamically create an instance of a java class. This assumes the classes
* are available on the classpath and returns a new instance.
*
* @param qualifiedClassName the qualified class name
* @return a java object
* @throws ClassLoadingException if object cannot be instantiated
*/
public static Object newObject(final String qualifiedClassName)
throws ClassLoadingException {
try {
Class < ? > clazz = loadClass(qualifiedClassName);
return clazz.newInstance();
} catch (InstantiationException e) {
throw new ClassLoadingException(e);
} catch (IllegalAccessException e) {
throw new ClassLoadingException(e);
} catch (ClassNotFoundException e) {
throw new ClassLoadingException(e);
}
}
/**
* Qualifies a class name.
*
* @param packageName the package name, null if none
* @param className the class name
* @return a qualified class name
*/
public static String toQualifiedClassName(final String packageName,
final String className) {
return (packageName == null) ? className : packageName + '.'
+ className;
}
/**
* Separate package name and class name from a qualified class name.
*
* @param qualifiedClassName qualified class name
* @return a structure with both parts
*/
public static ClassName toClassName(final String qualifiedClassName) {
ClassName className = new ClassName();
int pos = qualifiedClassName.lastIndexOf('.');
className.packageName = (pos == -1) ? null : qualifiedClassName
.substring(0, pos);
className.className = (pos == -1) ? qualifiedClassName
: qualifiedClassName.substring(pos + 1);
return className;
}
/**
* A simple vehicle for class name and package name.
*
*/
public static class ClassName {
/** The class name. */
public String className;
/** The package name (null if no package name). */
public String packageName;
}
/**
* The ObjectFactory exports a create method for each complex type in the
* object tree. Returns a jaxb object creator method.
*
* @param objectFactory JAXB Objectfactory
* @param jaxbTypeName the jaxb object type name
* @return the creator method
* @throws ClassMethodException if getter method does not exist
*/
public static Method getCreatorMethod(final Object objectFactory,
final String jaxbTypeName) throws ClassMethodException {
try {
Method creator = objectFactory.getClass().getMethod(
"create" + toPropertyType(jaxbTypeName));
return creator;
} catch (NoSuchMethodException e) {
throw (new ClassMethodException(e));
}
}
/**
* Returns a jaxb property getter method.
*
* @param parentObject JAXB Object owning the property
* @param getterPrefix the getter method prefix (get or is)
* @param jaxbName the property name to get
* @return the getter method
* @throws ClassMethodException if getter method does not exist
*/
public static Method getGetterMethod(final Object parentObject,
final String getterPrefix, final String jaxbName)
throws ClassMethodException {
String getterName = getGetterName(getterPrefix, jaxbName);
try {
Method getter = parentObject.getClass().getMethod(getterName);
return getter;
} catch (NoSuchMethodException e) {
throw (new ClassMethodException(e));
}
}
/**
* Build a conventional bean getter method name from a field name.
*
* @param getterPrefix the getter method name prefix (get or is)
* @param fieldName the field name
* @return a getter method name
*/
public static String getGetterName(final String getterPrefix,
final String fieldName) {
return getterPrefix + Character.toUpperCase(fieldName.charAt(0))
+ fieldName.substring(1);
}
/**
* Returns a jaxb property setter method.
*
* @param parentObject JAXB Object owning the property
* @param jaxbName the property name to get
* @param jaxbType the property type
* @return the getter method
* @throws ClassMethodException if getter method does not exist
*/
public static Method getSetterMethod(final Object parentObject,
final String jaxbName, final Class < ? > jaxbType)
throws ClassMethodException {
String setterName = getSetterMethodName(jaxbName);
try {
Class < ? >[] param = { jaxbType };
Method setter = parentObject.getClass()
.getMethod(setterName, param);
return setter;
} catch (NoSuchMethodException e) {
throw (new ClassMethodException(e));
}
}
/**
* Construct a setter method name for a JAXB property.
*
* @param jaxbName the JAXB property name
* @return the setter method name
*/
public static String getSetterMethodName(final String jaxbName) {
return "set" + NameUtil.upperFirstChar(jaxbName)
+ jaxbName.substring(1);
}
/**
* Helper method to extract the type name as used by JAXB create methods.
*
* Property type (as returned from Field.getGenericType()) can take 4 forms:
*
* - type
* - package.type
* - java.util.List < package.type >
* - type$nestedType
*
* Furthermore, primitive types are returned as their Object equivalent.
*
*
* @param genericType as returned from hostField.getGenericType()
* @return a normalized string representation of the type
*/
public static String toPropertyType(final String genericType) {
String type;
int lp = genericType.lastIndexOf('.');
if (lp == -1) {
type = genericType;
} else {
type = genericType.substring(lp + 1);
if (type.charAt(type.length() - 1) == '>') {
type = type.substring(0, type.length() - 1);
}
}
// type = type.replace("$", ".");
if (type.compareTo("byte") == 0) {
return "Byte";
} else if (type.compareTo("[B") == 0) {
return "byte[]";
} else if (type.compareTo("short") == 0) {
return "Short";
} else if (type.compareTo("int") == 0) {
return "Integer";
} else if (type.compareTo("long") == 0) {
return "Long";
} else if (type.compareTo("float") == 0) {
return "Float";
} else if (type.compareTo("double") == 0) {
return "Double";
} else if (type.compareTo("boolean") == 0) {
return "Boolean";
}
return type;
}
/**
* This method gets a property object from a parent object.
*
* @param parentObject JAXB Object owning the property
* @param jaxbName the property name to get
* @return instance of the property as returned from a getter method
* @throws ClassInvokeException if property cannot be accessed
* @deprecated use {@link invokeGetProperty(Object parentObject, String
* jaxbName, Class < ? > jaxbType)}
*/
public static Object invokeGetProperty(final Object parentObject,
final String jaxbName) throws ClassInvokeException {
Object result;
try {
/*
* The concrete object reference is obtained thru the corresponding
* parent getter method
*/
Method getter = getGetterMethod(parentObject, "get", jaxbName);
result = getter.invoke(parentObject);
} catch (IllegalAccessException e) {
throw (new ClassInvokeException(e));
} catch (InvocationTargetException e) {
throw (new ClassInvokeException(e));
} catch (ClassMethodException e) {
throw (new ClassInvokeException(e));
}
return result;
}
/**
* This method gets a property object from a parent object.
*
* @param parentObject JAXB Object owning the property
* @param jaxbName the property name to get
* @param maxOccurs the maximum number of occurrences
* @return instance of the property as returned from a getter method
* @throws ClassInvokeException if property cannot be accessed
*/
public static Object invokeGetProperty(final Object parentObject,
final String jaxbName, final Class < ? > jaxbType,
final int maxOccurs) throws ClassInvokeException {
Object result;
try {
/*
* The concrete object reference is obtained thru the corresponding
* parent getter method
*/
Method getter = getGetterMethod(parentObject,
getGetterPrefix(jaxbType, maxOccurs), jaxbName);
result = getter.invoke(parentObject);
} catch (IllegalAccessException e) {
throw (new ClassInvokeException(e));
} catch (InvocationTargetException e) {
throw (new ClassInvokeException(e));
} catch (ClassMethodException e) {
throw (new ClassInvokeException(e));
}
return result;
}
/**
* Evaluates the getter method prefix for a field, based on the field type.
*
* @param fieldType the field type
* @param maxOccurs the maximum number of occurrences
* @return the prefix to form a getter method
*/
public static String getGetterPrefix(final Class < ? > fieldType,
final int maxOccurs) {
String getterPrefix = "get";
if (maxOccurs <= 1) {
if (fieldType == boolean.class) {
getterPrefix = "is";
} else if (fieldType == Boolean.class) {
getterPrefix = "is";
}
}
return getterPrefix;
}
/**
* This method sets a property from a parent object to a given value.
*
* @param parentObject JAXB Object owning the property
* @param jaxbName the property name to set
* @param value value to set property to
* @param javaType the java class the value belongs to
* @throws ClassInvokeException if property cannot be set
*/
@SuppressWarnings({ "rawtypes" })
public static void invokeSetProperty(final Object parentObject,
final String jaxbName, final Object value,
final Class < ? > javaType) throws ClassInvokeException {
try {
/*
* When object to set is a List, we use the getXXX().AddAll
* technique
*/
if (value instanceof List) {
Method getter = getGetterMethod(parentObject, "get", jaxbName);
Class < ? > listClass = getter.getReturnType();
Method addAll = listClass.getMethod("addAll", Collection.class);
addAll.invoke(getter.invoke(parentObject), (Collection) value);
} else {
Method setter = getSetterMethod(parentObject, jaxbName,
javaType);
setter.invoke(parentObject, value);
}
} catch (IllegalAccessException e) {
throw (new ClassInvokeException(e));
} catch (NoSuchMethodException e) {
throw (new ClassInvokeException(e));
} catch (InvocationTargetException e) {
throw (new ClassInvokeException(e));
} catch (ClassMethodException e) {
throw (new ClassInvokeException(e));
}
}
/**
* This method creates a new instance of a property type in a parent object
* using a JAXB ObjectFactory. Given the property type name, the method
* constructs an ObjectFactory call for this property type. This method
* works for complex types only since the ObjectFactory will have create
* methods only for those.
*
* @param objectFactory a JAXB ObjectFactory
* @param parentObject instance of the JAXB parent class
* @param jaxbName complex property name
* @param jaxbTypeName complex property type name
* @return an instance of a JAXB object
* @throws ClassInvokeException if JAXB Object cannot be instanciated
*/
public static Object addComplexProperty(final Object objectFactory,
final Object parentObject, final String jaxbName,
final String jaxbTypeName) throws ClassInvokeException {
try {
Method creator = getCreatorMethod(objectFactory, jaxbTypeName);
Object result = creator.invoke(objectFactory);
/*
* Add a reference to the object just created to the parent object
* using its setter method
*/
Method setter = getSetterMethod(parentObject, jaxbName,
creator.getReturnType());
setter.invoke(parentObject, result);
return result;
} catch (IllegalAccessException e) {
throw new ClassInvokeException(e);
} catch (InvocationTargetException e) {
throw new ClassInvokeException(e);
} catch (ClassMethodException e) {
throw new ClassInvokeException(e);
}
}
/**
* This method gets an indexed property object from a parent array object.
* Assumes the parent inherits from java.util.List and implement a
* get(index) method.
*
* @param parentObject instance of the JAXB parent list class
* @param index item index in list
* @return an instance of a JAXB object
* @throws ClassInvokeException if JAXB Object cannot be returned
*/
public static Object invokeGetIndexedProperty(final Object parentObject,
final int index) throws ClassInvokeException {
Object result;
try {
/*
* To get an instance of the item identified by index, we use the
* get(i) method of ArrayList
*/
Method getter = parentObject.getClass().getMethod("get", int.class);
result = getter.invoke(parentObject, index);
} catch (IllegalAccessException e) {
throw new ClassInvokeException(e);
} catch (NoSuchMethodException e) {
throw new ClassInvokeException(e);
} catch (InvocationTargetException e) {
/* If requested item does not exist in array simply return null */
if (e.getTargetException().getClass().getName()
.compareTo("java.lang.IndexOutOfBoundsException") == 0) {
return null;
} else {
throw new ClassInvokeException(e);
}
}
return result;
}
/**
* This creates a new complex property item, identified by an index in a
* parent object array. This method assumes the items are complex objects
* for which the JAXB ObjectFactory implements a create method.
*
* @param objectFactory a JAXB ObjectFactory
* @param parentObject instance of the JAXB parent class
* @param jaxbTypeName complex property type name
* @param index item index in list
* @return an instance of a JAXB object
* @throws ClassInvokeException if JAXB Object cannot be instanciated
*/
public static Object addComplexIndexedProperty(final Object objectFactory,
final Object parentObject, final String jaxbTypeName,
final int index) throws ClassInvokeException {
try {
Method creator = getCreatorMethod(objectFactory, jaxbTypeName);
Object result = creator.invoke(objectFactory);
/*
* Add reference to object just created to the parent array using
* the add(index, Object) method
*/
Class < ? >[] param = { int.class, Object.class };
Method add = parentObject.getClass().getMethod("add", param);
add.invoke(parentObject, index, result);
return result;
} catch (IllegalAccessException e) {
throw new ClassInvokeException(e);
} catch (NoSuchMethodException e) {
throw new ClassInvokeException(e);
} catch (InvocationTargetException e) {
throw new ClassInvokeException(e);
} catch (ClassMethodException e) {
throw new ClassInvokeException(e);
}
}
/**
* This creates a new simple property item, identified by an index in a
* parent object array.
*
* @param parentObject instance of the JAXB parent list class
* @param index item index in list
* @param value value to set item to
* @throws ClassInvokeException if item cannot be set
*/
public static void addSimpleIndexedProperty(final Object parentObject,
final int index, final Object value) throws ClassInvokeException {
try {
/*
* Add reference to object just created to the parent array using
* the add(index, Object) method
*/
Class < ? >[] param = { int.class, Object.class };
Method setter = parentObject.getClass().getMethod("add", param);
setter.invoke(parentObject, index, value);
} catch (IllegalAccessException e) {
throw new ClassInvokeException(e);
} catch (NoSuchMethodException e) {
throw new ClassInvokeException(e);
} catch (InvocationTargetException e) {
throw new ClassInvokeException(e);
}
}
/**
* This will determine if a type name for a simple element is one of java's
* native types and assume it is an enum otherwise.
*
* @param type the element java type
* @return true if it should be considered an enum
*/
public static boolean isEnum(final String type) {
if (type == null) {
return false;
}
if (type.compareToIgnoreCase("String") == 0) {
return false;
} else if (type.compareToIgnoreCase("[B") == 0) {
return false;
} else if (type.compareToIgnoreCase("byte[]") == 0) {
return false;
} else if (type.compareToIgnoreCase("short") == 0) {
return false;
} else if (type.compareToIgnoreCase("int") == 0) {
return false;
} else if (type.compareToIgnoreCase("Integer") == 0) {
return false;
} else if (type.compareToIgnoreCase("long") == 0) {
return false;
} else if (type.compareToIgnoreCase("float") == 0) {
return false;
} else if (type.compareToIgnoreCase("double") == 0) {
return false;
} else if (type.compareToIgnoreCase("BigInteger") == 0) {
return false;
} else if (type.compareToIgnoreCase("BigDecimal") == 0) {
return false;
} else if (type.compareToIgnoreCase("byte") == 0) {
return false;
} else if (type.compareToIgnoreCase("boolean") == 0) {
return false;
}
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy