Search in sources :

Example 6 with ClassFieldInspector

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

the class PackageHeaderLoader method addFields.

private void addFields(Class clazz) throws IOException {
    String className = clazz.getName();
    ClassFieldInspector inspector = new ClassFieldInspector(clazz);
    Set<String> fieldNames = inspector.getFieldNames().keySet();
    Map<String, Class<?>> fieldTypes = inspector.getFieldTypes();
    addThisField(className);
    for (String field : fieldNames) {
        if (IGNORED_FIELDS.contains(field)) {
            continue;
        }
        fieldsByClassNames.put(className, field);
        fieldTypesByClassAndFieldNames.put(className + "." + field, fieldTypes.get(field).getName());
    }
}
Also used : ClassFieldInspector(org.drools.core.util.asm.ClassFieldInspector)

Example 7 with ClassFieldInspector

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

the class AbstractTraitFactory method buildClassDefinition.

public ClassDefinition buildClassDefinition(Class<?> klazz, Class<?> wrapperClass) throws IOException {
    ClassFieldInspector inspector = new ClassFieldInspector(klazz);
    ClassFieldAccessorStore store = getClassFieldAccessorStore();
    ClassDefinition def;
    if (!klazz.isInterface()) {
        String className = wrapperClass.getName();
        String superClass = wrapperClass != klazz ? klazz.getName() : klazz.getSuperclass().getName();
        String[] interfaces = new String[klazz.getInterfaces().length + 1];
        for (int j = 0; j < klazz.getInterfaces().length; j++) {
            interfaces[j] = klazz.getInterfaces()[j].getName();
        }
        interfaces[interfaces.length - 1] = CoreWrapper.class.getName();
        def = new ClassDefinition(className, superClass, interfaces);
        def.setDefinedClass(wrapperClass);
        Traitable tbl = wrapperClass.getAnnotation(Traitable.class);
        def.setTraitable(true, tbl != null && tbl.logical());
        Map<String, Field> fields = inspector.getFieldTypesField();
        for (Field f : fields.values()) {
            if (f != null) {
                FieldDefinition fld = new FieldDefinition();
                fld.setName(f.getName());
                fld.setTypeName(f.getType().getName());
                fld.setInherited(true);
                ClassFieldAccessor accessor = store.getAccessor(def.getDefinedClass().getName(), fld.getName());
                fld.setReadWriteAccessor(accessor);
                if (inspector.getGetterMethods().containsKey(f.getName())) {
                    fld.setGetterName(inspector.getGetterMethods().get(f.getName()).getName());
                }
                if (inspector.getSetterMethods().containsKey(f.getName())) {
                    fld.setSetterName(inspector.getSetterMethods().get(f.getName()).getName());
                }
                def.addField(fld);
            }
        }
    } else {
        String className = klazz.getName();
        String superClass = Object.class.getName();
        String[] interfaces = new String[klazz.getInterfaces().length];
        for (int j = 0; j < klazz.getInterfaces().length; j++) {
            interfaces[j] = klazz.getInterfaces()[j].getName();
        }
        def = new ClassDefinition(className, superClass, interfaces);
        def.setDefinedClass(klazz);
        Map<String, Method> properties = inspector.getGetterMethods();
        for (String key : properties.keySet()) {
            Method m = properties.get(key);
            if (m != null && m.getDeclaringClass() != TraitType.class && m.getDeclaringClass() != Thing.class && inspector.getSetterMethods().containsKey(key)) {
                FieldDefinition fld = new FieldDefinition();
                fld.setName(getterToFieldName(m.getName()));
                fld.setTypeName(m.getReturnType().getName());
                fld.setInherited(true);
                ClassFieldAccessor accessor = store.getAccessor(def.getDefinedClass().getName(), fld.getName());
                fld.setReadWriteAccessor(accessor);
                fld.setGetterName(m.getName());
                fld.setSetterName(inspector.getSetterMethods().get(key).getName());
                def.addField(fld);
            }
        }
    }
    return def;
}
Also used : FieldDefinition(org.drools.core.factmodel.FieldDefinition) ClassFieldAccessorStore(org.drools.core.base.ClassFieldAccessorStore) Method(java.lang.reflect.Method) ClassDefinition(org.drools.core.factmodel.ClassDefinition) Field(java.lang.reflect.Field) ClassFieldAccessor(org.drools.core.base.ClassFieldAccessor) ClassFieldInspector(org.drools.core.util.asm.ClassFieldInspector)

