[jboss-svn-commits] JBL Code SVN: r25875 - in labs/jbossrules/trunk/drools-core/src/main/java/org/drools: reteoo and 1 other directory.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sun Mar 29 16:59:37 EDT 2009
Author: stampy88
Date: 2009-03-29 16:59:36 -0400 (Sun, 29 Mar 2009)
New Revision: 25875
Modified:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java
Log:
Fixed synchronization problem with statefull sessions per JBRULES-2029. Also tightened up access modifiers from protected to private
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java 2009-03-29 20:10:29 UTC (rev 25874)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java 2009-03-29 20:59:36 UTC (rev 25875)
@@ -63,61 +63,60 @@
*
* @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
* @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
- *
* @version $Id: RuleBaseImpl.java,v 1.5 2005/08/14 22:44:12 mproctor Exp $
*/
-abstract public class AbstractRuleBase
- implements
- InternalRuleBase,
- Externalizable {
+abstract public class AbstractRuleBase implements InternalRuleBase, Externalizable {
// ------------------------------------------------------------
// Instance members
// ------------------------------------------------------------
- protected String id;
+ private String id;
- protected int workingMemoryCounter;
+ private int workingMemoryCounter;
- protected RuleBaseConfiguration config;
+ private RuleBaseConfiguration config;
- protected Map<String, Package> pkgs;
+ protected Map<String, Package> pkgs;
- protected Map processes;
+ private Map processes;
- protected Map agendaGroupRuleTotals;
+ private Map agendaGroupRuleTotals;
- protected transient CompositeClassLoader rootClassLoader;
+ private transient CompositeClassLoader rootClassLoader;
- /** The fact handle factory. */
- protected FactHandleFactory factHandleFactory;
+ /**
+ * The fact handle factory.
+ */
+ private FactHandleFactory factHandleFactory;
- protected transient Map<String, Class<?>> globals;
+ private transient Map<String, Class<?>> globals;
- private ReloadPackageCompilationData reloadPackageCompilationData = null;
+ private ReloadPackageCompilationData reloadPackageCompilationData = null;
- private RuleBaseEventSupport eventSupport = new RuleBaseEventSupport( this );
+ private RuleBaseEventSupport eventSupport = new RuleBaseEventSupport(this);
- /**
- * WeakHashMap to keep references of WorkingMemories but allow them to be
- * garbage collected
- */
- protected transient ObjectHashSet statefulSessions;
+ private transient ObjectHashSet statefulSessions;
// wms used for lock list during dynamic updates
- InternalWorkingMemory[] wms;
+ private InternalWorkingMemory[] wms;
// indexed used to track invariant lock
- int lastAquiredLock;
+ private int lastAquiredLock;
// lock for entire rulebase, used for dynamic updates
- protected ReentrantLock lock = new ReentrantLock();
+ private final ReentrantLock lock = new ReentrantLock();
- private int additionsSinceLock;
- private int removalsSinceLock;
+ /**
+ * This lock is used when adding to, or reading the <field>statefulSessions</field>
+ */
+ private final ReentrantLock statefuleSessionLock = new ReentrantLock();
- private transient Map<Class< ? >, TypeDeclaration> classTypeDeclaration;
+ private int additionsSinceLock;
+ private int removalsSinceLock;
- private List<RuleBasePartitionId> partitionIDs;
+ private transient Map<Class<?>, TypeDeclaration> classTypeDeclaration;
+ private List<RuleBasePartitionId> partitionIDs;
+
private ClassFieldAccessorCache classFieldAccessorCache;
/**
@@ -135,13 +134,12 @@
/**
* Construct.
*
- * @param id
- * The rete network.
+ * @param id The rete network.
*/
public AbstractRuleBase(final String id,
final RuleBaseConfiguration config,
final FactHandleFactory factHandleFactory) {
- if ( id != null ) {
+ if (id != null) {
this.id = id;
} else {
this.id = "default";
@@ -150,20 +148,20 @@
this.config.makeImmutable();
this.factHandleFactory = factHandleFactory;
- if ( this.config.isSequential() ) {
+ if (this.config.isSequential()) {
this.agendaGroupRuleTotals = new HashMap();
}
- this.rootClassLoader = new CompositeClassLoader( this.config.getClassLoader() );
+ this.rootClassLoader = new CompositeClassLoader(this.config.getClassLoader());
this.pkgs = new HashMap<String, Package>();
this.processes = new HashMap();
this.globals = new HashMap<String, Class<?>>();
this.statefulSessions = new ObjectHashSet();
- this.classTypeDeclaration = new HashMap<Class< ? >, TypeDeclaration>();
+ this.classTypeDeclaration = new HashMap<Class<?>, TypeDeclaration>();
this.partitionIDs = new ArrayList<RuleBasePartitionId>();
-
- this.classFieldAccessorCache = new ClassFieldAccessorCache( this.rootClassLoader );
+
+ this.classFieldAccessorCache = new ClassFieldAccessorCache(this.rootClassLoader);
}
// ------------------------------------------------------------
@@ -173,46 +171,45 @@
/**
* Handles the write serialization of the Package. Patterns in Rules may reference generated data which cannot be serialized by default methods.
* The Package uses PackageCompilationData to hold a reference to the generated bytecode. The generated bytecode must be restored before any Rules.
- *
*/
public void writeExternal(final ObjectOutput out) throws IOException {
ObjectOutput droolsStream;
boolean isDrools = out instanceof DroolsObjectOutputStream;
ByteArrayOutputStream bytes;
- if ( isDrools ) {
+ if (isDrools) {
droolsStream = out;
bytes = null;
} else {
bytes = new ByteArrayOutputStream();
- droolsStream = new DroolsObjectOutputStream( bytes );
+ droolsStream = new DroolsObjectOutputStream(bytes);
}
- droolsStream.writeObject( this.config );
- droolsStream.writeObject( this.pkgs );
+ droolsStream.writeObject(this.config);
+ droolsStream.writeObject(this.pkgs);
// Rules must be restored by an ObjectInputStream that can resolve using a given ClassLoader to handle seaprately by storing as
// a byte[]
- droolsStream.writeObject( this.id );
- droolsStream.writeInt( this.workingMemoryCounter );
- droolsStream.writeObject( this.processes );
- droolsStream.writeObject( this.agendaGroupRuleTotals );
- droolsStream.writeUTF( this.factHandleFactory.getClass().getName() );
- droolsStream.writeObject( buildGlobalMapForSerialization() );
- droolsStream.writeObject( this.partitionIDs );
+ droolsStream.writeObject(this.id);
+ droolsStream.writeInt(this.workingMemoryCounter);
+ droolsStream.writeObject(this.processes);
+ droolsStream.writeObject(this.agendaGroupRuleTotals);
+ droolsStream.writeUTF(this.factHandleFactory.getClass().getName());
+ droolsStream.writeObject(buildGlobalMapForSerialization());
+ droolsStream.writeObject(this.partitionIDs);
- this.eventSupport.removeEventListener( RuleBaseEventListener.class );
- droolsStream.writeObject( this.eventSupport );
- if ( !isDrools ) {
+ this.eventSupport.removeEventListener(RuleBaseEventListener.class);
+ droolsStream.writeObject(this.eventSupport);
+ if (!isDrools) {
bytes.close();
- out.writeObject( bytes.toByteArray() );
+ out.writeObject(bytes.toByteArray());
}
}
private Map<String, String> buildGlobalMapForSerialization() {
Map<String, String> gl = new HashMap<String, String>();
- for( Map.Entry<String, Class<?>> entry : this.globals.entrySet() ) {
- gl.put( entry.getKey(), entry.getValue().getName() );
+ for (Map.Entry<String, Class<?>> entry : this.globals.entrySet()) {
+ gl.put(entry.getKey(), entry.getValue().getName());
}
return gl;
}
@@ -221,37 +218,36 @@
* Handles the read serialization of the Package. Patterns in Rules may reference generated data which cannot be serialized by default methods.
* The Package uses PackageCompilationData to hold a reference to the generated bytecode; which must be restored before any Rules.
* A custom ObjectInputStream, able to resolve classes against the bytecode in the PackageCompilationData, is used to restore the Rules.
- *
*/
public void readExternal(final ObjectInput in) throws IOException,
- ClassNotFoundException {
+ ClassNotFoundException {
// PackageCompilationData must be restored before Rules as it has the ClassLoader needed to resolve the generated code references in Rules
- DroolsObjectInput droolsStream = null;
+ DroolsObjectInput droolsStream;
boolean isDrools = in instanceof DroolsObjectInput;
- if ( isDrools ) {
+ if (isDrools) {
droolsStream = (DroolsObjectInput) in;
} else {
- droolsStream = new DroolsObjectInputStream( (ObjectInputStream) in );
+ droolsStream = new DroolsObjectInputStream((ObjectInputStream) in);
}
- this.rootClassLoader = new CompositeClassLoader( droolsStream.getParentClassLoader() );
- droolsStream.setClassLoader( this.rootClassLoader );
- droolsStream.setRuleBase( this );
-
- this.classFieldAccessorCache = new ClassFieldAccessorCache( this.rootClassLoader );
-
+ this.rootClassLoader = new CompositeClassLoader(droolsStream.getParentClassLoader());
+ droolsStream.setClassLoader(this.rootClassLoader);
+ droolsStream.setRuleBase(this);
+
+ this.classFieldAccessorCache = new ClassFieldAccessorCache(this.rootClassLoader);
+
this.config = (RuleBaseConfiguration) droolsStream.readObject();
- this.config.setClassLoader( droolsStream.getParentClassLoader() );
-
+ this.config.setClassLoader(droolsStream.getParentClassLoader());
+
this.pkgs = (Map<String, Package>) droolsStream.readObject();
- for ( final Object object : this.pkgs.values() ) {
- ((Package) object).getDialectRuntimeRegistry().onAdd( this.rootClassLoader );
+ for (final Object object : this.pkgs.values()) {
+ ((Package) object).getDialectRuntimeRegistry().onAdd(this.rootClassLoader);
}
-
+
// PackageCompilationData must be restored before Rules as it has the ClassLoader needed to resolve the generated code references in Rules
this.id = (String) droolsStream.readObject();
this.workingMemoryCounter = droolsStream.readInt();
@@ -260,64 +256,64 @@
this.agendaGroupRuleTotals = (Map) droolsStream.readObject();
Class cls = null;
try {
- cls = droolsStream.getParentClassLoader().loadClass( droolsStream.readUTF() );
+ cls = droolsStream.getParentClassLoader().loadClass(droolsStream.readUTF());
this.factHandleFactory = (FactHandleFactory) cls.newInstance();
- } catch ( InstantiationException e ) {
- DroolsObjectInputStream.newInvalidClassException( cls,
- e );
- } catch ( IllegalAccessException e ) {
- DroolsObjectInputStream.newInvalidClassException( cls,
- e );
- }
-
- for ( final Object object : this.pkgs.values() ) {
- ((Package) object).getDialectRuntimeRegistry().onBeforeExecute( );
- ((Package) object).getClassFieldAccessorStore().setClassFieldAccessorCache( this.classFieldAccessorCache );
+ } catch (InstantiationException e) {
+ DroolsObjectInputStream.newInvalidClassException(cls,
+ e);
+ } catch (IllegalAccessException e) {
+ DroolsObjectInputStream.newInvalidClassException(cls,
+ e);
+ }
+
+ for (final Object object : this.pkgs.values()) {
+ ((Package) object).getDialectRuntimeRegistry().onBeforeExecute();
+ ((Package) object).getClassFieldAccessorStore().setClassFieldAccessorCache(this.classFieldAccessorCache);
((Package) object).getClassFieldAccessorStore().wire();
}
-
- this.populateTypeDeclarationMaps();
-
+
+ this.populateTypeDeclarationMaps();
+
// read globals
Map<String, String> globs = (Map<String, String>) droolsStream.readObject();
- populateGlobalsMap( globs );
-
+ populateGlobalsMap(globs);
+
this.partitionIDs = (List<RuleBasePartitionId>) droolsStream.readObject();
-
+
this.eventSupport = (RuleBaseEventSupport) droolsStream.readObject();
- this.eventSupport.setRuleBase( this );
+ this.eventSupport.setRuleBase(this);
this.statefulSessions = new ObjectHashSet();
- if ( !isDrools ) {
+ if (!isDrools) {
droolsStream.close();
- }
+ }
}
/**
* globals class types must be re-wired after serialization
- *
+ *
* @param globs
* @throws ClassNotFoundException
*/
private void populateGlobalsMap(Map<String, String> globs) throws ClassNotFoundException {
this.globals = new HashMap<String, Class<?>>();
- for( Map.Entry<String, String> entry : globs.entrySet() ) {
- this.globals.put( entry.getKey(), this.rootClassLoader.loadClass( entry.getValue() ) );
+ for (Map.Entry<String, String> entry : globs.entrySet()) {
+ this.globals.put(entry.getKey(), this.rootClassLoader.loadClass(entry.getValue()));
}
}
/**
* type classes must be re-wired after serialization
- *
+ *
* @throws ClassNotFoundException
*/
private void populateTypeDeclarationMaps() throws ClassNotFoundException {
- this.classTypeDeclaration = new HashMap<Class< ? >, TypeDeclaration>();
- for ( Package pkg : this.pkgs.values() ) {
- for ( TypeDeclaration type : pkg.getTypeDeclarations().values() ) {
- type.setTypeClass( this.rootClassLoader.loadClass( type.getTypeClassName() ) );
- this.classTypeDeclaration.put( type.getTypeClass(),
- type );
+ this.classTypeDeclaration = new HashMap<Class<?>, TypeDeclaration>();
+ for (Package pkg : this.pkgs.values()) {
+ for (TypeDeclaration type : pkg.getTypeDeclarations().values()) {
+ type.setTypeClass(this.rootClassLoader.loadClass(type.getTypeClassName()));
+ this.classTypeDeclaration.put(type.getTypeClass(),
+ type);
}
}
}
@@ -329,17 +325,27 @@
return this.id;
}
+ public RuleBaseConfiguration getConfig() {
+ return config;
+ }
+
/**
* @see RuleBase
*/
public StatefulSession newStatefulSession() {
- return newStatefulSession( new SessionConfiguration(), EnvironmentFactory.newEnvironment() );
+ return newStatefulSession(new SessionConfiguration(), EnvironmentFactory.newEnvironment());
}
- public synchronized void disposeStatefulSession(final StatefulSession statefulSession) {
- this.statefulSessions.remove( statefulSession );
- for ( Iterator it = statefulSession.getRuleBaseUpdateListeners().iterator(); it.hasNext(); ) {
- this.removeEventListener( (RuleBaseEventListener) it.next() );
+ public void disposeStatefulSession(final StatefulSession statefulSession) {
+ try {
+ statefuleSessionLock.lock();
+
+ this.statefulSessions.remove(statefulSession);
+ for (Object listener : statefulSession.getRuleBaseUpdateListeners()) {
+ this.removeEventListener((RuleBaseEventListener) listener);
+ }
+ } finally {
+ statefuleSessionLock.unlock();
}
}
@@ -357,16 +363,16 @@
public FactHandleFactory newFactHandleFactory(int id,
long counter) {
- return this.factHandleFactory.newInstance( id,
- counter );
+ return this.factHandleFactory.newInstance(id,
+ counter);
}
public Process[] getProcesses() {
- return (Process[]) this.processes.values().toArray( new Process[this.processes.size()] );
+ return (Process[]) this.processes.values().toArray(new Process[this.processes.size()]);
}
public Package[] getPackages() {
- return (Package[]) this.pkgs.values().toArray( new Package[this.pkgs.size()] );
+ return this.pkgs.values().toArray(new Package[this.pkgs.size()]);
}
public Map<String, Package> getPackagesMap() {
@@ -404,7 +410,7 @@
// Iterate each workingMemory and lock it
// This is so we don't update the Rete network during propagation
- for ( this.lastAquiredLock = 0; this.lastAquiredLock < this.wms.length; this.lastAquiredLock++ ) {
+ for (this.lastAquiredLock = 0; this.lastAquiredLock < this.wms.length; this.lastAquiredLock++) {
this.wms[this.lastAquiredLock].getLock().lock();
}
@@ -417,7 +423,7 @@
// Iterate each workingMemory and attempt to fire any rules, that were activated as a result
// as per the INVARIANT defined above, we need to iterate from lastAquiredLock-1 to 0.
- for ( this.lastAquiredLock--; this.lastAquiredLock > -1; this.lastAquiredLock-- ) {
+ for (this.lastAquiredLock--; this.lastAquiredLock > -1; this.lastAquiredLock--) {
this.wms[this.lastAquiredLock].getLock().unlock();
}
@@ -427,116 +433,115 @@
this.wms = null;
}
-
+
/**
* Add a <code>Package</code> to the network. Iterates through the
* <code>Package</code> adding Each individual <code>Rule</code> to the
* network. Before update network each referenced <code>WorkingMemory</code>
* is locked.
*
- * @param newPkg
- * The package to add.
- */
+ * @param newPkg The package to add.
+ */
public void addPackages(final Collection<Package> newPkgs) {
- synchronized ( this.pkgs ) {
+ synchronized (this.pkgs) {
boolean doUnlock = false;
// only acquire the lock if it hasn't been done explicitely
- if ( !this.lock.isHeldByCurrentThread() && (this.wms == null || this.wms.length == 0) ) {
+ if (!this.lock.isHeldByCurrentThread() && (this.wms == null || this.wms.length == 0)) {
lock();
doUnlock = true;
- }
- try {
+ }
+ try {
// we need to merge all byte[] first, so that the root classloader can resolve classes
- for ( Package newPkg : newPkgs ) {
- newPkg.checkValidity();
+ for (Package newPkg : newPkgs) {
+ newPkg.checkValidity();
this.additionsSinceLock++;
- this.eventSupport.fireBeforePackageAdded( newPkg );
-
- Package pkg = this.pkgs.get( newPkg.getName() );
- if ( pkg == null ) {
- pkg = new Package( newPkg.getName() );
-
+ this.eventSupport.fireBeforePackageAdded(newPkg);
+
+ Package pkg = this.pkgs.get(newPkg.getName());
+ if (pkg == null) {
+ pkg = new Package(newPkg.getName());
+
// @TODO we really should have a single root cache
- pkg.setClassFieldAccessorCache( this.classFieldAccessorCache );
- pkgs.put( pkg.getName(),
- pkg );
- }
-
+ pkg.setClassFieldAccessorCache(this.classFieldAccessorCache);
+ pkgs.put(pkg.getName(),
+ pkg);
+ }
+
// first merge anything related to classloader re-wiring
- pkg.getDialectRuntimeRegistry().merge( newPkg.getDialectRuntimeRegistry(), this.rootClassLoader );
+ pkg.getDialectRuntimeRegistry().merge(newPkg.getDialectRuntimeRegistry(), this.rootClassLoader);
}
// 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 ( Package newPkg : newPkgs ) {
- Package pkg = this.pkgs.get( newPkg.getName() );
+ for (Package newPkg : newPkgs) {
+ Package pkg = this.pkgs.get(newPkg.getName());
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() );
+ pkg.getClassFieldAccessorStore().merge(newPkg.getClassFieldAccessorStore());
}
-
- for ( Package newPkg : newPkgs ) {
- Package pkg = this.pkgs.get( newPkg.getName() );
-
- if ( newPkg.getFunctions() != null ) {
- for ( Map.Entry<String, Function> entry : newPkg.getFunctions().entrySet() ) {
- pkg.addFunction( entry.getValue() );
+
+ for (Package newPkg : newPkgs) {
+ Package pkg = this.pkgs.get(newPkg.getName());
+
+ if (newPkg.getFunctions() != null) {
+ for (Map.Entry<String, Function> entry : newPkg.getFunctions().entrySet()) {
+ pkg.addFunction(entry.getValue());
}
- }
-
+ }
+
// we have to do this before the merging, as it does some classloader resolving
TypeDeclaration lastType = null;
try {
// Add the type declarations to the RuleBase
- if ( newPkg.getTypeDeclarations() != null ) {
+ if (newPkg.getTypeDeclarations() != null) {
// add type declarations
- for ( TypeDeclaration type : newPkg.getTypeDeclarations().values() ) {
+ for (TypeDeclaration type : newPkg.getTypeDeclarations().values()) {
lastType = type;
- type.setTypeClass( this.rootClassLoader.loadClass( type.getTypeClassName() ) );
+ type.setTypeClass(this.rootClassLoader.loadClass(type.getTypeClassName()));
// @TODO should we allow overrides? only if the class is not in use.
- if ( !this.classTypeDeclaration.containsKey( type.getTypeClass() ) ) {
+ if (!this.classTypeDeclaration.containsKey(type.getTypeClass())) {
// add to rulebase list of type declarations
- this.classTypeDeclaration.put( type.getTypeClass(),
- type );
+ this.classTypeDeclaration.put(type.getTypeClass(),
+ type);
}
}
}
- } catch ( ClassNotFoundException e ) {
- throw new RuntimeDroolsException( "unable to resolve Type Declaration class '" + lastType.getTypeName()+"'" );
- }
-
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeDroolsException("unable to resolve Type Declaration class '" + lastType.getTypeName() + "'");
+ }
+
// now merge the new package into the existing one
- mergePackage( pkg,
- newPkg );
-
+ mergePackage(pkg,
+ newPkg);
+
// add the rules to the RuleBase
final Rule[] rules = newPkg.getRules();
- for ( int i = 0; i < rules.length; ++i ) {
- addRule( newPkg,
- rules[i] );
+ for (int i = 0; i < rules.length; ++i) {
+ addRule(newPkg,
+ rules[i]);
}
-
+
// add the flows to the RuleBase
- if ( newPkg.getRuleFlows() != null ) {
+ if (newPkg.getRuleFlows() != null) {
final Map flows = newPkg.getRuleFlows();
- for ( final Object object : newPkg.getRuleFlows().entrySet() ) {
+ for (final Object object : flows.entrySet()) {
final Entry flow = (Entry) object;
- this.processes.put( flow.getKey(),
- flow.getValue() );
+ this.processes.put(flow.getKey(),
+ flow.getValue());
}
}
-
- this.eventSupport.fireAfterPackageAdded( newPkg );
- }
+
+ this.eventSupport.fireAfterPackageAdded(newPkg);
+ }
} finally {
// only unlock if it had been acquired implicitely
- if ( doUnlock ) {
+ if (doUnlock) {
unlock();
}
}
}
-
- }
+ }
+
/**
* Merge a new package with an existing package.
* Most of the work is done by the concrete implementations,
@@ -547,41 +552,41 @@
final Package newPkg) {
// Merge imports
final Map<String, ImportDeclaration> imports = pkg.getImports();
- imports.putAll( newPkg.getImports() );
+ imports.putAll(newPkg.getImports());
String lastType = null;
try {
// merge globals
- if ( newPkg.getGlobals() != null && newPkg.getGlobals() != Collections.EMPTY_MAP ) {
+ if (newPkg.getGlobals() != null && newPkg.getGlobals() != Collections.EMPTY_MAP) {
Map<String, String> globals = pkg.getGlobals();
// Add globals
- for ( final Map.Entry<String, String> entry : newPkg.getGlobals().entrySet() ) {
+ for (final Map.Entry<String, String> entry : newPkg.getGlobals().entrySet()) {
final String identifier = entry.getKey();
final String type = entry.getValue();
lastType = type;
- if ( globals.containsKey( identifier ) && !globals.get( identifier ).equals( type ) ) {
- throw new PackageIntegrationException( pkg );
+ if (globals.containsKey(identifier) && !globals.get(identifier).equals(type)) {
+ throw new PackageIntegrationException(pkg);
} else {
- pkg.addGlobal( identifier,
- this.rootClassLoader.loadClass( type ) );
+ pkg.addGlobal(identifier,
+ this.rootClassLoader.loadClass(type));
// this isn't a package merge, it's adding to the rulebase, but I've put it here for convienience
- this.globals.put( identifier,
- this.rootClassLoader.loadClass( type ) );
+ this.globals.put(identifier,
+ this.rootClassLoader.loadClass(type));
}
}
}
- } catch ( ClassNotFoundException e ) {
- throw new RuntimeDroolsException( "Unable to resolve class '" + lastType + "'" );
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeDroolsException("Unable to resolve class '" + lastType + "'");
}
// merge the type declarations
- if ( newPkg.getTypeDeclarations() != null ) {
+ if (newPkg.getTypeDeclarations() != null) {
// add type declarations
- for ( TypeDeclaration type : newPkg.getTypeDeclarations().values() ) {
+ for (TypeDeclaration type : newPkg.getTypeDeclarations().values()) {
// @TODO should we allow overrides? only if the class is not in use.
- if ( !pkg.getTypeDeclarations().containsKey( type.getTypeName() ) ) {
+ if (!pkg.getTypeDeclarations().containsKey(type.getTypeName())) {
// add to package list of type declarations
- pkg.addTypeDeclaration( type );
+ pkg.addTypeDeclaration(type);
}
}
}
@@ -589,27 +594,27 @@
//Merge rules into the RuleBase package
//as this is needed for individual rule removal later on
final Rule[] newRules = newPkg.getRules();
- for ( int i = 0; i < newRules.length; i++ ) {
+ for (int i = 0; i < newRules.length; i++) {
final Rule newRule = newRules[i];
// remove the rule if it already exists
- if ( pkg.getRule( newRule.getName() ) != null ) {
- removeRule( pkg,
- pkg.getRule( newRule.getName() ) );
+ if (pkg.getRule(newRule.getName()) != null) {
+ removeRule(pkg,
+ pkg.getRule(newRule.getName()));
}
- pkg.addRule( newRule );
+ pkg.addRule(newRule);
}
//Merge The Rule Flows
- if ( newPkg.getRuleFlows() != null ) {
+ if (newPkg.getRuleFlows() != null) {
final Map flows = newPkg.getRuleFlows();
- for ( final Iterator iter = flows.values().iterator(); iter.hasNext(); ) {
+ for (final Iterator iter = flows.values().iterator(); iter.hasNext();) {
final Process flow = (Process) iter.next();
- pkg.addProcess( flow );
+ pkg.addProcess(flow);
}
- }
-
+ }
+
// // this handles re-wiring any dirty Packages, it's done lazily to allow incremental
// // additions without incurring the repeated cost.
// if ( this.reloadPackageCompilationData == null ) {
@@ -618,88 +623,88 @@
// this.reloadPackageCompilationData.addDialectDatas( pkg.getDialectRuntimeRegistry() );
}
- public TypeDeclaration getTypeDeclaration(Class< ? > clazz) {
- return this.classTypeDeclaration.get( clazz );
+ public TypeDeclaration getTypeDeclaration(Class<?> clazz) {
+ return this.classTypeDeclaration.get(clazz);
}
public Collection<TypeDeclaration> getTypeDeclarations() {
return this.classTypeDeclaration.values();
}
-
- public void addRule(final Package pkg,
- final Rule rule) throws InvalidPatternException {
- synchronized ( this.pkgs ) {
- this.eventSupport.fireBeforeRuleAdded( pkg,
- rule );
- // if ( !rule.isValid() ) {
- // throw new IllegalArgumentException( "The rule called " + rule.getName() + " is not valid. Check for compile errors reported." );
- // }
- addRule( rule );
- this.eventSupport.fireAfterRuleAdded( pkg,
- rule );
+
+ public void addRule(final Package pkg,
+ final Rule rule) throws InvalidPatternException {
+ synchronized (this.pkgs) {
+ this.eventSupport.fireBeforeRuleAdded(pkg,
+ rule);
+ // if ( !rule.isValid() ) {
+ // throw new IllegalArgumentException( "The rule called " + rule.getName() + " is not valid. Check for compile errors reported." );
+ // }
+ addRule(rule);
+ this.eventSupport.fireAfterRuleAdded(pkg,
+ rule);
}
}
protected abstract void addRule(final Rule rule) throws InvalidPatternException;
public void removePackage(final String packageName) {
- synchronized ( this.pkgs ) {
- final Package pkg = (Package) this.pkgs.get( packageName );
- if ( pkg == null ) {
- throw new IllegalArgumentException( "Package name '" + packageName + "' does not exist for this Rule Base." );
+ synchronized (this.pkgs) {
+ final Package pkg = this.pkgs.get(packageName);
+ if (pkg == null) {
+ throw new IllegalArgumentException("Package name '" + packageName + "' does not exist for this Rule Base.");
}
// only acquire the lock if it hasn't been done explicitely
boolean doUnlock = false;
- if ( !this.lock.isHeldByCurrentThread() && (this.wms == null || this.wms.length == 0) ) {
+ if (!this.lock.isHeldByCurrentThread() && (this.wms == null || this.wms.length == 0)) {
lock();
doUnlock = true;
}
try {
this.removalsSinceLock++;
- this.eventSupport.fireBeforePackageRemoved( pkg );
+ this.eventSupport.fireBeforePackageRemoved(pkg);
final Rule[] rules = pkg.getRules();
- for ( int i = 0; i < rules.length; ++i ) {
- removeRule( pkg,
- rules[i] );
+ for (int i = 0; i < rules.length; ++i) {
+ removeRule(pkg,
+ rules[i]);
}
// getting the list of referenced globals
final Set referencedGlobals = new HashSet();
- for ( final Iterator it = this.pkgs.values().iterator(); it.hasNext(); ) {
+ for (final Iterator it = this.pkgs.values().iterator(); it.hasNext();) {
final org.drools.rule.Package pkgref = (org.drools.rule.Package) it.next();
- if ( pkgref != pkg ) {
- referencedGlobals.addAll( pkgref.getGlobals().keySet() );
+ if (pkgref != pkg) {
+ referencedGlobals.addAll(pkgref.getGlobals().keySet());
}
}
// removing globals declared inside the package that are not shared
- for ( final Iterator it = pkg.getGlobals().keySet().iterator(); it.hasNext(); ) {
+ for (final Iterator it = pkg.getGlobals().keySet().iterator(); it.hasNext();) {
final String globalName = (String) it.next();
- if ( !referencedGlobals.contains( globalName ) ) {
- this.globals.remove( globalName );
+ if (!referencedGlobals.contains(globalName)) {
+ this.globals.remove(globalName);
}
}
//and now the rule flows
final Map flows = pkg.getRuleFlows();
- for ( final Iterator iter = flows.keySet().iterator(); iter.hasNext(); ) {
- removeProcess( (String) iter.next() );
+ for (final Iterator iter = flows.keySet().iterator(); iter.hasNext();) {
+ removeProcess((String) iter.next());
}
// removing the package itself from the list
- this.pkgs.remove( pkg.getName() );
-
+ this.pkgs.remove(pkg.getName());
+
pkg.getDialectRuntimeRegistry().onRemove();
//clear all members of the pkg
pkg.clear();
- this.eventSupport.fireAfterPackageRemoved( pkg );
+ this.eventSupport.fireAfterPackageRemoved(pkg);
// only unlock if it had been acquired implicitely
} finally {
- if ( doUnlock ) {
+ if (doUnlock) {
unlock();
}
}
@@ -708,35 +713,35 @@
public void removeRule(final String packageName,
final String ruleName) {
- synchronized ( this.pkgs ) {
- final Package pkg = (Package) this.pkgs.get( packageName );
- if ( pkg == null ) {
- throw new IllegalArgumentException( "Package name '" + packageName + "' does not exist for this Rule Base." );
+ synchronized (this.pkgs) {
+ final Package pkg = this.pkgs.get(packageName);
+ if (pkg == null) {
+ throw new IllegalArgumentException("Package name '" + packageName + "' does not exist for this Rule Base.");
}
- final Rule rule = pkg.getRule( ruleName );
- if ( rule == null ) {
- throw new IllegalArgumentException( "Rule name '" + ruleName + "' does not exist in the Package '" + packageName + "'." );
+ final Rule rule = pkg.getRule(ruleName);
+ if (rule == null) {
+ throw new IllegalArgumentException("Rule name '" + ruleName + "' does not exist in the Package '" + packageName + "'.");
}
// only acquire the lock if it hasn't been done explicitely
boolean doUnlock = false;
- if ( !this.lock.isHeldByCurrentThread() && (this.wms == null || this.wms.length == 0) ) {
+ if (!this.lock.isHeldByCurrentThread() && (this.wms == null || this.wms.length == 0)) {
lock();
doUnlock = true;
}
this.removalsSinceLock++;
- removeRule( pkg,
- rule );
- pkg.removeRule( rule );
- if ( this.reloadPackageCompilationData == null ) {
+ removeRule(pkg,
+ rule);
+ pkg.removeRule(rule);
+ if (this.reloadPackageCompilationData == null) {
this.reloadPackageCompilationData = new ReloadPackageCompilationData();
}
- this.reloadPackageCompilationData.addDialectDatas( pkg.getDialectRuntimeRegistry() );
+ this.reloadPackageCompilationData.addDialectDatas(pkg.getDialectRuntimeRegistry());
// only unlock if it had been acquired implicitely
- if ( doUnlock ) {
+ if (doUnlock) {
unlock();
}
}
@@ -744,13 +749,13 @@
public void removeRule(final Package pkg,
final Rule rule) {
- synchronized ( this.pkgs ) {
- this.eventSupport.fireBeforeRuleRemoved( pkg,
- rule );
-
- removeRule( rule );
- this.eventSupport.fireAfterRuleRemoved( pkg,
- rule );
+ synchronized (this.pkgs) {
+ this.eventSupport.fireBeforeRuleRemoved(pkg,
+ rule);
+
+ removeRule(rule);
+ this.eventSupport.fireAfterRuleRemoved(pkg,
+ rule);
}
}
@@ -758,69 +763,94 @@
public void removeFunction(final String packageName,
final String functionName) {
- synchronized ( this.pkgs ) {
- final Package pkg = (Package) this.pkgs.get( packageName );
- if ( pkg == null ) {
- throw new IllegalArgumentException( "Package name '" + packageName + "' does not exist for this Rule Base." );
+ synchronized (this.pkgs) {
+ final Package pkg = this.pkgs.get(packageName);
+ if (pkg == null) {
+ throw new IllegalArgumentException("Package name '" + packageName + "' does not exist for this Rule Base.");
}
- this.eventSupport.fireBeforeFunctionRemoved( pkg,
- functionName );
+ this.eventSupport.fireBeforeFunctionRemoved(pkg,
+ functionName);
- if ( !pkg.getFunctions().containsKey( functionName ) ) {
- throw new IllegalArgumentException( "function name '" + packageName + "' does not exist in the Package '" + packageName + "'." );
+ if (!pkg.getFunctions().containsKey(functionName)) {
+ throw new IllegalArgumentException("function name '" + packageName + "' does not exist in the Package '" + packageName + "'.");
}
- pkg.removeFunction( functionName );
+ pkg.removeFunction(functionName);
- if ( this.reloadPackageCompilationData == null ) {
+ if (this.reloadPackageCompilationData == null) {
this.reloadPackageCompilationData = new ReloadPackageCompilationData();
}
- this.reloadPackageCompilationData.addDialectDatas( pkg.getDialectRuntimeRegistry() );
+ this.reloadPackageCompilationData.addDialectDatas(pkg.getDialectRuntimeRegistry());
- this.eventSupport.fireAfterFunctionRemoved( pkg,
- functionName );
+ this.eventSupport.fireAfterFunctionRemoved(pkg,
+ functionName);
}
}
public void addProcess(final Process process) {
- synchronized ( this.pkgs ) {
- this.processes.put( process.getId(),
- process );
+ synchronized (this.pkgs) {
+ this.processes.put(process.getId(),
+ process);
}
}
public void removeProcess(final String id) {
- synchronized ( this.pkgs ) {
- this.processes.remove( id );
+ synchronized (this.pkgs) {
+ this.processes.remove(id);
}
}
public Process getProcess(final String id) {
- Process process = null;
- synchronized ( this.pkgs ) {
- process = (Process) this.processes.get( id );
+ Process process;
+ synchronized (this.pkgs) {
+ process = (Process) this.processes.get(id);
}
return process;
}
public void addStatefulSession(final StatefulSession statefulSession) {
- synchronized ( this.statefulSessions ) {
- this.statefulSessions.add( statefulSession );
+ try {
+ statefuleSessionLock.lock();
+
+ this.statefulSessions.add(statefulSession);
+ } finally {
+ statefuleSessionLock.unlock();
}
+
}
public Package getPackage(final String name) {
- return (Package) this.pkgs.get( name );
+ return this.pkgs.get(name);
}
public StatefulSession[] getStatefulSessions() {
- return (StatefulSession[]) this.statefulSessions.toArray( new StatefulSession[this.statefulSessions.size()] );
+ final StatefulSession[] copyOfSessions;
+ try {
+ statefuleSessionLock.lock();
+ copyOfSessions = new StatefulSession[this.statefulSessions.size()];
+
+ this.statefulSessions.toArray(copyOfSessions);
+ } finally {
+ statefuleSessionLock.unlock();
+ }
+
+ return copyOfSessions;
}
public InternalWorkingMemory[] getWorkingMemories() {
- return (InternalWorkingMemory[]) this.statefulSessions.toArray( new InternalWorkingMemory[this.statefulSessions.size()] );
+ final InternalWorkingMemory[] copyOfMemories;
+ try {
+ statefuleSessionLock.lock();
+ copyOfMemories = new InternalWorkingMemory[this.statefulSessions.size()];
+
+ this.statefulSessions.toArray(copyOfMemories);
+ } finally {
+ statefuleSessionLock.unlock();
+ }
+
+ return copyOfMemories;
}
public RuleBaseConfiguration getConfiguration() {
@@ -832,20 +862,19 @@
}
public void executeQueuedActions() {
- synchronized ( this.pkgs ) {
- if ( this.reloadPackageCompilationData != null ) {
- this.reloadPackageCompilationData.execute( this );
+ synchronized (this.pkgs) {
+ if (this.reloadPackageCompilationData != null) {
+ this.reloadPackageCompilationData.execute(this);
this.reloadPackageCompilationData = null;
}
-
}
}
public RuleBasePartitionId createNewPartitionId() {
- RuleBasePartitionId p = null;
- synchronized ( this.partitionIDs ) {
+ RuleBasePartitionId p;
+ synchronized (this.partitionIDs) {
p = new RuleBasePartitionId("P-" + this.partitionIDs.size());
- this.partitionIDs.add( p );
+ this.partitionIDs.add(p);
}
return p;
}
@@ -855,23 +884,23 @@
}
public void addEventListener(final RuleBaseEventListener listener) {
- // since the event support is thread-safe, no need for locks... right?
- this.eventSupport.addEventListener( listener );
+ // no need for synchonization or locking because eventSupport is thread-safe
+ this.eventSupport.addEventListener(listener);
}
public void removeEventListener(final RuleBaseEventListener listener) {
- // since the event support is thread-safe, no need for locks... right?
- this.eventSupport.removeEventListener( listener );
+ // no need for synchonization or locking because eventSupport is thread-safe
+ this.eventSupport.removeEventListener(listener);
}
public List<RuleBaseEventListener> getRuleBaseEventListeners() {
- // since the event support is thread-safe, no need for locks... right?
+ // no need for synchonization or locking because eventSupport is thread-safe
return this.eventSupport.getEventListeners();
}
public boolean isEvent(Class clazz) {
- for ( Package pkg : this.pkgs.values() ) {
- if ( pkg.isEvent( clazz ) ) {
+ for (Package pkg : this.pkgs.values()) {
+ if (pkg.isEvent(clazz)) {
return true;
}
}
@@ -879,9 +908,9 @@
}
public FactType getFactType(final String name) {
- for ( Package pkg : this.pkgs.values() ) {
- FactType type = pkg.getFactType( name );
- if ( type != null ) {
+ for (Package pkg : this.pkgs.values()) {
+ FactType type = pkg.getFactType(name);
+ if (type != null) {
return type;
}
}
@@ -889,41 +918,41 @@
}
public static class ReloadPackageCompilationData
- implements
- RuleBaseAction {
- private static final long serialVersionUID = 1L;
+ implements
+ RuleBaseAction {
+ private static final long serialVersionUID = 1L;
private Set<DialectRuntimeRegistry> set;
public void readExternal(ObjectInput in) throws IOException,
- ClassNotFoundException {
+ ClassNotFoundException {
set = (Set<DialectRuntimeRegistry>) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject( set );
+ out.writeObject(set);
}
public void addDialectDatas(final DialectRuntimeRegistry registry) {
- if ( this.set == null ) {
+ if (this.set == null) {
this.set = new HashSet<DialectRuntimeRegistry>();
}
- if ( !this.set.contains( registry ) ) this.set.add( registry );
+ if (!this.set.contains(registry)) this.set.add(registry);
}
public void execute(final InternalRuleBase ruleBase) {
- for ( final DialectRuntimeRegistry registry : this.set ) {
+ for (final DialectRuntimeRegistry registry : this.set) {
registry.onBeforeExecute();
}
}
}
public static interface RuleBaseAction
- extends
- Externalizable {
+ extends
+ Externalizable {
public void execute(InternalRuleBase ruleBase);
}
-
- public ClassFieldAccessorCache getClassFieldAccessorCache() {
+
+ public ClassFieldAccessorCache getClassFieldAccessorCache() {
return this.classFieldAccessorCache;
}
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java 2009-03-29 20:10:29 UTC (rev 25874)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java 2009-03-29 20:59:36 UTC (rev 25875)
@@ -171,7 +171,7 @@
}
ruleBase.getAgendaGroupRuleTotals().put( agendaGroup,
- new Integer( i ) );
+ i );
}
ordered = true;
}
@@ -221,7 +221,7 @@
}
public BaseNode[] getTerminalNodes(final Rule rule) {
- return (BaseNode[]) this.rules.get( rule );
+ return this.rules.get( rule );
}
public void removeRule(final Rule rule) {
@@ -276,11 +276,11 @@
if ( id == null ) {
return this.nextId++;
}
- return id.intValue();
+ return id;
}
public void releaseId(int id) {
- this.recycledIds.add( new Integer( id ) );
+ this.recycledIds.add(id );
}
public int getLastId() {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java 2009-03-29 20:10:29 UTC (rev 25874)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java 2009-03-29 20:59:36 UTC (rev 25875)
@@ -18,15 +18,12 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
-import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -154,7 +151,7 @@
// always add the default entry point
EntryPointNode epn = new EntryPointNode( this.reteooBuilder.getIdGenerator().getNextId(),
RuleBasePartitionId.MAIN_PARTITION,
- this.config.isMultithreadEvaluation(),
+ this.getConfig().isMultithreadEvaluation(),
this.rete,
EntryPoint.DEFAULT );
epn.attach();
@@ -277,8 +274,8 @@
if ( keepReference ) {
super.addStatefulSession( session );
- for ( Iterator it = session.getRuleBaseUpdateListeners().iterator(); it.hasNext(); ) {
- addEventListener( (RuleBaseEventListener) it.next() );
+ for (Object listener : session.getRuleBaseUpdateListeners()) {
+ addEventListener((RuleBaseEventListener) listener);
}
}
@@ -292,8 +289,7 @@
try {
stream.close();
} catch ( IOException e ) {
- new RuntimeException( "Unable to close stream",
- e );
+ throw new RuntimeException( "Unable to close stream", e );
}
}
return session;
@@ -312,16 +308,16 @@
environment );
}
- public StatefulSession newStatefulSession(int id,
+ StatefulSession newStatefulSession(int id,
final SessionConfiguration sessionConfig,
final Environment environment) {
- if ( this.config.isSequential() ) {
+ if ( this.getConfig().isSequential() ) {
throw new RuntimeException( "Cannot have a stateful rule session, with sequential configuration set to true" );
}
- ReteooStatefulSession session = null;
+ ReteooStatefulSession session ;
synchronized ( this.pkgs ) {
- ExecutorService executor = ExecutorServiceFactory.createExecutorService( this.config.getExecutorService() );;
+ ExecutorService executor = ExecutorServiceFactory.createExecutorService( this.getConfig().getExecutorService() );
session = new ReteooStatefulSession( id,
this,
executor,
@@ -332,8 +328,8 @@
if ( sessionConfig.isKeepReference() ) {
super.addStatefulSession( session );
- for ( Iterator it = session.getRuleBaseUpdateListeners().iterator(); it.hasNext(); ) {
- addEventListener( (RuleBaseEventListener) it.next() );
+ for (Object listener : session.getRuleBaseUpdateListeners()) {
+ addEventListener((RuleBaseEventListener) listener);
}
}
@@ -441,7 +437,7 @@
public StatelessSession newStatelessSession() {
//orders the rules
- if ( this.config.isSequential() ) {
+ if ( this.getConfig().isSequential() ) {
this.reteooBuilder.order();
}
@@ -470,7 +466,7 @@
public void addPackages(Collection<Package> pkgs) {
super.addPackages( pkgs );
- if ( this.config.isSequential() ) {
+ if ( this.getConfig().isSequential() ) {
this.reteooBuilder.setOrdered( false );
}
}
@@ -479,7 +475,7 @@
List<Package> list = new ArrayList<Package>();
list.add( newPkg );
super.addPackages( list );
- if ( this.config.isSequential() ) {
+ if ( this.getConfig().isSequential() ) {
this.reteooBuilder.setOrdered( false );
}
}
More information about the jboss-svn-commits
mailing list