TypeDeclarationDescr typeDescr) {
Map<String, TypeFieldDescr> fieldMap = new LinkedHashMap<String, TypeFieldDescr>();
PackageRegistry registry = this.pkgRegistryMap.get(superTypePackageName);
Package pack;
if (registry != null) {
pack = registry.getPackage();
} else {
// If there is no regisrty the type isn't a DRL-declared type, which is forbidden.
// Avoid NPE JIRA-3041 when trying to access the registry. Avoid subsequent problems.
this.results.add(new TypeDeclarationError(typeDescr, "Cannot extend supertype '" + fullSuper + "' (not a declared type)"));
typeDescr.setType(null, null);
return false;
}
// if a class is declared in DRL, its package can't be null? The default package is replaced by "defaultpkg"
boolean isSuperClassTagged = false;
boolean isSuperClassDeclared = true; //in the same package, or in a previous one
if (pack != null) {
// look for the supertype declaration in available packages
TypeDeclaration superTypeDeclaration = pack.getTypeDeclaration(simpleSuperTypeName);
if (superTypeDeclaration != null) {
ClassDefinition classDef = superTypeDeclaration.getTypeClassDef();
// inherit fields
for (FactField fld : classDef.getFields()) {
TypeFieldDescr inheritedFlDescr = buildInheritedFieldDescrFromDefinition(fld, typeDescr);
fieldMap.put(inheritedFlDescr.getFieldName(),
inheritedFlDescr);
}
// new classes are already distinguished from tagged external classes
isSuperClassTagged = !superTypeDeclaration.isNovel();
} else {
isSuperClassDeclared = false;
}
} else {
isSuperClassDeclared = false;
}
// look for the class externally
if (!isSuperClassDeclared || isSuperClassTagged) {
try {
Class superKlass = registry.getTypeResolver().resolveType(fullSuper);
ClassFieldInspector inspector = new ClassFieldInspector(superKlass);
for (String name : inspector.getGetterMethods().keySet()) {
// classFieldAccessor requires both getter and setter
if (inspector.getSetterMethods().containsKey(name)) {
if (!inspector.isNonGetter(name) && !"class".equals(name)) {
TypeFieldDescr inheritedFlDescr = new TypeFieldDescr(
name,
new PatternDescr(
inspector.getFieldTypes().get(name).getName()));
inheritedFlDescr.setInherited(!Modifier.isAbstract(inspector.getGetterMethods().get(name).getModifiers()));
if (!fieldMap.containsKey(inheritedFlDescr.getFieldName()))
fieldMap.put(inheritedFlDescr.getFieldName(),
inheritedFlDescr);
}
}
}
} catch (ClassNotFoundException cnfe) {
throw new RuntimeDroolsException("Unable to resolve Type Declaration superclass '" + fullSuper + "'");
} catch (IOException e) {
}
}
// finally, locally declared fields are merged. The map swap ensures that super-fields are added in order, before the subclass' ones
// notice that it is not possible to override a field changing its type
for (String fieldName : typeDescr.getFields().keySet()) {
if (fieldMap.containsKey(fieldName)) {
String type1 = fieldMap.get(fieldName).getPattern().getObjectType();
String type2 = typeDescr.getFields().get(fieldName).getPattern().getObjectType();
if (type2.lastIndexOf(".") < 0) {
try {
TypeResolver typeResolver = pkgRegistryMap.get(pack.getName()).getTypeResolver();
type1 = typeResolver.resolveType(type1).getName();
type2 = typeResolver.resolveType(type2).getName();
// now that we are at it... this will be needed later anyway
fieldMap.get(fieldName).getPattern().setObjectType(type1);
typeDescr.getFields().get(fieldName).getPattern().setObjectType(type2);