use of org.drools.drl.ast.descr.TypeFieldDescr in project drools by kiegroup.
the class ClassHierarchyManager method buildInheritedFieldDescrFromDefinition.
protected TypeFieldDescr buildInheritedFieldDescrFromDefinition(org.kie.api.definition.type.FactField fld, TypeDeclarationDescr typeDescr) {
TypeFieldDescr inheritedFldDescr = new TypeFieldDescr();
inheritedFldDescr.setFieldName(fld.getName());
inheritedFldDescr.setResource(typeDescr.getResource());
PatternDescr fldType = new PatternDescr();
fldType.setObjectType(((FieldDefinition) fld).getTypeName());
// also sets resource for PatternDescr fldType
inheritedFldDescr.setPattern(fldType);
if (fld.isKey()) {
AnnotationDescr keyAnnotation = new AnnotationDescr(Key.class.getCanonicalName());
keyAnnotation.setFullyQualifiedName(Key.class.getCanonicalName());
keyAnnotation.setResource(typeDescr.getResource());
inheritedFldDescr.addAnnotation(keyAnnotation);
}
inheritedFldDescr.setIndex(((FieldDefinition) fld).getDeclIndex());
inheritedFldDescr.setInherited(true);
String initExprOverride = ((FieldDefinition) fld).getInitExpr();
int overrideCount = 0;
// only @aliasing local fields may override defaults.
for (TypeFieldDescr localField : typeDescr.getFields().values()) {
Alias alias = getTypedAnnotation(localField, Alias.class);
if (alias != null && fld.getName().equals(alias.value().replaceAll("\"", "")) && localField.getInitExpr() != null) {
overrideCount++;
initExprOverride = localField.getInitExpr();
}
}
if (overrideCount > 1) {
// however, only one is allowed
initExprOverride = null;
}
inheritedFldDescr.setInitExpr(initExprOverride);
return inheritedFldDescr;
}
use of org.drools.drl.ast.descr.TypeFieldDescr in project drools by kiegroup.
the class ClassDefinitionFactory method wireFields.
protected boolean wireFields(AbstractClassTypeDeclarationDescr typeDescr, ClassDefinition def, PackageRegistry pkgRegistry, List<TypeDefinition> unresolvedTypeDefinitions) {
// Fields are SORTED in the process
if (!typeDescr.getFields().isEmpty()) {
if (unresolvedTypeDefinitions != null && !unresolvedTypeDefinitions.isEmpty()) {
for (TypeFieldDescr fld : typeDescr.getFields().values()) {
for (TypeDefinition typeDef : unresolvedTypeDefinitions) {
if (fld.getPattern().getObjectType().equals(typeDef.getTypeClassName())) {
return false;
}
}
}
}
List<FieldDefinition> fieldDefs = sortFields(typeDescr.getFields(), pkgRegistry.getTypeResolver(), kbuilder);
int i = 0;
for (FieldDefinition fieldDef : fieldDefs) {
fieldDef.setIndex(i++);
def.addField(fieldDef);
}
}
return true;
}
use of org.drools.drl.ast.descr.TypeFieldDescr in project drools by kiegroup.
the class DescrTypeDefinition method typeFieldsSortedByPosition.
private List<TypeFieldDescr> typeFieldsSortedByPosition(List<FieldDefinition> inheritedFields) {
Collection<TypeFieldDescr> typeFields = typeDeclarationDescr.getFields().values().stream().filter(f -> inheritedFields.stream().map(FieldDefinition::getFieldName).noneMatch(name -> name.equals(f.getFieldName()))).collect(Collectors.toList());
TypeFieldDescr[] sortedTypes = new TypeFieldDescr[typeFields.size()];
List<TypeFieldDescr> nonPositionalFields = new ArrayList<>();
for (TypeFieldDescr descr : typeFields) {
AnnotationDescr ann = descr.getAnnotation("Position");
if (ann == null) {
nonPositionalFields.add(descr);
} else {
int pos = Integer.parseInt(ann.getValue().toString());
if (pos >= sortedTypes.length) {
errors.add(new TypeDeclarationError(typeDeclarationDescr, "Out of range position " + pos + " for field '" + descr.getFieldName() + "' on class " + typeDeclarationDescr.getTypeName()));
} else if (sortedTypes[pos] != null) {
errors.add(new TypeDeclarationError(typeDeclarationDescr, "Duplicated position " + pos + " for field '" + descr.getFieldName() + "' on class " + typeDeclarationDescr.getTypeName()));
} else {
sortedTypes[pos] = descr;
}
}
}
if (!errors.isEmpty()) {
return Collections.emptyList();
}
int counter = 0;
for (TypeFieldDescr descr : nonPositionalFields) {
for (; sortedTypes[counter] != null; counter++) ;
sortedTypes[counter++] = descr;
}
return Arrays.asList(sortedTypes);
}
use of org.drools.drl.ast.descr.TypeFieldDescr in project drools by kiegroup.
the class ClassDefinitionFactory method sortFields.
private static List<FieldDefinition> sortFields(Map<String, TypeFieldDescr> fields, TypeResolver typeResolver, KnowledgeBuilderImpl kbuilder) {
List<FieldDefinition> fieldDefs = new ArrayList<>(fields.size());
int maxDeclaredPos = 0;
BitSet occupiedPositions = new BitSet(fields.size());
for (TypeFieldDescr field : fields.values()) {
GenericTypeDefinition genericType = field.getPattern().getGenericType().map(type -> TypeDeclarationUtils.toBuildableType(type, kbuilder != null ? kbuilder.getRootClassLoader() : null));
FieldDefinition fieldDef = new FieldDefinition(field.getFieldName(), genericType);
fieldDefs.add(fieldDef);
if (field.hasOverride()) {
fieldDef.setOverriding(field.getOverriding().getPattern().getObjectType());
}
fieldDef.setInherited(field.isInherited());
fieldDef.setRecursive(field.isRecursive());
fieldDef.setInitExpr(TypeDeclarationUtils.rewriteInitExprWithImports(field.getInitExpr(), typeResolver));
if (field.getIndex() >= 0) {
int pos = field.getIndex();
occupiedPositions.set(pos);
maxDeclaredPos = Math.max(maxDeclaredPos, pos);
fieldDef.addMetaData("position", pos);
} else {
Position position = getTypedAnnotation(field, Position.class);
if (position != null) {
int pos = position.value();
field.setIndex(pos);
occupiedPositions.set(pos);
maxDeclaredPos = Math.max(maxDeclaredPos, pos);
fieldDef.addMetaData("position", pos);
}
}
if (field.hasAnnotation(Key.class)) {
fieldDef.setKey(true);
fieldDef.addMetaData("key", null);
}
for (AnnotationDescr annotationDescr : field.getAnnotations()) {
if (annotationDescr.getFullyQualifiedName() == null) {
if (annotationDescr.isStrict()) {
kbuilder.addBuilderResult(new TypeDeclarationError(field, "Unknown annotation @" + annotationDescr.getName() + " on field " + field.getFieldName()));
} else {
// Annotation is custom metadata
fieldDef.addMetaData(annotationDescr.getName(), annotationDescr.getSingleValue());
continue;
}
}
Annotation annotation = AnnotationFactory.buildAnnotation(typeResolver, annotationDescr);
if (annotation != null) {
try {
AnnotationDefinition annotationDefinition = AnnotationDefinition.build(annotation.annotationType(), field.getAnnotation(annotationDescr.getFullyQualifiedName()).getValueMap(), typeResolver);
fieldDef.addAnnotation(annotationDefinition);
} catch (Exception e) {
kbuilder.addBuilderResult(new TypeDeclarationError(field, "Annotated field " + field.getFieldName() + " - undefined property in @annotation " + annotationDescr.getName() + ": " + e.getMessage() + ";"));
}
} else {
if (annotationDescr.isStrict()) {
kbuilder.addBuilderResult(new TypeDeclarationError(field, "Unknown annotation @" + annotationDescr.getName() + " on field " + field.getFieldName()));
}
}
}
fieldDef.setDeclIndex(field.getIndex());
}
int curr = 0;
for (FieldDefinition fieldDef : fieldDefs) {
if (fieldDef.getDeclIndex() < 0) {
int freePos = occupiedPositions.nextClearBit(0);
if (freePos < maxDeclaredPos) {
occupiedPositions.set(freePos);
} else {
freePos = maxDeclaredPos + 1;
}
fieldDef.setPriority(freePos * 256 + curr++);
} else {
fieldDef.setPriority(fieldDef.getDeclIndex() * 256 + curr++);
}
}
Collections.sort(fieldDefs);
return fieldDefs;
}
use of org.drools.drl.ast.descr.TypeFieldDescr in project drools by kiegroup.
the class ClassHierarchyManager method sortByHierarchy.
/**
* Utility method to sort declared beans. Linearizes the hierarchy,
* i.e.generates a sequence of declaration such that, if Sub is subclass of
* Sup, then the index of Sub will be > than the index of Sup in the
* resulting collection. This ensures that superclasses are processed before
* their subclasses
*/
protected List<AbstractClassTypeDeclarationDescr> sortByHierarchy(Collection<AbstractClassTypeDeclarationDescr> unsortedDescrs, KnowledgeBuilderImpl kbuilder) {
taxonomy = new HashMap<>();
Map<QualifiedName, AbstractClassTypeDeclarationDescr> cache = new HashMap<>();
for (AbstractClassTypeDeclarationDescr tdescr : unsortedDescrs) {
cache.put(tdescr.getType(), tdescr);
}
for (AbstractClassTypeDeclarationDescr tdescr : unsortedDescrs) {
QualifiedName name = tdescr.getType();
Collection<QualifiedName> supers = taxonomy.get(name);
if (supers == null) {
supers = new ArrayList<>();
taxonomy.put(name, supers);
} else {
kbuilder.addBuilderResult(new TypeDeclarationError(tdescr, "Found duplicate declaration for type " + tdescr.getType()));
}
boolean circular = false;
for (QualifiedName sup : tdescr.getSuperTypes()) {
if (!Object.class.getName().equals(name.getFullName())) {
if (!hasCircularDependency(tdescr.getType(), sup, taxonomy)) {
if (cache.containsKey(sup)) {
supers.add(sup);
}
} else {
circular = true;
kbuilder.addBuilderResult(new TypeDeclarationError(tdescr, "Found circular dependency for type " + tdescr.getTypeName()));
break;
}
}
}
if (circular) {
tdescr.getSuperTypes().clear();
}
}
for (AbstractClassTypeDeclarationDescr tdescr : unsortedDescrs) {
for (TypeFieldDescr field : tdescr.getFields().values()) {
QualifiedName name = tdescr.getType();
QualifiedName typeName = new QualifiedName(field.getPattern().getGenericType().getRawType());
if (!hasCircularDependency(name, typeName, taxonomy)) {
if (cache.containsKey(typeName)) {
taxonomy.get(name).add(typeName);
}
} else {
field.setRecursive(true);
}
}
}
List<QualifiedName> sorted = new HierarchySorter<QualifiedName>().sort(taxonomy);
ArrayList list = new ArrayList(sorted.size());
for (QualifiedName name : sorted) {
list.add(cache.get(name));
}
return list;
}
Aggregations