use of org.drools.compiler.lang.descr.AbstractClassTypeDeclarationDescr in project drools by kiegroup.
the class TypeDeclarationBuilder method compactDefinitionsAndDeclarations.
private Collection<AbstractClassTypeDeclarationDescr> compactDefinitionsAndDeclarations(Collection<AbstractClassTypeDeclarationDescr> unsortedDescrs, Map<String, AbstractClassTypeDeclarationDescr> unprocesseableDescrs) {
Map<String, AbstractClassTypeDeclarationDescr> compactedUnsorted = new HashMap<String, AbstractClassTypeDeclarationDescr>(unsortedDescrs.size());
for (AbstractClassTypeDeclarationDescr descr : unsortedDescrs) {
if (compactedUnsorted.containsKey(descr.getType().getFullName())) {
AbstractClassTypeDeclarationDescr prev = compactedUnsorted.get(descr.getType().getFullName());
boolean res = mergeTypeDescriptors(prev, descr);
if (!res) {
unprocesseableDescrs.put(prev.getType().getFullName(), prev);
kbuilder.addBuilderResult(new TypeDeclarationError(prev, "Found duplicate declaration for type " + prev.getType().getFullName() + ", unable to reconcile "));
}
} else {
compactedUnsorted.put(descr.getType().getFullName(), descr);
}
}
return compactedUnsorted.values();
}
use of org.drools.compiler.lang.descr.AbstractClassTypeDeclarationDescr in project drools by kiegroup.
the class TypeDeclarationBuilder method updateTraitInformation.
protected void updateTraitInformation(AbstractClassTypeDeclarationDescr typeDescr, TypeDeclaration type, ClassDefinition def, PackageRegistry pkgRegistry) {
if (typeDescr.hasAnnotation(Traitable.class) || (!type.getKind().equals(TypeDeclaration.Kind.TRAIT) && kbuilder.getPackageRegistry().containsKey(def.getSuperClass()) && kbuilder.getPackageRegistry(def.getSuperClass()).getTraitRegistry().getTraitables().containsKey(def.getSuperClass()))) {
// traitable
if (type.isNovel()) {
try {
PackageRegistry reg = kbuilder.getPackageRegistry(typeDescr.getNamespace());
String availableName = typeDescr.getType().getFullName();
Class<?> resolvedType = reg.getTypeResolver().resolveType(availableName);
updateTraitDefinition(type, resolvedType, false);
} catch (ClassNotFoundException cnfe) {
// we already know the class exists
}
}
pkgRegistry.getTraitRegistry().addTraitable(def);
} else if (type.getKind().equals(TypeDeclaration.Kind.TRAIT) || typeDescr.hasAnnotation(Trait.class)) {
// trait
if (!type.isNovel()) {
try {
PackageRegistry reg = kbuilder.getPackageRegistry(typeDescr.getNamespace());
String availableName = typeDescr.getType().getFullName();
Class<?> resolvedType = reg.getTypeResolver().resolveType(availableName);
if (!Thing.class.isAssignableFrom(resolvedType)) {
if (!resolvedType.isInterface()) {
kbuilder.addBuilderResult(new TypeDeclarationError(typeDescr, "Unable to redeclare concrete class " + resolvedType.getName() + " as a trait."));
return;
}
updateTraitDefinition(type, resolvedType, false);
String target = typeDescr.getTypeName() + TraitFactory.SUFFIX;
TypeDeclarationDescr tempDescr = new TypeDeclarationDescr();
tempDescr.setNamespace(typeDescr.getNamespace());
tempDescr.setFields(typeDescr.getFields());
tempDescr.setType(target, typeDescr.getNamespace());
tempDescr.setTrait(true);
tempDescr.addSuperType(typeDescr.getType());
tempDescr.setResource(type.getResource());
TypeDeclaration tempDeclr = new TypeDeclaration(target);
tempDeclr.setKind(TypeDeclaration.Kind.TRAIT);
tempDeclr.setTypesafe(type.isTypesafe());
tempDeclr.setNovel(true);
tempDeclr.setTypeClassName(tempDescr.getType().getFullName());
tempDeclr.setResource(type.getResource());
ClassDefinition tempDef = new ClassDefinition(target);
tempDef.setClassName(tempDescr.getType().getFullName());
tempDef.setTraitable(false);
for (FieldDefinition fld : def.getFieldsDefinitions()) {
tempDef.addField(fld);
}
tempDef.setInterfaces(def.getInterfaces());
tempDef.setSuperClass(def.getClassName());
tempDef.setDefinedClass(resolvedType);
tempDef.setAbstrakt(true);
tempDeclr.setTypeClassDef(tempDef);
declaredClassBuilder.generateBeanFromDefinition(tempDescr, tempDeclr, pkgRegistry, tempDef);
try {
Class<?> clazz = pkgRegistry.getTypeResolver().resolveType(tempDescr.getType().getFullName());
tempDeclr.setTypeClass(clazz);
pkgRegistry.getTraitRegistry().addTrait(tempDef.getClassName().replace(TraitFactory.SUFFIX, ""), tempDef);
} catch (ClassNotFoundException cnfe) {
kbuilder.addBuilderResult(new TypeDeclarationError(typeDescr, "Internal Trait extension Class '" + target + "' could not be generated correctly'"));
} finally {
pkgRegistry.getPackage().addTypeDeclaration(tempDeclr);
}
} else {
updateTraitDefinition(type, resolvedType, true);
pkgRegistry.getTraitRegistry().addTrait(def);
}
} catch (ClassNotFoundException cnfe) {
// we already know the class exists
}
} else {
if (def.getClassName().endsWith(TraitFactory.SUFFIX)) {
pkgRegistry.getTraitRegistry().addTrait(def.getClassName().replace(TraitFactory.SUFFIX, ""), def);
} else {
pkgRegistry.getTraitRegistry().addTrait(def);
}
}
}
}
use of org.drools.compiler.lang.descr.AbstractClassTypeDeclarationDescr in project drools by kiegroup.
the class ClassHierarchyManager method inheritFields.
public void inheritFields(PackageRegistry pkgRegistry, AbstractClassTypeDeclarationDescr typeDescr, Collection<AbstractClassTypeDeclarationDescr> sortedTypeDescriptors, List<TypeDefinition> unresolvedTypes, Map<String, AbstractClassTypeDeclarationDescr> unprocessableDescrs) {
TypeDeclarationDescr tDescr = (TypeDeclarationDescr) typeDescr;
boolean isNovel = TypeDeclarationUtils.isNovelClass(typeDescr, pkgRegistry);
boolean inferFields = !isNovel && typeDescr.getFields().isEmpty();
for (QualifiedName qname : tDescr.getSuperTypes()) {
// descriptor needs fields inherited from superclass
mergeInheritedFields(tDescr, unresolvedTypes, unprocessableDescrs, pkgRegistry.getTypeResolver());
}
if (inferFields) {
// not novel, but only an empty declaration was provided.
// after inheriting the fields from supertypes, now we fill in the locally declared fields
Class existingClass = TypeDeclarationUtils.getExistingDeclarationClass(typeDescr, pkgRegistry);
buildDescrsFromFields(existingClass, tDescr, pkgRegistry, tDescr.getFields());
}
}
use of org.drools.compiler.lang.descr.AbstractClassTypeDeclarationDescr 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<QualifiedName, Collection<QualifiedName>>();
Map<QualifiedName, AbstractClassTypeDeclarationDescr> cache = new HashMap<QualifiedName, AbstractClassTypeDeclarationDescr>();
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<QualifiedName>();
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().getObjectType());
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;
}
use of org.drools.compiler.lang.descr.AbstractClassTypeDeclarationDescr in project drools by kiegroup.
the class KnowledgeBuilderImpl method mergePackage.
void mergePackage(PackageRegistry pkgRegistry, PackageDescr packageDescr) {
for (final ImportDescr importDescr : packageDescr.getImports()) {
pkgRegistry.addImport(importDescr);
}
normalizeTypeDeclarationAnnotations(packageDescr, pkgRegistry.getTypeResolver());
processAccumulateFunctions(pkgRegistry, packageDescr);
processEntryPointDeclarations(pkgRegistry, packageDescr);
Map<String, AbstractClassTypeDeclarationDescr> unprocesseableDescrs = new HashMap<String, AbstractClassTypeDeclarationDescr>();
List<TypeDefinition> unresolvedTypes = new ArrayList<TypeDefinition>();
List<AbstractClassTypeDeclarationDescr> unsortedDescrs = new ArrayList<AbstractClassTypeDeclarationDescr>();
unsortedDescrs.addAll(packageDescr.getTypeDeclarations());
unsortedDescrs.addAll(packageDescr.getEnumDeclarations());
typeBuilder.processTypeDeclarations(packageDescr, pkgRegistry, unsortedDescrs, unresolvedTypes, unprocesseableDescrs);
for (AbstractClassTypeDeclarationDescr descr : unprocesseableDescrs.values()) {
this.addBuilderResult(new TypeDeclarationError(descr, "Unable to process type " + descr.getTypeName()));
}
processOtherDeclarations(pkgRegistry, packageDescr);
normalizeRuleAnnotations(packageDescr, pkgRegistry.getTypeResolver());
}
Aggregations