Example 8 with ClassFieldInspector

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

the class TraitBuilderUtil method findMixinInfo.

static MixinInfo findMixinInfo(Class<?> traitClass) {
    if (traitClass == null) {
        return null;
    }
    Map<Class<?>, List<Method>> mixinMethodMap = findMixinMethodImpls(traitClass);
    if (mixinMethodMap.isEmpty()) {
        return null;
    }
    MixinInfo mixinInfo = new MixinInfo(traitClass);
    try {
        mixinInfo.mixinClasses = new ArrayList<>();
        mixinInfo.mixinClasses.addAll(mixinMethodMap.keySet());
        mixinInfo.mixinMethods = new HashMap<>();
        mixinInfo.mixinGetSet = new HashMap<>();
        for (Map.Entry<Class<?>, List<Method>> entry : mixinMethodMap.entrySet()) {
            Class<?> mixinClass = entry.getKey();
            ClassFieldInspector cfi = new ClassFieldInspector(mixinClass);
            for (Method m : entry.getValue()) {
                try {
                    traitClass.getMethod(m.getName(), m.getParameterTypes());
                    if (cfi.getGetterMethods().containsValue(m) || cfi.getSetterMethods().containsValue(m)) {
                        Map<String, Method> map = mixinInfo.mixinGetSet.computeIfAbsent(mixinClass, k -> new HashMap<>());
                        map.put(m.getName(), m);
                    } else {
                        Set<Method> set = mixinInfo.mixinMethods.computeIfAbsent(mixinClass, k -> new HashSet<>());
                        set.add(m);
                    }
                } catch (NoSuchMethodException ignored) {
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return mixinInfo;
}
Also used : Method(java.lang.reflect.Method) ArrayList(java.util.ArrayList) List(java.util.List) Arrays.asList(java.util.Arrays.asList) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ClassFieldInspector(org.drools.core.util.asm.ClassFieldInspector)

Example 9 with ClassFieldInspector

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

the class TypeDeclarationFactory method checkRedeclaration.

protected void checkRedeclaration(AbstractClassTypeDeclarationDescr typeDescr, TypeDeclaration type, PackageRegistry pkgRegistry) {
    TypeDeclaration previousTypeDeclaration = kbuilder.getPackageRegistry(typeDescr.getNamespace()).getPackage().getTypeDeclaration(typeDescr.getTypeName());
    try {
        // to the behavior previous these changes
        if (!type.isDefinition()) {
            // new declarations of a POJO can't declare new fields,
            // except if the POJO was previously generated/compiled and saved into the kjar
            Class<?> existingDeclarationClass = TypeDeclarationUtils.getExistingDeclarationClass(typeDescr, pkgRegistry);
            if (!kbuilder.getBuilderConfiguration().isPreCompiled() && !GeneratedFact.class.isAssignableFrom(existingDeclarationClass) && !type.getTypeClassDef().getFields().isEmpty()) {
                try {
                    Class existingClass = pkgRegistry.getPackage().getTypeResolver().resolveType(typeDescr.getType().getFullName());
                    ClassFieldInspector cfi = new ClassFieldInspector(existingClass);
                    int fieldCount = 0;
                    for (String existingFieldName : cfi.getFieldTypesField().keySet()) {
                        if (!cfi.isNonGetter(existingFieldName) && !"class".equals(existingFieldName) && cfi.getSetterMethods().containsKey(existingFieldName) && cfi.getGetterMethods().containsKey(existingFieldName)) {
                            if (!typeDescr.getFields().containsKey(existingFieldName)) {
                                type.setValid(false);
                                kbuilder.addBuilderResult(new TypeDeclarationError(typeDescr, "New declaration of " + typeDescr.getType().getFullName() + " does not include field " + existingFieldName));
                            } else {
                                String fldType = cfi.getFieldType(existingFieldName).getName();
                                fldType = TypeDeclarationUtils.toBuildableType(fldType, kbuilder.getRootClassLoader());
                                TypeFieldDescr declaredField = typeDescr.getFields().get(existingFieldName);
                                if (!fldType.equals(type.getTypeClassDef().getField(existingFieldName).getTypeName())) {
                                    type.setValid(false);
                                    kbuilder.addBuilderResult(new TypeDeclarationError(typeDescr, "New declaration of " + typeDescr.getType().getFullName() + " redeclared field " + existingFieldName + " : \n" + "existing : " + fldType + " vs declared : " + declaredField.getPattern().getObjectType()));
                                } else {
                                    fieldCount++;
                                }
                            }
                        }
                    }
                    if (fieldCount != typeDescr.getFields().size()) {
                        kbuilder.addBuilderResult(reportDeclarationDiff(cfi, typeDescr));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    type.setValid(false);
                    kbuilder.addBuilderResult(new TypeDeclarationError(typeDescr, "Unable to redeclare " + typeDescr.getType().getFullName() + " : " + e.getMessage()));
                } catch (ClassNotFoundException e) {
                    type.setValid(false);
                    kbuilder.addBuilderResult(new TypeDeclarationError(typeDescr, "Unable to redeclare " + typeDescr.getType().getFullName() + " : " + e.getMessage()));
                }
            }
        } else if (previousTypeDeclaration != null) {
            // previous declaration can be null during an incremental compilation
            int typeComparisonResult = this.compareTypeDeclarations(previousTypeDeclaration, type);
            if (typeComparisonResult < 0) {
                // oldDeclaration is "less" than newDeclaration -> error
                kbuilder.addBuilderResult(new TypeDeclarationError(typeDescr, typeDescr.getType().getFullName() + " declares more fields than the already existing version"));
                type.setValid(false);
            } else if (typeComparisonResult > 0 && !type.getTypeClassDef().getFields().isEmpty()) {
                // oldDeclaration is "grater" than newDeclaration -> error
                kbuilder.addBuilderResult(new TypeDeclarationError(typeDescr, typeDescr.getType().getFullName() + " declares less fields than the already existing version"));
                type.setValid(false);
            }
            // fields present in the previous declaration
            if (type.getNature() == TypeDeclaration.Nature.DECLARATION) {
                mergeTypeDeclarations(previousTypeDeclaration, type);
            }
        }
    } catch (IncompatibleClassChangeError error) {
        // if the types are incompatible -> error
        kbuilder.addBuilderResult(new TypeDeclarationError(typeDescr, error.getMessage()));
    }
}
Also used : TypeDeclarationError(org.drools.compiler.compiler.TypeDeclarationError) TypeFieldDescr(org.drools.compiler.lang.descr.TypeFieldDescr) IOException(java.io.IOException) TypeDeclaration(org.drools.core.rule.TypeDeclaration) GeneratedFact(org.drools.core.factmodel.GeneratedFact) ClassFieldInspector(org.drools.core.util.asm.ClassFieldInspector)

Example 10 with ClassFieldInspector

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

the class TypeDeclarationUtils method isCompatible.

public static boolean isCompatible(Class<?> typeClass, AbstractClassTypeDeclarationDescr typeDescr) {
    try {
        if (typeDescr.getFields().isEmpty()) {
            return true;
        }
        Class<?> sup = typeClass.getSuperclass();
        if (sup == null) {
            return true;
        }
        if (!sup.getName().equals(typeDescr.getSupertTypeFullName())) {
            return false;
        }
        ClassFieldInspector cfi = new ClassFieldInspector(typeClass, false);
        if (cfi.getGetterMethods().size() != typeDescr.getFields().size()) {
            return false;
        }
        for (String fieldName : cfi.getFieldTypes().keySet()) {
            if (!typeDescr.getFields().containsKey(fieldName)) {
                return false;
            }
            String fieldTypeName = typeDescr.getFields().get(fieldName).getPattern().getObjectType();
            Class fieldType = cfi.getFieldTypes().get(fieldName);
            if (!fieldTypeName.equals(fieldType.getName()) || !fieldTypeName.equals(fieldType.getSimpleName())) {
                return false;
            }
        }
    } catch (IOException e) {
        return false;
    }
    return true;
}
Also used : 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