/**
* $Id: $
* $Date: $
*
*/
package org.xmlsh.util;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.XdmAtomicValue;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.s9api.XdmValue;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ClassUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.xmlsh.core.CoreException;
import org.xmlsh.core.InvalidArgumentException;
import org.xmlsh.core.XValue;
import org.xmlsh.sh.shell.SerializeOpts;
import org.xmlsh.sh.shell.Shell;
public class JavaUtils {
private static Set< String > mReserved;
private static Logger mLogger = LogManager.getLogger() ;
// Words that could not make valid class names so cant otherwise be used as commands or functions
static {
mReserved = new HashSet<String>();
mReserved.add( "class");
mReserved.add( "boolean" );
mReserved.add( "int" );
mReserved.add( "double");
mReserved.add( "true" );
mReserved.add( "false" );
mReserved.add( "long" );
mReserved.add( "char" );
mReserved.add( "null" );
mReserved.add( "float" );
mReserved.add( "byte" );
mReserved.add( "short" );
mReserved.add("package");
mReserved.add("new");
}
public static boolean isReserved(String n )
{
return mReserved.contains(n);
}
public static XValue newXValue(Class<?> cls, List<XValue> args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, CoreException
{
Constructor<?>[] constructors = cls.getConstructors();
return newXValue( cls , constructors , args );
}
public static XValue newXValue(Class<?> cls, Constructor<?>[] constructors ,List<XValue> args) throws CoreException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
Constructor<?> c = getBestMatch(args, constructors);
if (c == null)
throw new InvalidArgumentException("No construtor match found for: " + cls.getName() + "(" + getArgClassesString(args) + ")");
Object obj = c.newInstance(getArgs(c.getParameterTypes(), args));
return XValue.newXValue(null,obj);
}
public static XValue newXValue(String classname, List<XValue> args, ClassLoader classloader) throws Exception {
Class<?> cls = findClass(classname, classloader);
return newXValue( cls , args );
}
public static Class<?> findClass(String classname, ClassLoader classloader) throws ClassNotFoundException
{
Class<?> cls = Class.forName(classname, true, classloader);
return cls;
}
public static <T> T newObject( Class<T> cls , Object... args ) throws InvalidArgumentException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
@SuppressWarnings("unchecked")
Constructor<T>[] constructors = (Constructor<T>[]) cls.getConstructors();
Constructor<T> c = getBestConstructor(constructors, args );
if( c == null )
throw new InvalidArgumentException("Cannot find constructor for: " + cls.getName());
return c.newInstance(args);
}
public static XValue callStatic(String classname, String methodName, List<XValue> args,
ClassLoader classloader) throws Exception {
Class<?> cls = findClass(classname, classloader);
Method m = getBestMatch(cls,methodName, args, true);
if (m == null)
throw new InvalidArgumentException("No method match found for: " + classname + "." + methodName + "(" + getArgClassesString(args) + ")");
return callStaticMethod(m, args);
}
public static XValue callStaticMethod(Method m, List<XValue> args) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException, CoreException
{
Object obj = m.invoke(null, getArgs(m.getParameterTypes(), args));
// Special case for null - use formal return type to cast to right XValue type
if( obj == null ){
if( String.class.isAssignableFrom(m.getReturnType()) )
return XValue.newXValue((String) null);
else
return XValue.newXValue(null,(Object)null);
}
return XValue.newXValue(null,obj);
}
public static String getArgClassesString(List<XValue> args) {
StringBuffer sb = new StringBuffer();
for( XValue arg : args ){
if( sb.length() > 0 )
sb.append(",");
sb.append( arg.asObject().getClass().getName() );
}
return sb.toString();
}
public static XValue callMethod(XValue instance, String methodName, List<XValue> args,
ClassLoader classloader) throws Exception {
Class<?> cls = instance.asObject().getClass();
Method m = getBestMatch(cls,methodName, args, false);
if (m == null)
throw new InvalidArgumentException("No method match found for: " + cls.getName() + "." + methodName);
return callMethod(m, instance.asObject(), args);
}
public static XValue callMethod(Method m, Object instance, List<XValue> args) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException, CoreException
{
Object obj = m.invoke(instance, getArgs(m.getParameterTypes(), args));
// Special case for null - use formal return type to cast to right XValue type
if( obj == null ){
if( String.class.isAssignableFrom(m.getReturnType()) )
return XValue.newXValue((String) null);
else
return XValue.newXValue( null , (Object) null);
}
return XValue.newXValue(null , obj) ;
}
public static Method getBestMatch(Class<?> cls, String methodName, List<XValue> args, boolean bStatic ) throws CoreException {
return getBestMatch( cls.getMethods() , methodName , args , bStatic );
}
public static Method getBestMatch(Method[] methods, String methodName, List<XValue> args, boolean bStatic ) throws CoreException {
Method best = null;
int bestConversions = 0;
for (Method m : methods) {
int conversions = 0;
if (m.getName().equals(methodName)) {
boolean isStatic = (m.getModifiers() & Modifier.STATIC) == Modifier.STATIC ;
if( bStatic && ! isStatic )
continue ;
Class<?>[] params = m.getParameterTypes();
if (params.length == args.size()) {
int i = 0;
for (XValue arg : args) {
int conversion = arg.canConvert(params[i]);
if( conversion < 0 )
break;
i++;
conversions += conversion ;
}
if (i == params.length){
if( best == null || conversions < bestConversions ){
best = m;
bestConversions = conversions ;
}
}
}
}
}
return best;
}
public static Object[] getArgs(Class<?>[] params, List<XValue> args) throws CoreException {
Object[] ret = new Object[params.length];
int i = 0;
for (XValue arg : args) {
ret[i] = arg.convert(params[i]);
i++;
}
return ret;
}
public static Object[] convertObjects(Class<?>[] params, List<Object> args) throws CoreException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Object[] ret = new Object[params.length];
int i = 0;
for (Object arg : args) {
ret[i] = convert(arg , params[i]);
i++;
}
return ret;
}
public static Constructor<?> getBestMatch(List<XValue> args, Constructor<?>[] constructors) throws CoreException {
Constructor<?> best = null;
int bestConversions = 0;
// TODO how to choose best match
for (Constructor<?> c : constructors)
{
Class<?>[] params = c.getParameterTypes();
if (params.length == args.size()) {
int conversions = 0;
int i = 0;
for (XValue arg : args) {
int convert = arg.canConvert(params[i]);
if( convert < 0 )
break;
conversions += convert;
i++;
}
if (i == params.length){
// Find best match
if( best == null || conversions < bestConversions ){
best = c ;
bestConversions = conversions;
}
}
}
}
return best;
}
public static <T> Constructor<T> getBestConstructor(Constructor<T>[] constructors, Object... argValues ) throws InvalidArgumentException {
Constructor<T> best = null;
int bestConversions = 0;
// TODO how to choose best match
for (Constructor<T> c : constructors)
{
Class<?>[] params = c.getParameterTypes();
if (params.length == argValues.length) {
int conversions = 0;
int i = 0;
for (Object obj : argValues) {
int convert = canConvertObject( obj , params[i] );
if( convert < 0 )
break;
conversions += convert;
i++;
}
if (i == params.length){
// Find best match
if( best == null || conversions < bestConversions ){
best = c ;
bestConversions = conversions;
}
}
}
}
return best;
}
public static int hasBeanConstructor(Class<?> targetClass, Class<?> sourceClass) throws InvalidArgumentException
{
Constructor<?> c = getBeanConstructor( targetClass , sourceClass );
if( c == null )
return -1;
if( c.getParameterTypes()[0].isAssignableFrom( sourceClass) )
return 3;
else
return 4;
}
// Does the target hava a single method constructor from a convertable source
public static Constructor<?> getBeanConstructor(Class<?> targetClass, Class<?> sourceClass) throws InvalidArgumentException
{
try {
Constructor<?> c = targetClass.getConstructor(sourceClass);
if( c !=null )
return c ;
} catch (NoSuchMethodException | SecurityException e) {
mLogger.info("Exception getting constructors for: " + targetClass.getName(), e );
return null ;
}
Constructor<?>[] cs = targetClass.getConstructors();
for (Constructor<?> c : cs)
{
Class<?>[] params = c.getParameterTypes();
if (params.length == 1) {
int convert = canConvertClass( sourceClass , params[0] );
if( convert >= 0 )
return c ;
}
}
return null ;
}
static private final Class<?> mNumberWrappers[] = new Class<?>[] {
Integer.class,
Long.class,
Byte.class,
Short.class,
Number.class,
AtomicInteger.class,
AtomicLong.class,
BigDecimal.class,
BigInteger.class,
Double.class,
Float.class
};
public static boolean isWrappedOrPrimativeNumber( Class<?> c )
{
if( c == null )
return false ;
if( c.isPrimitive() && ! ( c == Void.TYPE || c == Boolean.TYPE ) )
return true ;
for( Class<?> w : mNumberWrappers )
if( c.isAssignableFrom(w) )
return true ;
return false ;
}
public static Class<?> fromPrimativeName( String name )
{
switch( name ) {
case "boolean" : return java.lang.Boolean.TYPE ;
case "char" : return java.lang.Character.TYPE ;
case "byte" : return java.lang.Byte.TYPE;
case "short" : return java.lang.Short.TYPE;
case "int" : return java.lang.Integer.TYPE;
case "long" : return java.lang.Long.TYPE;
case "float" : return java.lang.Float.TYPE;
case "double" :return java.lang.Double.TYPE;
case "void" : return java.lang.Void.TYPE;
default :
return null;
}
}
public static <T> T convert(Object value, Class<T> targetClass) throws InvalidArgumentException {
assert( targetClass != null );
assert( value != null );
if( targetClass.isInstance(value))
return targetClass.cast(value);
Class<?> sourceClass = value.getClass();
// Asking for an XdmValue class
if(XdmValue.class.isAssignableFrom(targetClass)) {
if( value instanceof XdmNode )
return (T) (XdmValue) value ;
if( targetClass.isAssignableFrom(XdmAtomicValue.class) ) {
// Try some smart conversions of all types XdmAtomicValue knows
if(value instanceof Boolean)
return (T) new XdmAtomicValue(((Boolean) value).booleanValue());
else if(value instanceof Double)
return (T) new XdmAtomicValue(((Double) value).doubleValue());
else if(value instanceof Float)
return (T) new XdmAtomicValue(((Float) value).floatValue());
else if(value instanceof BigDecimal)
return (T) new XdmAtomicValue((BigDecimal) value);
else if(value instanceof BigDecimal)
return (T) new XdmAtomicValue((BigDecimal) value);
else if(value instanceof URI)
return (T) new XdmAtomicValue((URI) value);
else if(value instanceof Long)
return (T) new XdmAtomicValue((Long) value);
else if(value instanceof QName)
return (T) new XdmAtomicValue((QName) value);
// Still wanting an xdm value
}
if( isAtomic( value ) )
return (T) new XdmAtomicValue(value.toString());
}
boolean bAtomic = isAtomic( value );
Class<?> vclass = value.getClass();
if( targetClass.isPrimitive() && bAtomic ){
/* Try to match non-primative types
*/
if( targetClass == Integer.TYPE ){
if( vclass == Long.class )
value = Integer.valueOf(((Long)value).intValue());
else
if( vclass == Short.class )
value = Integer.valueOf( ((Short)value).intValue() );
else
if( vclass== Byte.class )
value = Integer.valueOf( ((Byte)value).intValue() );
else
value = Integer.valueOf( value.toString() );
}
else
if( targetClass == Long.TYPE ){
if(vclass == Integer.class )
value = Long.valueOf(((Integer)value).intValue());
else
if( vclass == Short.class )
value = Long.valueOf( ((Short)value).intValue() );
else
if( vclass == Byte.class )
value = Long.valueOf( ((Byte)value).intValue() );
value = Long.valueOf( value.toString() );
}
else
if( targetClass == Short.TYPE ){
if( vclass == Integer.class )
value = Short.valueOf((short)((Integer)value).intValue());
else
if( vclass == Long.class )
value = Short.valueOf((short) ((Long)value).intValue() );
else
if( vclass== Byte.class )
value = Short.valueOf((short) ((Byte)value).intValue() );
value = Short.valueOf( value.toString() );
}
else
if( targetClass == Byte.TYPE ){
if( vclass == Integer.class )
value = Byte.valueOf((byte)((Integer)value).intValue());
else
if(vclass == Long.class )
value = Byte.valueOf((byte) ((Long)value).intValue() );
else
if( vclass == Short.class )
value = Byte.valueOf((byte) ((Short)value).intValue() );
value = Byte.valueOf( value.toString() );
}
else
; // skip
return (T) value ;
}
// Bean constructor
Constructor<?> cnst = getBeanConstructor( targetClass , sourceClass ) ;
if( cnst != null )
try {
return (T) cnst.newInstance( convert( value , cnst.getParameterTypes()[0] ) );
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
mLogger.debug("Exception converting argument for constructor",e);
}
// Cast through string
String svalue = value.toString();
if( targetClass == Integer.class )
value = Integer.valueOf( svalue );
else
if( targetClass == Long.class )
value = Long.valueOf( svalue );
else
if( targetClass == Short.class )
value = Short.valueOf(svalue);
else
if( targetClass == Float.class )
value = Float.valueOf(svalue );
else
if( targetClass == Double.class )
value = Double.valueOf(svalue);
else
value = null ;
return (T) value ;
}
public static Object getFieldValue(String classname, XValue instance, String fieldName, ClassLoader classloader) throws InvalidArgumentException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, ClassNotFoundException {
Class<?> cls = findClass(classname, classloader);
return getFieldValue( cls , instance == null ? null : instance.asObject() , fieldName , classloader );
}
public static Object getFieldValue(Class<?> cls , Object instance, String fieldName, ClassLoader classloader) throws InvalidArgumentException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, ClassNotFoundException {
assert( cls != null );
assert( fieldName != null );
Field f = cls.getField(fieldName);
if (f == null)
throw new InvalidArgumentException("No field match found for: " + cls.getName() + "." + fieldName );
Object obj = f.get(instance == null ? null : instance);
return obj ;
}
public static int canConvertClass( Class<?> sourceClass , Class<?> targetClass) throws InvalidArgumentException {
assert( targetClass != null );
if( targetClass == null )
return -1;
// Null case
if( sourceClass == null ) {
if( XdmValue.class.isAssignableFrom(targetClass) )
return 3;
return -1;
}
// Equal class
if( sourceClass.equals(targetClass))
return 0 ;
// Directly assignable
if( targetClass.isAssignableFrom(sourceClass))
return 1 ;
boolean sourceNum = isWrappedOrPrimativeNumber(sourceClass) ;
boolean targetNum = isWrappedOrPrimativeNumber(targetClass) ;
// Boxable
// int <-> Integer
if(sourceNum && targetNum )
return 2 ;
boolean soruceString = isStringClass(sourceClass);
// TypeFamily conversion TO XdmValue
if( XdmValue.class.isAssignableFrom(targetClass)) {
if( XdmNode.class.isAssignableFrom(sourceClass ) )
return 1;
if( XdmAtomicValue.class.isAssignableFrom(sourceClass) )
return 2;
if( sourceNum || soruceString || isBooleanClass( sourceClass ) )
return 3 ;
if( isAtomic( sourceClass ) )
return 3 ;
}
boolean targetString = isStringClass(targetClass);
if( targetClass.isPrimitive() && soruceString )
// convert string to primative, yes
return 4 ;
if( targetString )
return 5 ;
int c = hasBeanConstructor( targetClass , sourceClass );
if( c >= 0 )
return 5 + c ;
return -1;
}
public static int canConvertObject( Object sourceObject , Class<?> targetClass) throws InvalidArgumentException {
return canConvertClass( sourceObject.getClass() , targetClass );
}
public static Class<?> convertToClass(XValue arg, Shell shell) throws CoreException
{
return convertToClass(arg, shell.getClassLoader(null));
}
public static Class<?> convertToClass(XValue arg, ClassLoader classLoader)
{
if( arg.isAtomic() && arg.isString() )
try {
return findClass(arg.toString(),classLoader);
} catch (ClassNotFoundException e) {
mLogger.catching( e );
return null;
}
Object obj = arg.asObject();
if( obj instanceof Class )
return (Class<?>) obj ;
return obj.getClass();
}
public static byte[] toByteArray(Object value, SerializeOpts opts) throws UnsupportedEncodingException {
return value.toString().getBytes( opts.getOutput_text_encoding() );
}
public static int getSize(Object obj)
{
if( obj == null )
if( obj instanceof Collection )
return ((Collection<?>)obj).size();
if( obj instanceof Array )
Array.getLength(obj);
return 1;
}
public static boolean isNullClass(Class<?> cls)
{
return cls == null ;
}
public static boolean isContainer( Object obj)
{
return isContainerClass( obj.getClass());
}
public static boolean isContainerClass(Class<?> cls)
{
if( cls == null )
return false;
if( Collection.class.isAssignableFrom(cls) ||
Array.class.isAssignableFrom(cls) )
return true ;
return false ;
}
public static boolean isArrayClass(Class<?> cls)
{
if( cls == null )
return false;
if( List.class.isAssignableFrom(cls) ||
Array.class.isAssignableFrom(cls) )
return true ;
return false ;
}
public static boolean isObjectClass(Class<?> cls)
{
if( cls == null )
return false;
return ( ! isAtomicClass( cls ) );
}
public static boolean isBooleanClass( Class<?> c )
{
return c == Boolean.TYPE ||
Boolean.class.isAssignableFrom( c ) ;
}
//DAL: TODO: See 1.3
public static boolean isStringClass( Class<?> cls) {
return String.class.isAssignableFrom(cls ) ||
CharSequence.class.isAssignableFrom(cls );
}
public static boolean isAtomicClass(Class<?> cls)
{
return cls.isEnum() ||
isWrappedOrPrimativeNumber( cls ) ||
isStringClass( cls ) ;
}
public static boolean isClassClass(Class<?> cls)
{
return Class.class.isAssignableFrom(cls);
}
public static Object stringConcat(Object o, Object that)
{
return o.toString() + that.toString() ;
}
public static boolean isNumber(String v) {
return toNumber(v,null) != null ;
}
// Is a or attomic collection type that is empty
public static boolean isEmpty(Object value) {
if( isAtomic( value ) )
return isAtomicEmpty(value);
else
return isObjectEmpty( value );
}
public static boolean isObjectEmpty(Object value)
{
if( value instanceof Collection )
return ((Collection<?>)value).isEmpty() ;
if( value instanceof Map)
return ((Map<?, ?>)value).isEmpty() ;
if( value.getClass().isArray() )
return Array.getLength(value) == 0 ;
return false ;
}
private static boolean isAtomicEmpty(Object value)
{
return value == null || value.toString().isEmpty();
}
private static boolean isAtomic(Object value)
{
return isAtomicClass( value.getClass() );
}
public static void setNameIndexedValue( Object obj, String ind, Object object) throws NoSuchFieldException, SecurityException, InvalidArgumentException, IllegalArgumentException, IllegalAccessException {
Field f = obj.getClass().getField(ind);
if (f == null)
throw new InvalidArgumentException("No field match found for: " + getClassName(obj) + "." + ind );
f.set(obj, object);
}
public static String getClassName(Object obj)
{
assert( obj != null );
if( obj == null )
return "";
return obj.getClass().getName();
}
@SuppressWarnings("rawtypes")
public static void setNamePositionalValue( Object obj, int index, Object object) throws InvalidArgumentException
{
if(obj.getClass().isArray() ) {
Array.set( obj ,index, object);
} else
if( obj instanceof List) {
((List)obj).set( index, object);
}
else
throw new InvalidArgumentException("No positional index for class: " + getClassName(obj) );
}
public static boolean isArrayOf(Object value, Class<?> cls) {
return value.getClass().isArray() &&
cls.isAssignableFrom(value.getClass().getComponentType());
}
public static Object getIndexValue(Object obj, int index )
{
Object res = null ;
if(obj.getClass().isArray() ) {
res = Array.get( obj , index);
} else
if( obj instanceof List) {
res = ((List<?>)obj).get(index);
}
return res;
}
public static <T> List<T> getValues( Object obj ){
if(obj.getClass().isArray() ) {
Object array = obj ;
int len = ArrayUtils.getLength(array);
ArrayList<T> list = new ArrayList<>(len);
for( int i = 0 ;i < len ; i++ )
list.add( (T) Array.get(array, i));
return list ;
}
if( obj instanceof Collection ){
@SuppressWarnings({ "rawtypes", "unchecked" })
Collection<T> c = ((Collection)obj) ;
ArrayList<T> list = new ArrayList<>( c.size() );
list.addAll( c );
return list;
}
return (List<T>) Collections.singletonList(obj);
}
public static boolean isCollection(Object obj) {
return obj instanceof Collection;
}
public static String simpleTypeName(Object value)
{
if( value == null )
return "null";
Class<?> cls = value.getClass();
if( isStringClass( cls ) )
return "string" ;
if( isArrayClass( cls ) )
return "array" ;
if( isWrappedOrPrimativeNumber( cls ) )
return "number" ;
return "object" ;
}
public static boolean hasKey(Object obj, String key) {
if( obj instanceof Map )
return ((Map)obj).containsKey(key);
return false ;
}
public static Object getNameIndexValue(Object obj, String ind) throws CoreException {
if( obj instanceof Map )
return ((Map)obj).get(ind);
try {
return getFieldValue(obj.getClass(), obj, ind, null);
} catch (SecurityException | NoSuchFieldException | IllegalArgumentException
| IllegalAccessException | ClassNotFoundException e) {
Util.wrapCoreException("Exception getting value from java class: " + obj.getClass().getName(), e);
}
return null;
}
public static boolean isList(Object obj) {
return isArrayClass(obj.getClass()) ||
obj instanceof List ;
}
public static Package convertToPackage(XValue arg) {
if( arg.isAtomic() && arg.isString() )
return Package.getPackage(arg.toString());
Object obj = arg.asObject();
if( obj instanceof Package)
return (Package) arg.asObject();
return null ;
}
public static String convertToCamelCase(String name) {
if (name.indexOf('-') < 0)
return name;
String parts[] = name.split("-");
if (parts.length == 1)
return name;
StringBuilder result = new StringBuilder(name.length());
for (String p : parts) {
if (p.length() == 0)
continue;
if (result.length() == 0)
result.append(p);
else {
result.append(Character.toUpperCase(p.charAt(0)));
result.append(p.substring(1));
}
}
return result.toString();
}
public static String convertFromCamelCase(String name) {
StringBuilder result = new StringBuilder(name.length());
for( char c : name.toCharArray() ){
if( Character.isUpperCase(c) ){
result.append('-');
result.append( Character.toLowerCase(c));
} else
result.append(c);
}
return result.toString();
}
public static <T> List<T> uniqueList(List<T> list) {
if( list == null )
return null ;
Set<T> set = new HashSet<T>(list);
if( set.size() == list.size() )
return list ;
set.clear();
List<T> alist = new ArrayList<>( set.size());
for( T item : list ){
if( set.contains(item))
continue;
set.add( item );
alist.add( item );
}
return alist ;
}
public static Class<?> getContainedType(Object value) {
Class<?> c = getClass( value );
return c.getComponentType();
}
public static Class<?> getClass(Object value) {
assert( value != null );
if( value instanceof Class )
return (Class<?>) value ;
return value.getClass();
}
public static boolean isContainerOf(Object obj, Class<?> c ) {
assert( obj != null );
return isArrayOf( obj , c ) ||
isCollectionOf( obj , c );
}
public static Number toNumber(String v, Number def) {
try {
if( Util.isInt(v, true))
return Long.parseLong(v);
return Double.parseDouble(v);
} catch (NumberFormatException e) {
// silent
return def;
}
}
public static boolean isCollectionOf(Object obj, Class<?> c) {
if( obj instanceof Collection ){
Collection col = (Collection<?>) obj;
if( col.isEmpty())
return true ; // sure WTF
return ClassUtils.isAssignable(col.iterator().next().getClass(), c );
}
return false ;
}
public static String toGetterName(String f) {
return "get" + toFirstUpperCase(f);
}
public static String toSetterName(String f) {
return "set" + toFirstUpperCase(f);
}
protected static String toFirstUpperCase(String f) {
return Character.toUpperCase(f.charAt(0)) + f.substring(1);
}
}
//
//
//Copyright (C) 2008-2014 David A. Lee.
//
//The contents of this file are subject to the "Simplified BSD License" (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.opensource.org/licenses/bsd-license.php
//
//Software distributed under the License is distributed on an "AS IS" basis,
//WITHOUT WARRANTY OF ANY KIND, either express or implied.
//See the License for the specific language governing rights and limitations under the License.
//
//The Original Code is: all this file.
//
//The Initial Developer of the Original Code is David A. Lee
//
//Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
//
//Contributor(s): none.
//