From 5edaf6a5a2986045b88b62f31c607baedad00536 Mon Sep 17 00:00:00 2001 From: Clisprail Date: Mon, 4 Aug 2014 19:01:52 +0200 Subject: [PATCH] Reflection wrapper started --- .../org/parabot/core/reflect/RefClass.java | 74 ++++++++ .../org/parabot/core/reflect/RefField.java | 174 ++++++++++++++++++ .../org/parabot/core/reflect/RefUtils.java | 23 +++ 3 files changed, 271 insertions(+) create mode 100644 parabotv2/src/org/parabot/core/reflect/RefClass.java create mode 100644 parabotv2/src/org/parabot/core/reflect/RefField.java create mode 100644 parabotv2/src/org/parabot/core/reflect/RefUtils.java diff --git a/parabotv2/src/org/parabot/core/reflect/RefClass.java b/parabotv2/src/org/parabot/core/reflect/RefClass.java new file mode 100644 index 0000000..a9b0aef --- /dev/null +++ b/parabotv2/src/org/parabot/core/reflect/RefClass.java @@ -0,0 +1,74 @@ +package org.parabot.core.reflect; + +import java.util.ArrayList; + +/** + * + * A RefClass represents a class or an instance of that class, if no instance is + * provided this class can only get values from static fields and only invoke + * static methods + * + * @author Everel + * + */ +public class RefClass { + private Object instance; + private Class clazz; + + public RefClass(Class clazz) { + this.clazz = clazz; + } + + public RefClass(Object instance) { + setInstance(instance); + } + + public RefClass(Class clazz, Object instance) { + this.clazz = clazz; + setInstance(instance); + } + + /** + * Sets the instance of this class so now non static fields values can be retrieved and non static methods can be invoked + * @param instance instance of this class. + */ + public void setInstance(Object instance) { + if(instance == null) { + this.instance = null; + return; + } + if (this.clazz != null) { + if (!clazz.isInstance(instance)) { + throw new IllegalArgumentException(instance + + " is not an instance of the class " + clazz); + } + } + this.instance = instance; + if (this.clazz == null) { + this.clazz = instance.getClass(); + } + } + + /** + * + * Gets the instance of this class + * + * @return if an instance of this class is known it will return that instance, otherwise it will return null. + */ + public Object getInstance() { + return this.instance; + } + + /** + * Gets the class' fields + * @return all fields if an instance is provided, otherwise only static fields + */ + public RefField[] getFields() { + ArrayList fields = new ArrayList(); + if(this.instance == null) { + return null; + } + return fields.toArray(new RefField[fields.size()]); + } + +} diff --git a/parabotv2/src/org/parabot/core/reflect/RefField.java b/parabotv2/src/org/parabot/core/reflect/RefField.java new file mode 100644 index 0000000..96c7e1e --- /dev/null +++ b/parabotv2/src/org/parabot/core/reflect/RefField.java @@ -0,0 +1,174 @@ +package org.parabot.core.reflect; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; + +/** + * + * A RefField represents a field in a class + * + * @author Everel + * + */ +public class RefField { + private Field field; + private Object instance; + + public RefField(Field field) { + this(field, null); + } + + public RefField(Field field, Object instance) { + this.field = field; + this.instance = instance; + } + + public Object asObject() { + if(instance == null && !isStatic()) { + throw new IllegalStateException("Non static field cannot be fetched without an instance"); + } + try { + if(!isAccessible()) { + field.setAccessible(true); + } + return field.get(instance); + } catch (Throwable t) { + t.printStackTrace(); + } + return null; + } + + public int asInt() { + return (int) asObject(); + } + + public long asLong() { + return (long) asObject(); + } + + public double asDouble() { + return (double) asObject(); + } + + public float asFloat() { + return (float) asObject(); + } + + public boolean asBoolean() { + return (boolean) asObject(); + } + + public short asShort() { + return (short) asObject(); + } + + public byte asByte() { + return (byte) asObject(); + } + + public String asString() { + return (String) asObject(); + } + + public char asChar() { + return (char) asObject(); + } + + public Class getType() { + return field.getType(); + } + + public Type getGenericType() { + return field.getGenericType(); + } + + public boolean isPrimitiveType() { + return RefUtils.isPrimitive(getType()); + } + + public boolean isString() { + return getType() == String.class; + } + + public boolean isStatic() { + return Modifier.isStatic(field.getModifiers()); + } + + public boolean isAbstract() { + return Modifier.isAbstract(field.getModifiers()); + } + + public boolean isFinal() { + return Modifier.isFinal(field.getModifiers()); + } + + public boolean isInterface() { + return Modifier.isInterface(field.getModifiers()); + } + + public boolean isNative() { + return Modifier.isNative(field.getModifiers()); + } + + public boolean isPrivate() { + return Modifier.isPrivate(field.getModifiers()); + } + + public boolean isProtected() { + return Modifier.isProtected(field.getModifiers()); + } + + public boolean isPublic() { + return Modifier.isPublic(field.getModifiers()); + } + + public boolean isStrict() { + return Modifier.isStrict(field.getModifiers()); + } + + public boolean isSynchronized() { + return Modifier.isSynchronized(field.getModifiers()); + } + + public boolean isTransient() { + return Modifier.isTransient(field.getModifiers()); + } + + public boolean isVolatile() { + return Modifier.isVolatile(field.getModifiers()); + } + + public boolean isEnumConstants() { + return field.isEnumConstant(); + } + + public boolean isAccessible() { + return field.isAccessible(); + } + + public boolean isSynthetic() { + return field.isSynthetic(); + } + + public String getName() { + return field.getName(); + } + + public int getModifiers() { + return field.getModifiers(); + } + + public Field getField() { + return field; + } + + public String toGenericString() { + return field.toGenericString(); + } + + public String toString() { + return field.toString(); + } + +} diff --git a/parabotv2/src/org/parabot/core/reflect/RefUtils.java b/parabotv2/src/org/parabot/core/reflect/RefUtils.java new file mode 100644 index 0000000..fc38485 --- /dev/null +++ b/parabotv2/src/org/parabot/core/reflect/RefUtils.java @@ -0,0 +1,23 @@ +package org.parabot.core.reflect; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * + * @author Everel + * + */ +public class RefUtils { + + public static final Set> PRIMITIVE_TYPES = new HashSet>( + Arrays.asList(Boolean.class, Character.class, Byte.class, + Short.class, Integer.class, Long.class, Float.class, + Double.class, Void.class)); + + public static boolean isPrimitive(Class clazz) { + return PRIMITIVE_TYPES.contains(clazz); + } + +}