use of org.drools.wiring.api.util.ByteArrayClassLoader in project drools by kiegroup.
the class ClassFieldAccessorFactory method getClassFieldReader.
@Override
public BaseClassFieldReader getClassFieldReader(Class<?> clazz, String fieldName, CacheEntry cache) {
try {
// if it is a self reference
if (SELF_REFERENCE_FIELD.equals(fieldName)) {
// then just create an instance of the special class field extractor
return new SelfReferenceClassFieldReader(clazz);
} else {
// otherwise, bytecode generate a specific extractor
ClassFieldInspector inspector = getClassFieldInspector(clazz, cache);
Method getterMethod = inspector.getGetterMethods().get(fieldName);
Integer index = inspector.getFieldNames().get(fieldName);
Class<?> fieldType = inspector.getFieldType(fieldName);
if (fieldType == null && fieldName.length() > 1 && Character.isLowerCase(fieldName.charAt(0)) && Character.isUpperCase(fieldName.charAt(1))) {
// it might be that odd case of javabeans naming conventions that does not use lower case first letters if the second is uppercase
String altFieldName = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
fieldType = inspector.getFieldType(altFieldName);
if (fieldType != null) {
// it seems it is the corner case indeed.
getterMethod = inspector.getGetterMethods().get(altFieldName);
index = inspector.getFieldNames().get(altFieldName);
}
}
if (fieldType != null && getterMethod != null) {
final String className = ClassFieldAccessorFactory.BASE_PACKAGE + "/" + Type.getInternalName(clazz) + Math.abs((long) System.identityHashCode(clazz)) + "$" + getterMethod.getName();
// generating byte array to create target class
final byte[] bytes = dumpReader(clazz, className, getterMethod, fieldType);
// use bytes to get a class
ByteArrayClassLoader byteArrayClassLoader = cache.getByteArrayClassLoader();
final Class<?> newClass = byteArrayClassLoader.defineClass(className.replace('/', '.'), bytes, PROTECTION_DOMAIN);
// instantiating target class
final ValueType valueType = ValueType.determineValueType(fieldType);
final Object[] params = { index, fieldType, valueType };
return (BaseClassFieldReader) newClass.getConstructors()[0].newInstance(params);
} else {
// must be a public field
return null;
}
}
} catch (final RuntimeException e) {
throw e;
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
use of org.drools.wiring.api.util.ByteArrayClassLoader in project drools by kiegroup.
the class ClassGenerator method generateClass.
private Class<?> generateClass() {
if (clazz == null) {
byte[] bytecode = generateBytecode();
if (ClassUtils.isAndroid()) {
ByteArrayClassLoader cl = (ByteArrayClassLoader) ClassUtils.instantiateObject("org.drools.android.MultiDexClassLoader", null, writableClassLoader.asClassLoader());
clazz = cl.defineClass(className, bytecode, null);
} else {
clazz = writableClassLoader.writeClass(className, bytecode);
}
}
return clazz;
}
use of org.drools.wiring.api.util.ByteArrayClassLoader in project drools by kiegroup.
the class ClassFieldAccessorFactory method getClassFieldWriter.
@Override
public BaseClassFieldWriter getClassFieldWriter(Class<?> clazz, String fieldName, CacheEntry cache) {
ByteArrayClassLoader byteArrayClassLoader = cache.getByteArrayClassLoader();
Map<Class<?>, ClassFieldInspector> inspectors = cache.getInspectors();
try {
// otherwise, bytecode generate a specific extractor
ClassFieldInspector inspector = inspectors.get(clazz);
if (inspector == null) {
inspector = new ClassFieldInspectorImpl(clazz);
inspectors.put(clazz, inspector);
}
Method setterMethod = inspector.getSetterMethods().get(fieldName);
Integer index = inspector.getFieldNames().get(fieldName);
if (setterMethod == null && fieldName.length() > 1 && Character.isLowerCase(fieldName.charAt(0)) && Character.isUpperCase(fieldName.charAt(1))) {
// it might be that odd case of javabeans naming conventions that does not use lower case first letters if the second is uppercase
String altFieldName = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
setterMethod = inspector.getSetterMethods().get(altFieldName);
index = inspector.getFieldNames().get(altFieldName);
}
if (setterMethod != null) {
final Class<?> fieldType = setterMethod.getParameterTypes()[0];
final String className = ClassFieldAccessorFactory.BASE_PACKAGE + "/" + Type.getInternalName(clazz) + Math.abs((long) System.identityHashCode(clazz)) + "$" + setterMethod.getName();
// generating byte array to create target class
final byte[] bytes = dumpWriter(clazz, className, setterMethod, fieldType);
// use bytes to get a class
final Class<?> newClass = byteArrayClassLoader.defineClass(className.replace('/', '.'), bytes, PROTECTION_DOMAIN);
// instantiating target class
final ValueType valueType = ValueType.determineValueType(fieldType);
final Object[] params = { index, fieldType, valueType };
return (BaseClassFieldWriter) newClass.getConstructors()[0].newInstance(params);
} else {
if (inspector.getFieldNames().containsKey(fieldName)) {
return null;
} else {
throw new RuntimeException("Field/method '" + fieldName + "' not found for class '" + clazz.getName() + "'");
}
}
} catch (final RuntimeException e) {
throw e;
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
Aggregations