Search in sources :

Example 11 with ClassFieldInspector

use of org.drools.core.util.asm.ClassFieldInspector in project drools by kiegroup.

the class ClassFieldAccessorFactory method getClassFieldWriter.

public static 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 ClassFieldInspector(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(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)) {
                if (inspector.getGetterMethods().get(fieldName) != null) {
                    // field without setter
                    return null;
                } else {
                    // public field
                    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);
    }
}
Also used : ByteArrayClassLoader(org.drools.core.util.ByteArrayClassLoader) Method(java.lang.reflect.Method) IOException(java.io.IOException) ClassFieldInspector(org.drools.core.util.asm.ClassFieldInspector)

Aggregations

ClassFieldInspector (org.drools.core.util.asm.ClassFieldInspector)11 IOException (java.io.IOException)7 Method (java.lang.reflect.Method)5 TypeFieldDescr (org.drools.compiler.lang.descr.TypeFieldDescr)3 Field (java.lang.reflect.Field)2 HashMap (java.util.HashMap)2 PatternDescr (org.drools.compiler.lang.descr.PatternDescr)2 FieldDefinition (org.drools.core.factmodel.FieldDefinition)2 ByteArrayClassLoader (org.drools.core.util.ByteArrayClassLoader)2 ArrayList (java.util.ArrayList)1 Arrays.asList (java.util.Arrays.asList)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1 TypeDeclarationError (org.drools.compiler.compiler.TypeDeclarationError)1 ClassFieldAccessor (org.drools.core.base.ClassFieldAccessor)1 ClassFieldAccessorStore (org.drools.core.base.ClassFieldAccessorStore)1 SelfReferenceClassFieldReader (org.drools.core.base.extractors.SelfReferenceClassFieldReader)1 ClassDefinition (org.drools.core.factmodel.ClassDefinition)1