if ( newPkg.hasTraitRegistry() ) {
getTraitRegistry().merge( newPkg.getTraitRegistry() );
}
InternalKnowledgePackage pkg = this.pkgs.get( newPkg.getName() );
if ( pkg == null ) {
pkg = new KnowledgePackageImpl( newPkg.getName() );
// @TODO we really should have a single root cache
pkg.setClassFieldAccessorCache( this.classFieldAccessorCache );
pkgs.put( pkg.getName(),
pkg );
}
// first merge anything related to classloader re-wiring
pkg.getDialectRuntimeRegistry().merge( newPkg.getDialectRuntimeRegistry(),
this.rootClassLoader,
true );
}
List<TypeDeclaration> allTypeDeclarations = new ArrayList<TypeDeclaration>();
// Add all Type Declarations, this has to be done first incase packages cross reference each other during build process.
for ( InternalKnowledgePackage newPkg : clonedPkgs ) {
// we have to do this before the merging, as it does some classloader resolving
if ( newPkg.getTypeDeclarations() != null ) {
for ( TypeDeclaration newDecl : newPkg.getTypeDeclarations().values() ) {
allTypeDeclarations.add( newDecl );
}
}
}
Collections.sort( allTypeDeclarations );
String lastType = null;
try {
// add type declarations according to the global order
for ( TypeDeclaration newDecl : allTypeDeclarations ) {
lastType = newDecl.getTypeClassName();
InternalKnowledgePackage newPkg = null;
for ( InternalKnowledgePackage kpkg : clonedPkgs ) {
if ( kpkg.getTypeDeclarations().containsKey( newDecl.getTypeName() ) ) {
newPkg = kpkg;
break;
}
}
processTypeDeclaration( newDecl, newPkg );
}
} catch (ClassNotFoundException e) {
throw new RuntimeException( "unable to resolve Type Declaration class '" + lastType + "'", e );
}
for ( InternalKnowledgePackage newPkg : clonedPkgs ) {
// Add functions
try {
JavaDialectRuntimeData runtime = ((JavaDialectRuntimeData) newPkg.getDialectRuntimeRegistry().getDialectData( "java" ));
for ( Function function : newPkg.getFunctions().values() ) {
String functionClassName = function.getClassName();
byte [] def = runtime.getStore().get(convertClassToResourcePath(functionClassName));
registerAndLoadTypeDefinition( functionClassName, def );
}
} catch (ClassNotFoundException e) {
throw new RuntimeException( "unable to resolve Type Declaration class '" + lastType + "'", e );
}
}
// now iterate again, this time onBeforeExecute will handle any wiring or cloader re-creating that needs to be done as part of the merge
for (InternalKnowledgePackage newPkg : clonedPkgs) {
InternalKnowledgePackage pkg = this.pkgs.get( newPkg.getName() );
// this needs to go here, as functions will set a java dialect to dirty
if (newPkg.getFunctions() != null) {
for (Map.Entry<String, Function> entry : newPkg.getFunctions().entrySet()) {
pkg.addFunction( entry.getValue() );
}
}
pkg.getDialectRuntimeRegistry().onBeforeExecute();
// with the classloader recreated for all byte[] classes, we should now merge and wire any new accessors
pkg.getClassFieldAccessorStore().merge( newPkg.getClassFieldAccessorStore() );
}
for (InternalKnowledgePackage newPkg : clonedPkgs) {
InternalKnowledgePackage pkg = this.pkgs.get( newPkg.getName() );
// now merge the new package into the existing one
mergePackage( pkg,
newPkg );