package fr.lteconsulting.hexa.classinfo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ClassInfoJre implements IClassInfo
{
private static final ClassInfoJre instance = new ClassInfoJre();
public static ClassInfoJre get()
{
return instance;
}
private ClassInfoJre()
{
}
HashMap<Class<?>, ClazzJre<?>> clazzCache = new HashMap<>();
@Override
public <T> Clazz<T> Clazz( Class<T> clazz )
{
ClazzJre<T> result = FindClazz( clazz );
if( result == null )
throw new RuntimeException( "Cannot find class '" + clazz.getName() + "'" );
return result;
}
@Override
public <T> void RegisterClazz( Clazz<T> clazz )
{
clazzCache.put( clazz.getReflectedClass(), (ClazzJre<?>) clazz );
}
@Override
public Clazz<?> FindClazz( String name )
{
try
{
return FindClazz( Class.forName( name ) );
}
catch( ClassNotFoundException e )
{
return null;
}
}
@Override
public <T> ClazzJre<T> FindClazz( Class<T> clazz )
{
@SuppressWarnings( "unchecked" )
ClazzJre<T> result = (ClazzJre<T>) clazzCache.get( clazz );
if( result == null )
{
result = new ClazzJre<T>( clazz );
clazzCache.put( clazz, result );
}
return result;
}
@Override
public Set<Class<?>> GetRegisteredClazz()
{
return clazzCache.keySet();
}
}
class ClazzJre<T> implements Clazz<T>
{
private Class<T> classs;
private List<Field> fields;
private List<Method> methods;
private Map<String, Method> methodsByName;
public ClazzJre( Class<T> classs )
{
this.classs = classs;
}
@Override
public String getClassName()
{
return classs.getName();
}
@Override
public Class<T> getReflectedClass()
{
return classs;
}
@Override
public Clazz<? super T> getSuperclass()
{
return ClassInfoJre.get().Clazz( classs.getSuperclass() );
}
@Override
public List<Field> getAllFields()
{
if( fields != null )
return fields;
fields = new ArrayList<>();
Class<?> cur = classs;
while( cur != null && cur != Object.class )
{
for( java.lang.reflect.Field f : classs.getDeclaredFields() )
fields.add( new FieldJre( f ) );
cur = cur.getSuperclass();
}
return fields;
}
@Override
public Field getAllField( String fieldName )
{
for( Field field : getAllFields() )
{
if( field.getName().equals( fieldName ) )
return field;
}
return null;
}
@Override
public List<Field> getFields()
{
// TODO
return getAllFields();
}
@Override
public Field getField( String fieldName )
{
// TODO
return getAllField( fieldName );
}
@Override
public List<Field> getDeclaredFields()
{
// TODO
return getAllFields();
}
@Override
public Field getDeclaredField( String fieldName )
{
// TODO
return getAllField( fieldName );
}
@Override
public List<Method> getMethods()
{
if( methods != null )
return methods;
methods = new ArrayList<>();
for( java.lang.reflect.Method m : classs.getMethods() )
methods.add( new MethodJre( m ) );
return methods;
}
@Override
public Method getMethod( String methodName )
{
if( methodsByName == null ){
methodsByName = new HashMap<>();
for( Method m : getMethods() )
methodsByName.put(m.getName(), m);
}
return methodsByName.get(methodName);
}
@Override
public T NEW()
{
T result;
try
{
result = classs.newInstance();
}
catch( Exception e )
{
throw new RuntimeException( e );
}
return result;
}
}
class FieldJre implements Field
{
private java.lang.reflect.Field field;
public FieldJre( java.lang.reflect.Field field )
{
this.field = field;
if( !field.isAccessible() )
field.setAccessible( true );
}
@Override
public String getName()
{
return field.getName();
}
@Override
public Class<?> getType()
{
return field.getType();
}
@Override
public void setValue( Object object, Object value )
{
try
{
field.set( object, value );
}
catch( Exception e )
{
throw new RuntimeException( e );
}
}
@Override
public <OUT> OUT getValue( Object object )
{
try
{
@SuppressWarnings( "unchecked" )
OUT result = (OUT) field.get( object );
return result;
}
catch( Exception e )
{
throw new RuntimeException( e );
}
}
@Override
public void copyValueTo( Object source, Object destination )
{
try
{
field.set( destination, field.get( source ) );
}
catch( Exception e )
{
throw new RuntimeException( e );
}
}
@Override
public int getModifier()
{
return field.getModifiers();
}
@Override
public String toString()
{
return "[FieldJre " + field.getType().getName() + " " + field.getName() + "]";
}
}
class MethodJre implements Method
{
private java.lang.reflect.Method method;
private List<Class<?>> parameterTypes;
public MethodJre( java.lang.reflect.Method method )
{
this.method = method;
if( !method.isAccessible() )
method.setAccessible( true );
}
@Override
public String getName()
{
return method.getName();
}
@Override
public Class<?> getReturnType()
{
return method.getReturnType();
}
@Override
public List<Class<?>> getParameterTypes()
{
if( parameterTypes != null )
return parameterTypes;
Class<?>[] arr = method.getParameterTypes();
parameterTypes = new ArrayList<>();
for( Class<?> c : arr )
parameterTypes.add( c );
return parameterTypes;
}
@Override
public Object invoke( Object target, Object... parameters )
{
try
{
return method.invoke( target, parameters );
}
catch( Exception e )
{
throw new RuntimeException( e );
}
}
@Override
public String toString()
{
return "[MethodJre " + method.getName() + "]";
}
}