You can subscribe to this list here.
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(233) |
Sep
(199) |
Oct
(206) |
Nov
(185) |
Dec
(270) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
(232) |
Feb
(426) |
Mar
(623) |
Apr
(592) |
May
(506) |
Jun
(389) |
Jul
(160) |
Aug
(3) |
Sep
(1) |
Oct
(1) |
Nov
(2) |
Dec
(5) |
2007 |
Jan
(1) |
Feb
(1) |
Mar
(2) |
Apr
(2) |
May
(4) |
Jun
(2) |
Jul
|
Aug
(3) |
Sep
(5) |
Oct
(9) |
Nov
(6) |
Dec
(6) |
2008 |
Jan
(3) |
Feb
|
Mar
(1) |
Apr
(3) |
May
(3) |
Jun
(5) |
Jul
(10) |
Aug
(2) |
Sep
(12) |
Oct
(10) |
Nov
(54) |
Dec
(49) |
2009 |
Jan
(19) |
Feb
(13) |
Mar
(20) |
Apr
(24) |
May
(44) |
Jun
(29) |
Jul
(32) |
Aug
(10) |
Sep
(7) |
Oct
(10) |
Nov
(4) |
Dec
(17) |
2010 |
Jan
(14) |
Feb
(5) |
Mar
(23) |
Apr
(50) |
May
(31) |
Jun
(9) |
Jul
(5) |
Aug
(4) |
Sep
(7) |
Oct
(5) |
Nov
(2) |
Dec
(3) |
2011 |
Jan
(12) |
Feb
(5) |
Mar
(5) |
Apr
(3) |
May
(4) |
Jun
(3) |
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2012 |
Jan
(1) |
Feb
(2) |
Mar
|
Apr
(1) |
May
(1) |
Jun
(2) |
Jul
(4) |
Aug
(1) |
Sep
|
Oct
(1) |
Nov
|
Dec
|
2013 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(3) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
2015 |
Jan
|
Feb
|
Mar
(2) |
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <jbo...@li...> - 2006-04-27 09:55:23
|
Author: mar...@jb... Date: 2006-04-27 05:55:10 -0400 (Thu, 27 Apr 2006) New Revision: 3992 Removed: labs/jbossrules/trunk/drools-core/src/main/java/org/objectweb/ Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AgendaEventSupport.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/WorkingMemoryEventSupport.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleBaseImpl.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/WorkingMemoryImpl.java Log: -Add Lock code. So that when we add a Package to RuleBaseImpl it doesn't udpate a working memory during a WMA. Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java 2006-04-27 09:00:47 UTC (rev 3991) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java 2006-04-27 09:55:10 UTC (rev 3992) @@ -93,7 +93,7 @@ Map getGlobals(); /** - * Set a specific piece of application data in this working memory + * Set a specific piece of global in this working memory. * * @param name * the name under which to populate the data @@ -104,7 +104,7 @@ Object value); /** - * Retrieve a specific piece of application data by name + * Retrieve a specific piece of global data by name * * @return application data or null if nothing is set under this name */ Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AgendaEventSupport.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AgendaEventSupport.java 2006-04-27 09:00:47 UTC (rev 3991) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AgendaEventSupport.java 2006-04-27 09:55:10 UTC (rev 3992) @@ -33,7 +33,7 @@ public class AgendaEventSupport implements Serializable { - private final List listeners = new ArrayList(); + private final List listeners = Collections.synchronizedList( new ArrayList() ); private final WorkingMemory workingMemory; public AgendaEventSupport(WorkingMemory workingMemory) { Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/WorkingMemoryEventSupport.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/WorkingMemoryEventSupport.java 2006-04-27 09:00:47 UTC (rev 3991) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/WorkingMemoryEventSupport.java 2006-04-27 09:55:10 UTC (rev 3992) @@ -34,7 +34,7 @@ public class WorkingMemoryEventSupport implements Serializable { - private final List listeners = new ArrayList(); + private final List listeners = Collections.synchronizedList( new ArrayList() ); private final WorkingMemory workingMemory; public WorkingMemoryEventSupport(WorkingMemory workingMemory) { Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleBaseImpl.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleBaseImpl.java 2006-04-27 09:00:47 UTC (rev 3991) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleBaseImpl.java 2006-04-27 09:55:10 UTC (rev 3992) @@ -170,16 +170,16 @@ this.rete = (Rete) streamWithLoader.readObject(); this.reteooBuilder = (ReteooBuilder) streamWithLoader.readObject(); - + this.reteooBuilder.setRuleBase( this ); this.reteooBuilder.setRete( this.rete ); - + this.factHandleFactory = (FactHandleFactory) streamWithLoader.readObject(); this.globals = (Map) streamWithLoader.readObject(); this.workingMemories = new WeakHashMap(); this.lock = new Object(); - + } // ------------------------------------------------------------ @@ -306,10 +306,12 @@ /** * Add a <code>Package</code> to the network. Iterates through the * <code>Package</code> adding Each individual <code>Rule</code> to the - * network. + * network. Before update network each referenced <code>WorkingMemory</code> + * is locked. * * @param pkg - * The rule-set to add. + * The package to add. + * @throws PackageIntegrationException * * @throws RuleIntegrationException * if an error prevents complete construction of the network for @@ -317,12 +319,17 @@ * @throws FactException * @throws InvalidPatternException */ - public void addPackage(Package newPkg) throws RuleIntegrationException, - PackageIntegrationException, - FactException, - InvalidPatternException { + public void addPackage(Package newPkg) throws PackageIntegrationException { newPkg.checkValidity(); Package pkg = (Package) this.pkgs.get( newPkg.getName() ); + + // Iterate each workingMemory and lock it + // This is so we don't update the Rete network during propagation + for ( Iterator it = this.workingMemories.keySet().iterator(); it.hasNext(); ) { + WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) it.next(); + workingMemory.getLock().lock(); + } + if ( pkg != null ) { mergePackage( pkg, newPkg ); @@ -351,10 +358,19 @@ } this.packageClassLoader.addClassLoader( newPkg.getPackageCompilationData().getClassLoader() ); + + // Iterate each workingMemory and attempt to fire any rules, that were activated as a result of the new rule addition + // + for ( Iterator it = this.workingMemories.keySet().iterator(); it.hasNext(); ) { + WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) it.next(); + + workingMemory.fireAllRules(); + workingMemory.getLock().unlock(); + } } - public void mergePackage(Package pkg, - Package newPkg) throws PackageIntegrationException { + private void mergePackage(Package pkg, + Package newPkg) throws PackageIntegrationException { Map globals = pkg.getGlobals(); List imports = pkg.getImports(); @@ -385,21 +401,15 @@ } } - public void addRule(Rule rule) throws InvalidPatternException { - if ( !rule.isValid() ) throw new IllegalArgumentException( "The rule called " + rule.getName() + " is not valid. Check for compile errors reported." ); + private void addRule(Rule rule) throws InvalidPatternException { + if ( !rule.isValid() ) { + throw new IllegalArgumentException( "The rule called " + rule.getName() + " is not valid. Check for compile errors reported." ); + } - synchronized ( this.lock ) { - // This adds the rule. ReteBuilder has a reference to the WorkingMemories and will propagate any existing facts. - this.reteooBuilder.addRule( rule ); + // This adds the rule. ReteBuilder has a reference to the WorkingMemories and will propagate any existing facts. + this.reteooBuilder.addRule( rule ); + } - // Iterate each workingMemory and attempt to fire any rules, that were activated as a result of the new rule addition - for ( Iterator it = this.workingMemories.keySet().iterator(); it.hasNext(); ) { - WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) it.next(); - workingMemory.fireAllRules(); - } - } - } - public void removePackage(String packageName) { Package pkg = (Package) this.pkgs.get( packageName ); Rule[] rules = pkg.getRules(); Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/WorkingMemoryImpl.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/WorkingMemoryImpl.java 2006-04-27 09:00:47 UTC (rev 3991) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/WorkingMemoryImpl.java 2006-04-27 09:55:10 UTC (rev 3992) @@ -58,6 +58,8 @@ import org.drools.util.IdentityMap; import org.drools.util.PrimitiveLongMap; import org.drools.util.PrimitiveLongStack; +import org.drools.util.concurrent.locks.Lock; +import org.drools.util.concurrent.locks.ReentrantLock; /** * Implementation of <code>WorkingMemory</code>. @@ -90,9 +92,9 @@ /** Global values which are associated with this memory. */ private final Map globals = new HashMap(); -// /** Handle-to-object mapping. */ -// private final PrimitiveLongMap objects = new PrimitiveLongMap( 32, -// 8 ); + // /** Handle-to-object mapping. */ + // private final PrimitiveLongMap objects = new PrimitiveLongMap( 32, + // 8 ); /** Object-to-handle mapping. */ private final Map identityMap = new IdentityMap(); @@ -117,7 +119,7 @@ //private LinkedList factQueue = new LinkedList(); - private Object lock = new Object(); + private ReentrantLock lock = new ReentrantLock(); /** The <code>RuleBase</code> with which this memory is associated. */ private final RuleBaseImpl ruleBase; @@ -200,10 +202,10 @@ * @see WorkingMemory */ public void setGlobal(String name, - Object value) { - // Make sure the application data has been declared in the RuleBase - Map applicationDataDefintions = this.ruleBase.getGlobals(); - Class type = (Class) applicationDataDefintions.get( name ); + Object value) { + // Make sure the global has been declared in the RuleBase + Map globalDefintions = this.ruleBase.getGlobals(); + Class type = (Class) globalDefintions.get( name ); if ( (type == null) ) { throw new RuntimeException( "Unexpected global [" + name + "]" ); } else if ( !type.isInstance( value ) ) { @@ -219,7 +221,8 @@ * @see WorkingMemory */ public Object getGlobal(String name) { - return this.globals.get( name ); + Object object = this.globals.get( name ); + return object; } /** @@ -246,6 +249,13 @@ return this.ruleBase; } + /** + * @see WorkingMemory + */ + public void fireAllRules() throws FactException { + fireAllRules( null ); + } + public synchronized void fireAllRules(AgendaFilter agendaFilter) throws FactException { // If we're already firing a rule, then it'll pick up // the firing for any other assertObject(..) that get @@ -266,13 +276,6 @@ } /** - * @see WorkingMemory - */ - public void fireAllRules() throws FactException { - fireAllRules( null ); - } - - /** * Returns the fact Object for the given <code>FactHandle</code>. It * actually attemps to return the value from the handle, before retrieving * it from objects map. @@ -286,14 +289,6 @@ */ public Object getObject(FactHandle handle) { InternalFactHandle handleImpl = (InternalFactHandle) handle; -// if ( handleImpl.getObject() == null ) { -// Object object = this.objects.get( handleImpl.getId() ); -// if ( object == null ) { -// throw new NoSuchFactObjectException( handle ); -// } -// handleImpl.setObject( object ); -// } - return handleImpl.getObject(); } @@ -437,9 +432,9 @@ boolean logical, Rule rule, Activation activation) throws FactException { + this.lock.lock(); + try { - synchronized ( this.ruleBase.getLock() ) { - // check if the object already exists in the WM FactHandleImpl handle = (FactHandleImpl) this.identityMap.get( object ); @@ -531,6 +526,8 @@ handle, object ); return handle; + } finally { + this.lock.unlock(); } } @@ -595,9 +592,9 @@ * The object. */ void putObject(FactHandle handle, - Object object) { -// Object oldValue = this.objects.put( ((FactHandleImpl) handle).getId(), -// object ); + Object object) { + // Object oldValue = this.objects.put( ((FactHandleImpl) handle).getId(), + // object ); this.identityMap.put( object, handle ); @@ -631,7 +628,8 @@ boolean updateEqualsMap, Rule rule, Activation activation) throws FactException { - synchronized ( this.ruleBase.getLock() ) { + this.lock.lock(); + try { removePropertyChangeListener( handle ); PropagationContext propagationContext = new PropagationContextImpl( this.propagationIdCounter++, @@ -668,6 +666,8 @@ oldObject ); ((FactHandleImpl) handle).invalidate(); + } finally { + this.lock.unlock(); } } @@ -686,7 +686,8 @@ Object object, Rule rule, Activation activation) throws FactException { - synchronized ( this.ruleBase.getLock() ) { + this.lock.lock(); + try { Object originalObject = removeObject( handle ); if ( originalObject == null ) { @@ -731,6 +732,8 @@ handle, originalObject, object ); + } finally { + this.lock.unlock(); } } @@ -857,6 +860,10 @@ this.ruleBase.disposeWorkingMemory( this ); } + public Lock getLock() { + return this.lock; + } + private static class FactStatus { private int counter; private String status; |
From: <jbo...@li...> - 2006-04-27 09:00:56
|
Author: mar...@jb... Date: 2006-04-27 05:00:47 -0400 (Thu, 27 Apr 2006) New Revision: 3991 Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/concurrent/ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/concurrent/locks/ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/concurrent/locks/Lock.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/concurrent/locks/ReentrantLock.java Log: -Added in a stripped Lock implementation from concurrent backport Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/concurrent/locks/Lock.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/concurrent/locks/Lock.java 2006-04-27 05:25:16 UTC (rev 3990) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/concurrent/locks/Lock.java 2006-04-27 09:00:47 UTC (rev 3991) @@ -0,0 +1,243 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package org.drools.util.concurrent.locks; + +//import edu.emory.mathcs.backport.java.util.concurrent.locks.*; // for javadoc (till 6280605 is fixed) +//import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit; + +/** + * <tt>Lock</tt> implementations provide more extensive locking + * operations than can be obtained using <tt>synchronized</tt> methods + * and statements. They allow more flexible structuring, may have + * quite different properties, and may support multiple associated + * {@link Condition} objects. + * + * <p>A lock is a tool for controlling access to a shared resource by + * multiple threads. Commonly, a lock provides exclusive access to a + * shared resource: only one thread at a time can acquire the lock and + * all access to the shared resource requires that the lock be + * acquired first. However, some locks may allow concurrent access to + * a shared resource, such as the read lock of a {@link + * ReadWriteLock}. + * + * <p>The use of <tt>synchronized</tt> methods or statements provides + * access to the implicit monitor lock associated with every object, but + * forces all lock acquisition and release to occur in a block-structured way: + * when multiple locks are acquired they must be released in the opposite + * order, and all locks must be released in the same lexical scope in which + * they were acquired. + * + * <p>While the scoping mechanism for <tt>synchronized</tt> methods + * and statements makes it much easier to program with monitor locks, + * and helps avoid many common programming errors involving locks, + * there are occasions where you need to work with locks in a more + * flexible way. For example, some algorithms for traversing + * concurrently accessed data structures require the use of + * "hand-over-hand" or "chain locking": you + * acquire the lock of node A, then node B, then release A and acquire + * C, then release B and acquire D and so on. Implementations of the + * <tt>Lock</tt> interface enable the use of such techniques by + * allowing a lock to be acquired and released in different scopes, + * and allowing multiple locks to be acquired and released in any + * order. + * + * <p>With this increased flexibility comes additional + * responsibility. The absence of block-structured locking removes the + * automatic release of locks that occurs with <tt>synchronized</tt> + * methods and statements. In most cases, the following idiom + * should be used: + * + * <pre><tt> Lock l = ...; + * l.lock(); + * try { + * // access the resource protected by this lock + * } finally { + * l.unlock(); + * } + * </tt></pre> + * + * When locking and unlocking occur in different scopes, care must be + * taken to ensure that all code that is executed while the lock is + * held is protected by try-finally or try-catch to ensure that the + * lock is released when necessary. + * + * <p><tt>Lock</tt> implementations provide additional functionality + * over the use of <tt>synchronized</tt> methods and statements by + * providing a non-blocking attempt to acquire a lock ({@link + * #tryLock()}), an attempt to acquire the lock that can be + * interrupted ({@link #lockInterruptibly}, and an attempt to acquire + * the lock that can timeout ({@link #tryLock(long, TimeUnit)}). + * + * <p>A <tt>Lock</tt> class can also provide behavior and semantics + * that is quite different from that of the implicit monitor lock, + * such as guaranteed ordering, non-reentrant usage, or deadlock + * detection. If an implementation provides such specialized semantics + * then the implementation must document those semantics. + * + * <p>Note that <tt>Lock</tt> instances are just normal objects and can + * themselves be used as the target in a <tt>synchronized</tt> statement. + * Acquiring the + * monitor lock of a <tt>Lock</tt> instance has no specified relationship + * with invoking any of the {@link #lock} methods of that instance. + * It is recommended that to avoid confusion you never use <tt>Lock</tt> + * instances in this way, except within their own implementation. + * + * <p>Except where noted, passing a <tt>null</tt> value for any + * parameter will result in a {@link NullPointerException} being + * thrown. + * + * <h3>Memory Synchronization</h3> + * <p>All <tt>Lock</tt> implementations <em>must</em> enforce the same + * memory synchronization semantics as provided by the built-in monitor + * lock, as described in <a href="http://java.sun.com/docs/books/jls/"> + * The Java Language Specification, Third Edition (17.4 Memory Model)</a>: + * <ul> + * <li>A successful <tt>lock</tt> operation has the same memory + * synchronization effects as a successful <em>Lock</em> action. + * <li>A successful <tt>unlock</tt> operation has the same + * memory synchronization effects as a successful <em>Unlock</em> action. + * </ul> + * + * Unsuccessful locking and unlocking operations, and reentrant + * locking/unlocking operations, do not require any memory + * synchronization effects. + * + * <h3>Implementation Considerations</h3> + * + * <p> The three forms of lock acquisition (interruptible, + * non-interruptible, and timed) may differ in their performance + * characteristics, ordering guarantees, or other implementation + * qualities. Further, the ability to interrupt the <em>ongoing</em> + * acquisition of a lock may not be available in a given <tt>Lock</tt> + * class. Consequently, an implementation is not required to define + * exactly the same guarantees or semantics for all three forms of + * lock acquisition, nor is it required to support interruption of an + * ongoing lock acquisition. An implementation is required to clearly + * document the semantics and guarantees provided by each of the + * locking methods. It must also obey the interruption semantics as + * defined in this interface, to the extent that interruption of lock + * acquisition is supported: which is either totally, or only on + * method entry. + * + * <p>As interruption generally implies cancellation, and checks for + * interruption are often infrequent, an implementation can favor responding + * to an interrupt over normal method return. This is true even if it can be + * shown that the interrupt occurred after another action may have unblocked + * the thread. An implementation should document this behavior. + * + * + * @see ReentrantLock + * @see Condition + * @see ReadWriteLock + * + * @since 1.5 + * @author Doug Lea + * + */ +public interface Lock { + + /** + * Acquires the lock. + * <p>If the lock is not available then + * the current thread becomes disabled for thread scheduling + * purposes and lies dormant until the lock has been acquired. + * <p><b>Implementation Considerations</b> + * <p>A <tt>Lock</tt> implementation may be able to detect + * erroneous use of the lock, such as an invocation that would cause + * deadlock, and may throw an (unchecked) exception in such circumstances. + * The circumstances and the exception type must be documented by that + * <tt>Lock</tt> implementation. + */ + void lock(); + + /** + * Acquires the lock unless the current thread is + * {@link Thread#interrupt interrupted}. + * <p>Acquires the lock if it is available and returns immediately. + * <p>If the lock is not available then + * the current thread becomes disabled for thread scheduling + * purposes and lies dormant until one of two things happens: + * <ul> + * <li>The lock is acquired by the current thread; or + * <li>Some other thread {@link Thread#interrupt interrupts} the current + * thread, and interruption of lock acquisition is supported. + * </ul> + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@link Thread#interrupt interrupted} while acquiring + * the lock, and interruption of lock acquisition is supported, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * <p><b>Implementation Considerations</b> + * + * <p>The ability to interrupt a lock acquisition in some + * implementations may not be possible, and if possible may be an + * expensive operation. The programmer should be aware that this + * may be the case. An implementation should document when this is + * the case. + * + * <p>An implementation can favor responding to an interrupt over + * normal method return. + * + * <p>A <tt>Lock</tt> implementation may be able to detect + * erroneous use of the lock, such as an invocation that would + * cause deadlock, and may throw an (unchecked) exception in such + * circumstances. The circumstances and the exception type must + * be documented by that <tt>Lock</tt> implementation. + * + * @throws InterruptedException if the current thread is interrupted + * while acquiring the lock (and interruption of lock acquisition is + * supported). + * + * @see Thread#interrupt + */ + void lockInterruptibly() throws InterruptedException; + + + /** + * Acquires the lock only if it is free at the time of invocation. + * <p>Acquires the lock if it is available and returns immediately + * with the value <tt>true</tt>. + * If the lock is not available then this method will return + * immediately with the value <tt>false</tt>. + * <p>A typical usage idiom for this method would be: + * <pre> + * Lock lock = ...; + * if (lock.tryLock()) { + * try { + * // manipulate protected state + * } finally { + * lock.unlock(); + * } + * } else { + * // perform alternative actions + * } + * </pre> + * This usage ensures that the lock is unlocked if it was acquired, and + * doesn't try to unlock if the lock was not acquired. + * + * @return <tt>true</tt> if the lock was acquired and <tt>false</tt> + * otherwise. + */ + boolean tryLock(); + + /** + * Releases the lock. + * <p><b>Implementation Considerations</b> + * <p>A <tt>Lock</tt> implementation will usually impose + * restrictions on which thread can release a lock (typically only the + * holder of the lock can release it) and may throw + * an (unchecked) exception if the restriction is violated. + * Any restrictions and the exception + * type must be documented by that <tt>Lock</tt> implementation. + */ + void unlock(); + +} Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/concurrent/locks/ReentrantLock.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/concurrent/locks/ReentrantLock.java 2006-04-27 05:25:16 UTC (rev 3990) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/concurrent/locks/ReentrantLock.java 2006-04-27 09:00:47 UTC (rev 3991) @@ -0,0 +1,466 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package org.drools.util.concurrent.locks; + +import java.util.Collection; + +/** + * This is a stripped down version of jdk1.5 ReentrantLock. + * All the condition and wait stuff has been removed + * + * @since 1.5 + * @author Doug Lea + * @author Dawid Kurzyniec + */ +public class ReentrantLock implements Lock, java.io.Serializable { + private static final long serialVersionUID = 7373984872572414699L; + + private final NonfairSync sync; + + final static class NonfairSync { + private static final long serialVersionUID = 7316153563782823691L; + + protected transient Thread owner_ = null; + protected transient int holds_ = 0; + + final void incHolds() { + int nextHolds = ++holds_; + if (nextHolds < 0) + throw new Error("Maximum lock count exceeded"); + holds_ = nextHolds; + } + + public boolean tryLock() { + Thread caller = Thread.currentThread(); + synchronized (this) { + if (owner_ == null) { + owner_ = caller; + holds_ = 1; + return true; + } + else if (caller == owner_) { + incHolds(); + return true; + } + } + return false; + } + + public synchronized int getHoldCount() { + return isHeldByCurrentThread() ? holds_ : 0; + } + + public synchronized boolean isHeldByCurrentThread() { + return holds_ > 0 && Thread.currentThread() == owner_; + } + + public synchronized boolean isLocked() { + return owner_ != null; + } + + protected synchronized Thread getOwner() { + return owner_; + } + + public boolean hasQueuedThreads() { + throw new UnsupportedOperationException("Use FAIR version"); + } + + public int getQueueLength() { + throw new UnsupportedOperationException("Use FAIR version"); + } + + public Collection getQueuedThreads() { + throw new UnsupportedOperationException("Use FAIR version"); + } + + public boolean isQueued(Thread thread) { + throw new UnsupportedOperationException("Use FAIR version"); + } + + public void lock() { + Thread caller = Thread.currentThread(); + synchronized (this) { + if (owner_ == null) { + owner_ = caller; + holds_ = 1; + return; + } + else if (caller == owner_) { + incHolds(); + return; + } + else { + boolean wasInterrupted = Thread.interrupted(); + try { + while (true) { + try { + wait(); + } + catch (InterruptedException e) { + wasInterrupted = true; + // no need to notify; if we were signalled, we + // will act as signalled, ignoring the + // interruption + } + if (owner_ == null) { + owner_ = caller; + holds_ = 1; + return; + } + } + } + finally { + if (wasInterrupted) Thread.currentThread().interrupt(); + } + } + } + } + + public void lockInterruptibly() throws InterruptedException { + if (Thread.interrupted()) throw new InterruptedException(); + Thread caller = Thread.currentThread(); + synchronized (this) { + if (owner_ == null) { + owner_ = caller; + holds_ = 1; + return; + } + else if (caller == owner_) { + incHolds(); + return; + } + else { + try { + do { wait(); } while (owner_ != null); + owner_ = caller; + holds_ = 1; + return; + } + catch (InterruptedException ex) { + if (owner_ == null) notify(); + throw ex; + } + } + } + } + + public synchronized void unlock() { + if (Thread.currentThread() != owner_) + throw new IllegalMonitorStateException("Not owner"); + + if (--holds_ == 0) { + owner_ = null; + notify(); + } + } + } + + /** + * Creates an instance of <tt>ReentrantLock</tt>. + * This is equivalent to using <tt>ReentrantLock(false)</tt>. + */ + public ReentrantLock() { + sync = new NonfairSync(); + } + + /** + * Acquires the lock. + * + * <p>Acquires the lock if it is not held by another thread and returns + * immediately, setting the lock hold count to one. + * + * <p>If the current thread + * already holds the lock then the hold count is incremented by one and + * the method returns immediately. + * + * <p>If the lock is held by another thread then the + * current thread becomes disabled for thread scheduling + * purposes and lies dormant until the lock has been acquired, + * at which time the lock hold count is set to one. + */ + public void lock() { + sync.lock(); + } + + /** + * Acquires the lock unless the current thread is + * {@link Thread#interrupt interrupted}. + * + * <p>Acquires the lock if it is not held by another thread and returns + * immediately, setting the lock hold count to one. + * + * <p>If the current thread already holds this lock then the hold count + * is incremented by one and the method returns immediately. + * + * <p>If the lock is held by another thread then the + * current thread becomes disabled for thread scheduling + * purposes and lies dormant until one of two things happens: + * + * <ul> + * + * <li>The lock is acquired by the current thread; or + * + * <li>Some other thread {@link Thread#interrupt interrupts} the current + * thread. + * + * </ul> + * + * <p>If the lock is acquired by the current thread then the lock hold + * count is set to one. + * + * <p>If the current thread: + * + * <ul> + * + * <li>has its interrupted status set on entry to this method; or + * + * <li>is {@link Thread#interrupt interrupted} while acquiring + * the lock, + * + * </ul> + * + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * <p>In this implementation, as this method is an explicit interruption + * point, preference is + * given to responding to the interrupt over normal or reentrant + * acquisition of the lock. + * + * @throws InterruptedException if the current thread is interrupted + */ + public void lockInterruptibly() throws InterruptedException { + sync.lockInterruptibly(); + } + + /** + * Acquires the lock only if it is not held by another thread at the time + * of invocation. + * + * <p>Acquires the lock if it is not held by another thread and + * returns immediately with the value <tt>true</tt>, setting the + * lock hold count to one. Even when this lock has been set to use a + * fair ordering policy, a call to <tt>tryLock()</tt> <em>will</em> + * immediately acquire the lock if it is available, whether or not + * other threads are currently waiting for the lock. + * This "barging" behavior can be useful in certain + * circumstances, even though it breaks fairness. If you want to honor + * the fairness setting for this lock, then use + * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) } + * which is almost equivalent (it also detects interruption). + * + * <p> If the current thread + * already holds this lock then the hold count is incremented by one and + * the method returns <tt>true</tt>. + * + * <p>If the lock is held by another thread then this method will return + * immediately with the value <tt>false</tt>. + * + * @return <tt>true</tt> if the lock was free and was acquired by the + * current thread, or the lock was already held by the current thread; and + * <tt>false</tt> otherwise. + */ + public boolean tryLock() { + return sync.tryLock(); + } + + + /** + * Attempts to release this lock. + * + * <p>If the current thread is the + * holder of this lock then the hold count is decremented. If the + * hold count is now zero then the lock is released. If the + * current thread is not the holder of this lock then {@link + * IllegalMonitorStateException} is thrown. + * @throws IllegalMonitorStateException if the current thread does not + * hold this lock. + */ + public void unlock() { + sync.unlock(); + } + + /** + * Queries the number of holds on this lock by the current thread. + * + * <p>A thread has a hold on a lock for each lock action that is not + * matched by an unlock action. + * + * <p>The hold count information is typically only used for testing and + * debugging purposes. For example, if a certain section of code should + * not be entered with the lock already held then we can assert that + * fact: + * + * <pre> + * class X { + * ReentrantLock lock = new ReentrantLock(); + * // ... + * public void m() { + * assert lock.getHoldCount() == 0; + * lock.lock(); + * try { + * // ... method body + * } finally { + * lock.unlock(); + * } + * } + * } + * </pre> + * + * @return the number of holds on this lock by the current thread, + * or zero if this lock is not held by the current thread. + */ + public int getHoldCount() { + return sync.getHoldCount(); + } + + /** + * Queries if this lock is held by the current thread. + * + * <p>Analogous to the {@link Thread#holdsLock} method for built-in + * monitor locks, this method is typically used for debugging and + * testing. For example, a method that should only be called while + * a lock is held can assert that this is the case: + * + * <pre> + * class X { + * ReentrantLock lock = new ReentrantLock(); + * // ... + * + * public void m() { + * assert lock.isHeldByCurrentThread(); + * // ... method body + * } + * } + * </pre> + * + * <p>It can also be used to ensure that a reentrant lock is used + * in a non-reentrant manner, for example: + * + * <pre> + * class X { + * ReentrantLock lock = new ReentrantLock(); + * // ... + * + * public void m() { + * assert !lock.isHeldByCurrentThread(); + * lock.lock(); + * try { + * // ... method body + * } finally { + * lock.unlock(); + * } + * } + * } + * </pre> + * @return <tt>true</tt> if current thread holds this lock and + * <tt>false</tt> otherwise. + */ + public boolean isHeldByCurrentThread() { + return sync.isHeldByCurrentThread(); + } + + /** + * Queries if this lock is held by any thread. This method is + * designed for use in monitoring of the system state, + * not for synchronization control. + * @return <tt>true</tt> if any thread holds this lock and + * <tt>false</tt> otherwise. + */ + public boolean isLocked() { + return sync.isLocked(); + } + + /** + * <tt>null</tt> if not owned. When this method is called by a + * thread that is not the owner, the return value reflects a + * best-effort approximation of current lock status. For example, + * the owner may be momentarily <tt>null</tt> even if there are + * threads trying to acquire the lock but have not yet done so. + * This method is designed to facilitate construction of + * subclasses that provide more extensive lock monitoring + * facilities. + * + * @return the owner, or <tt>null</tt> if not owned + */ + protected Thread getOwner() { + return sync.getOwner(); + } + + /** + * Queries whether any threads are waiting to acquire this lock. Note that + * because cancellations may occur at any time, a <tt>true</tt> + * return does not guarantee that any other thread will ever + * acquire this lock. This method is designed primarily for use in + * monitoring of the system state. + * + * @return true if there may be other threads waiting to acquire + * the lock. + */ + public final boolean hasQueuedThreads() { + return sync.hasQueuedThreads(); + } + + + /** + * Queries whether the given thread is waiting to acquire this + * lock. Note that because cancellations may occur at any time, a + * <tt>true</tt> return does not guarantee that this thread + * will ever acquire this lock. This method is designed primarily for use + * in monitoring of the system state. + * + * @param thread the thread + * @return true if the given thread is queued waiting for this lock. + * @throws NullPointerException if thread is null + */ + public final boolean hasQueuedThread(Thread thread) { + return sync.isQueued(thread); + } + + + /** + * Returns an estimate of the number of threads waiting to + * acquire this lock. The value is only an estimate because the number of + * threads may change dynamically while this method traverses + * internal data structures. This method is designed for use in + * monitoring of the system state, not for synchronization + * control. + * @return the estimated number of threads waiting for this lock + */ + public final int getQueueLength() { + return sync.getQueueLength(); + } + + /** + * Returns a collection containing threads that may be waiting to + * acquire this lock. Because the actual set of threads may change + * dynamically while constructing this result, the returned + * collection is only a best-effort estimate. The elements of the + * returned collection are in no particular order. This method is + * designed to facilitate construction of subclasses that provide + * more extensive monitoring facilities. + * @return the collection of threads + */ + protected Collection getQueuedThreads() { + return sync.getQueuedThreads(); + } + + /** + * Returns a string identifying this lock, as well as its lock + * state. The state, in brackets, includes either the String + * "Unlocked" or the String "Locked by" + * followed by the {@link Thread#getName} of the owning thread. + * @return a string identifying this lock, as well as its lock state. + */ + public String toString() { + Thread o = getOwner(); + return super.toString() + ((o == null) ? + "[Unlocked]" : + "[Locked by thread " + o.getName() + "]"); + } +} |
From: <jbo...@li...> - 2006-04-27 05:25:22
|
Author: mic...@jb... Date: 2006-04-27 01:25:16 -0400 (Thu, 27 Apr 2006) New Revision: 3990 Modified: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ActionType.java Log: improved comments Modified: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ActionType.java =================================================================== --- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ActionType.java 2006-04-27 05:15:52 UTC (rev 3989) +++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/parser/ActionType.java 2006-04-27 05:25:16 UTC (rev 3990) @@ -25,7 +25,9 @@ import org.drools.decisiontable.model.SnippetBuilder; /** - * Simple holder class identifying a condition or action column. + * Simple holder class identifying a condition or action column etc. + * This is stored in a map in the main listener class, to track what type of values + * you can expect to see in the rows directly below. * * There are five types of columns relevant to a rule table. * @author <a href="mailto:Mic...@gm..."> Michael Neale</a> |
Author: mic...@jb... Date: 2006-04-27 01:15:52 -0400 (Thu, 27 Apr 2006) New Revision: 3989 Removed: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/model/DRLElementTest.java Modified: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/model/DRLElement.java Log: removed unneeded code Modified: labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/model/DRLElement.java =================================================================== --- labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/model/DRLElement.java 2006-04-27 03:39:28 UTC (rev 3988) +++ labs/jbossrules/trunk/drools-decisiontables/src/main/java/org/drools/decisiontable/model/DRLElement.java 2006-04-27 05:15:52 UTC (rev 3989) @@ -15,15 +15,6 @@ * limitations under the License. */ - - - - - - - -import java.text.StringCharacterIterator; - /** * @author <a href="mailto:mic...@gm..."> Michael Neale </a> * @@ -48,51 +39,6 @@ return (_comment != null && !("".equals(_comment))); } - /** - * This escapes plain snippets into an xml/drl safe format. - * - * @param snippet - * @return An escaped DRL safe string. - */ - static String escapeSnippet(String snippet) - { - if ( snippet != null ) - { - final StringBuffer result = new StringBuffer( ); - final StringCharacterIterator iterator = new StringCharacterIterator( snippet ); - char character = iterator.current( ); - while ( character != StringCharacterIterator.DONE ) - { - if ( character == '<' ) - { - result.append( "<" ); - } - else if ( character == '>' ) - { - result.append( ">" ); - } // What else really needs to be escaped? SAX parsers are - // inconsistent here... - /* - * else if (character == '\"') { result.append("""); } else - * if (character == '\'') { result.append("'"); } else if - * (character == '\\') { result.append("\"); } - */ - else if ( character == '&' ) - { - result.append( "&" ); - } - else - { - // the char is not a special one - // add it to the result as is - result.append( character ); - } - character = iterator.next( ); - } - return result.toString( ); - } - return null; - } } \ No newline at end of file Deleted: labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/model/DRLElementTest.java =================================================================== --- labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/model/DRLElementTest.java 2006-04-27 03:39:28 UTC (rev 3988) +++ labs/jbossrules/trunk/drools-decisiontables/src/test/java/org/drools/decisiontable/model/DRLElementTest.java 2006-04-27 05:15:52 UTC (rev 3989) @@ -1,48 +0,0 @@ -package org.drools.decisiontable.model; -/* - * Copyright 2005 JBoss Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - - - - - - - -import junit.framework.TestCase; - -/** - * @author <a href="mailto:mic...@gm..."> Michael Neale</a> - * - * - */ -public class DRLElementTest extends TestCase -{ - - public void testEscaping() - { - assertNotNull( "this test is not needed, as using CDATA now" ); - String snippet = "user.getAge() >= 20 && user.getAge() <= 31"; - String result = DRLElement.escapeSnippet( snippet ); - assertEquals( "user.getAge() >= 20 && user.getAge() <= 31", - result ); - - snippet = "nothing"; - assertEquals( snippet, - DRLElement.escapeSnippet( snippet ) ); - } - -} \ No newline at end of file |
From: <jbo...@li...> - 2006-04-27 03:39:33
|
Author: mic...@jb... Date: 2006-04-26 23:39:28 -0400 (Wed, 26 Apr 2006) New Revision: 3988 Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Agenda.xml Log: Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Agenda.xml =================================================================== --- labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Agenda.xml 2006-04-27 03:37:13 UTC (rev 3987) +++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Agenda.xml 2006-04-27 03:39:28 UTC (rev 3988) @@ -2,7 +2,8 @@ <section> <title>Agenda</title> - <para>uuuere</para> + <para>The agenda is a RETE feature. It is an area where rules + matching + facts are kept before they are fired.</para> <section> <title>Conflict Resultion</title> |
From: <jbo...@li...> - 2006-04-27 03:37:21
|
Author: mic...@jb... Date: 2006-04-26 23:37:13 -0400 (Wed, 26 Apr 2006) New Revision: 3987 Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Working_Memory.xml Log: Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Working_Memory.xml =================================================================== --- labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Working_Memory.xml 2006-04-27 03:22:58 UTC (rev 3986) +++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Working_Memory.xml 2006-04-27 03:37:13 UTC (rev 3987) @@ -1,51 +1,104 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <section> <title>WorkingMemory</title> - <para>uuuere</para> + <para>The working memory is basically the rule engine, with all the rules + loaded, ready to go. It holds references to all data that has been + "asserted" into it (until retracted) and it the place where the interaction + with your application occurs. Working memories are stateful objects. They + may be shortlived, or longlived. If you are interacting with an engine in a + stateless manner, that means you would use the RuleBase object to create a + newWorkingMemory for each session, and then discard the working memory when + finished (creating a working memory is a cheap operation). An alternative + pattern is a working memory that is kept around for a longer time (such as a + conversation) - and kept updated with new facts.</para> <section> <title>Facts</title> - <para></para> + <para>Facts are objects (beans) from your application that you assert into + the working memory. Facts are any java objects which the rules can access. + The rule engine does not "clone" facts at all, it is all + references/pointers at the end of the day. Facts are your applications + data.</para> </section> <section> <title>Assertion</title> - <para></para> + <para>"Assertion" is the act of telling the working memory about the + facts. WorkingMemory.assertObject(yourObject) for example. When you assert + a fact, it is examined for matches against the rules etc. However, no + actions are taken until you call "fireAllRules()" after you have finished + asserting your facts.</para> </section> <section> <title>Retraction</title> - <para></para> + <para>Basically the reverse of Asserting. When you retract a fact, the + working memory will no longer track that fact, and any rules that were + dependent on that fact will not be activated. Note that it is possible to + have rules that depend on the "non existence" of fact, in which case + retracting a fact may cause a rule to activate. </para> </section> <section> <title>Modification</title> - <para></para> + <para>If the rule engine has to know when a fact has changed, as rules + that depend on that fact may have to be triggered again. You modify a fact + to tell the rule engine that its state has changed.</para> </section> <section> <title>Globals</title> - <para></para> + <para>Globals are a named objects that can be passed in to the rule + engine. Most often these are used for static information, or services that + are used in the RHS of a rule, or perhaps a means to return objects from + the rule engine.</para> </section> <section> <title>Property Change Listener</title> - <para></para> + <para>If your fact objects are java beans, you can implement a property + change listener for them, and then tell the rule engine about it. This + means that the engine will automatically know when a fact has changed, and + behave accordingly (you don't need to tell it that it is modified). There + are proxy libraries that can help automate this (a future version of + drools will bundle some to make it easier).</para> </section> <section> <title>Shadow Facts</title> - <para>A shadow fact is a shallow copy of an asserted object. Shadow facts are cached copies of object asserted to the working memory. The term shadow facts is commonly known as a feature of JESS (Java Expert System Shell).</para> - <para>The origins of shadow facts traces back to the concept of truth maintenance. The basic idea is that an expert system should gaurantee the derived conclusions are accurate. A running system may alter a fact during evaluation. When this occurs, the rule engine must know a modification occurred and handle the change appropriately. There's generally two ways to gaurantee truthfullness. The first is to lock all the facts during the inference process. The second is to make a cache copy of an object and force all modifications to go through the rule engine. This way, the changes are processed in an orderly fashion. Shadow facts are particularly important in multi-threaded environments, where an engine is shared by multiple sessions. Without truth maintenance, a system has a difficult time proving the results are accurate. The primary benefit of shadow facts is it makes development easier. When developers are forced to keep track of fact modifications, it can lead to erro! rs, which are difficult to debug. Building a moderately complex system using a rule engine is hard enough without adding the burden of tracking changes to facts and when they should notify the rule engine.</para> - <para>As of Drools 3.0, shadow facts hasn't been implemented, but it is planned for the future.</para> + <para>A shadow fact is a shallow copy of an asserted object. Shadow facts + are cached copies of object asserted to the working memory. The term + shadow facts is commonly known as a feature of JESS (Java Expert System + Shell).</para> + + <para>The origins of shadow facts traces back to the concept of truth + maintenance. The basic idea is that an expert system should gaurantee the + derived conclusions are accurate. A running system may alter a fact during + evaluation. When this occurs, the rule engine must know a modification + occurred and handle the change appropriately. There's generally two ways + to gaurantee truthfullness. The first is to lock all the facts during the + inference process. The second is to make a cache copy of an object and + force all modifications to go through the rule engine. This way, the + changes are processed in an orderly fashion. Shadow facts are particularly + important in multi-threaded environments, where an engine is shared by + multiple sessions. Without truth maintenance, a system has a difficult + time proving the results are accurate. The primary benefit of shadow facts + is it makes development easier. When developers are forced to keep track + of fact modifications, it can lead to errors, which are difficult to + debug. Building a moderately complex system using a rule engine is hard + enough without adding the burden of tracking changes to facts and when + they should notify the rule engine.</para> + + <para>As of Drools 3.0, shadow facts hasn't been implemented, but it is + planned for the future.</para> </section> <section> |
Author: bagerman Date: 2006-04-26 23:22:58 -0400 (Wed, 26 Apr 2006) New Revision: 3986 Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/LeapsTest.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/ColumnConstraints.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactHandleImpl.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsAgenda.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsTuple.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/Token.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/WorkingMemoryImpl.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/leaps/LogicalAssertionTest.java Log: logical assertion for leaps Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/LeapsTest.java =================================================================== --- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/LeapsTest.java 2006-04-27 03:19:05 UTC (rev 3985) +++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/LeapsTest.java 2006-04-27 03:22:58 UTC (rev 3986) @@ -119,36 +119,16 @@ assertEquals("group2", list.get(3)); } - public void testLogicalAssertions() throws Exception { - // Not working in leaps - } - - public void testLogicalAssertionsBacking() throws Exception { - // Not working in leaps - } - - public void testLogicalAssertionsSelfreferencing() throws Exception { - // Not working in leaps - } - - public void testLogicalAssertionsLoop() throws Exception { - // Not working in leaps - } - - public void testLogicalAssertionsNoLoop() throws Exception { - // Not working in leaps - } - + // the problem here is that rete does conflict resolution after all + // activations + // are generated and takes rules salience as a first sorting criteria + // and only then uses fact recency while leaps uses fact recency (and other + // possible + // criteria) first and rule based after public void testLogicalAssertions2() throws Exception { // Not working in leaps } - - public void testLogicalAssertionsNot() throws Exception { - // Not working in leaps - } - - public void testLogicalAssertionsNotPingPong() throws Exception { - // Not working in leaps - } -} \ No newline at end of file + public void testEmptyColumn() throws Exception { + } +} Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java 2006-04-27 03:19:05 UTC (rev 3985) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java 2006-04-27 03:22:58 UTC (rev 3986) @@ -24,7 +24,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -74,12 +73,6 @@ /** The arguments used when adding/removing a property change listener. */ protected final Object[] addRemovePropertyChangeListenerArgs = new Object[]{this}; - /** The actual memory for the <code>JoinNode</code>s. */ - private final PrimitiveLongMap nodeMemories = new PrimitiveLongMap( 32, - 8 ); - /** Handle-to-object mapping. */ - protected final PrimitiveLongMap objects = new PrimitiveLongMap( 32, - 8 ); /** Global values which are associated with this memory. */ private final Map globals = new HashMap(); @@ -92,6 +85,10 @@ private final PrimitiveLongStack factHandlePool = new PrimitiveLongStack(); protected static final String STATED = "STATED"; + protected static final String JUSTIFIED = "JUSTIFIED"; + protected static final String NEW = "NEW"; + protected static final FactStatus STATUS_NEW = new FactStatus( NEW, + 0 ); /** The eventSupport */ protected final WorkingMemoryEventSupport workingMemoryEventSupport = new WorkingMemoryEventSupport( this ); @@ -227,12 +224,12 @@ * @see WorkingMemory */ public List getObjects() { - return new ArrayList( this.objects.values() ); + return new ArrayList( this.identityMap.keySet() ); } public List getObjects(Class objectClass) { - List matching = new LinkedList(); - for ( Iterator objIter = this.objects.values().iterator(); objIter.hasNext(); ) { + List matching = new java.util.LinkedList(); + for ( Iterator objIter = this.identityMap.keySet().iterator(); objIter.hasNext(); ) { Object obj = objIter.next(); if ( objectClass.isInstance( obj ) ) { @@ -392,24 +389,24 @@ set.add( node ); } - public void removeLogicalDependencies(Activation activation, + public void removeLogicalDependencies( Activation activation, PropagationContext context, - Rule rule) throws FactException { + Rule rule ) throws FactException { org.drools.util.LinkedList list = activation.getLogicalDependencies(); - if ( list == null || list.isEmpty() ) { + if (list == null || list.isEmpty( )) { return; } - for ( LogicalDependency node = (LogicalDependency) list.getFirst(); node != null; node = (LogicalDependency) node.getNext() ) { - InternalFactHandle handle = (InternalFactHandle) node.getFactHandle(); - Set set = (Set) this.justified.get( handle.getId() ); + for (LogicalDependency node = (LogicalDependency) list.getFirst( ); node != null; node = (LogicalDependency) node.getNext( )) { + InternalFactHandle handle = (InternalFactHandle) node.getFactHandle( ); + Set set = (Set) this.justified.get( handle.getId( ) ); set.remove( node ); - if ( set.isEmpty() ) { - this.justified.remove( handle.getId() ); + if (set.isEmpty( )) { + this.justified.remove( handle.getId( ) ); retractObject( handle, false, true, - context.getRuleOrigin(), - context.getActivationOrigin() ); + context.getRuleOrigin( ), + context.getActivationOrigin( ) ); } } } @@ -423,4 +420,87 @@ } } } + + protected static class FactStatus { + private int counter; + private String status; + private InternalFactHandle handle; + + public FactStatus() { + this( AbstractWorkingMemory.STATED, + 1 ); + } + + public FactStatus(String status) { + this( status, + 1 ); + } + + public FactStatus(String status, + InternalFactHandle handle) { + this.status = status; + this.handle = handle; + } + + public FactStatus(String status, + int counter) { + this.status = status; + this.counter = counter; + } + + /** + * @return the counter + */ + public int getCounter() { + return counter; + } + + /** + * @param counter the counter to set + */ + public void setCounter(int counter) { + this.counter = counter; + } + + public int incCounter() { + return ++counter; + } + + public int decCounter() { + return --counter; + } + + /** + * @return the handle + */ + public InternalFactHandle getHandle() { + return handle; + } + + /** + * @param handle the handle to set + */ + public void setHandle(InternalFactHandle handle) { + this.handle = handle; + } + + /** + * @return the status + */ + public String getStatus() { + return status; + } + + /** + * @param status the status to set + */ + public void setStatus(String status) { + this.status = status; + } + + public String toString() { + return "FactStatus( " + this.status + ", handle=" + this.handle + ", counter=" + this.counter + ")"; + } + } } + Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/ColumnConstraints.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/ColumnConstraints.java 2006-04-27 03:19:05 UTC (rev 3985) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/ColumnConstraints.java 2006-04-27 03:22:58 UTC (rev 3986) @@ -17,7 +17,6 @@ import java.util.List; -import org.drools.FactHandle; import org.drools.WorkingMemory; import org.drools.base.ClassObjectType; import org.drools.common.BetaNodeBinder; @@ -64,11 +63,11 @@ } } - public Class getClassType() { + protected final Class getClassType() { return this.classType; } - boolean isAllowed(InternalFactHandle factHandle, + protected final boolean isAllowed(InternalFactHandle factHandle, Tuple tuple, WorkingMemory workingMemory) { return this.isAllowedAlpha( factHandle, @@ -78,7 +77,7 @@ workingMemory ); } - public boolean isAllowedAlpha(InternalFactHandle factHandle, + public final boolean isAllowedAlpha(InternalFactHandle factHandle, Tuple tuple, WorkingMemory workingMemory) { if ( this.alphaPresent ) { @@ -95,7 +94,7 @@ return true; } - boolean isAllowedBeta(InternalFactHandle factHandle, + protected final boolean isAllowedBeta(InternalFactHandle factHandle, Tuple tuple, WorkingMemory workingMemory) { if ( this.betaPresent ) { @@ -107,8 +106,8 @@ return true; } - protected boolean isAlphaPresent() { + protected final boolean isAlphaPresent() { return alphaPresent; } -} \ No newline at end of file +} Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactHandleImpl.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactHandleImpl.java 2006-04-27 03:19:05 UTC (rev 3985) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactHandleImpl.java 2006-04-27 03:22:58 UTC (rev 3986) @@ -39,12 +39,6 @@ private List existsTuples = null; - private Set logicalJustifiers = null; - - private boolean logicalyDependent = false; - - private int dependencyCount = 0; - /** * actual object that is asserted to the system no getters just a direct * access to speed things up @@ -55,14 +49,14 @@ object ); } - void addActivatedTuple(LeapsTuple tuple) { + protected final void addActivatedTuple(LeapsTuple tuple) { if ( this.activatedTuples == null ) { this.activatedTuples = new HashSet(); } this.activatedTuples.add( tuple ); } - void addNotTuple(LeapsTuple tuple, + protected final void addNotTuple(LeapsTuple tuple, int index) { if ( this.notTuples == null ) { this.notTuples = new LinkedList(); @@ -71,7 +65,7 @@ index ) ); } - void addExistsTuple(LeapsTuple tuple, + protected final void addExistsTuple(LeapsTuple tuple, int index) { if ( this.existsTuples == null ) { this.existsTuples = new LinkedList(); @@ -80,59 +74,27 @@ index ) ); } - Iterator getActivatedTuples() { + protected final Iterator getActivatedTuples() { if ( this.activatedTuples != null ) { return this.activatedTuples.iterator(); } return null; } - Iterator getNotTupleAssemblies() { + protected final Iterator getNotTupleAssemblies() { if ( this.notTuples != null ) { return this.notTuples.iterator(); } return null; } - Iterator getExistsTupleAssemblies() { + protected final Iterator getExistsTupleAssemblies() { if ( this.existsTuples != null ) { return this.existsTuples.iterator(); } return null; } - void addLogicalDependency(LeapsTuple tuple) { - if ( this.logicalJustifiers == null ) { - this.logicalyDependent = true; - this.logicalJustifiers = new HashSet(); - } - this.logicalJustifiers.add( tuple ); - - this.dependencyCount++; - } - - void removeLogicalDependency(LeapsTuple tuple) { - if ( this.dependencyCount > 0 ) { - this.logicalJustifiers.remove( tuple ); - } - this.dependencyCount--; - } - - void removeAllLogicalDependencies() { - if ( this.dependencyCount > 0 ) { - for ( Iterator it = this.logicalJustifiers.iterator(); it.hasNext(); ) { - this.removeLogicalDependency( (LeapsTuple) it.next() ); - } - } - } - - boolean isLogicalyValid() { - if ( this.logicalyDependent ) { - return this.dependencyCount != 0; - } - return true; - } - /** * @see FactHandle */ @@ -146,4 +108,4 @@ public String toString() { return toExternalForm(); } -} \ No newline at end of file +} Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsAgenda.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsAgenda.java 2006-04-27 03:19:05 UTC (rev 3985) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsAgenda.java 2006-04-27 03:22:58 UTC (rev 3986) @@ -45,15 +45,8 @@ this.workingMemory.addToQueryResults( activation.getRule().getName(), activation.getTuple() ); } else { - // remove tuple from fact tables, we do it first so assert and retract - // in rule does not touch this tuple - LeapsTuple tuple = (LeapsTuple) activation.getTuple(); - Class[] classes = tuple.getLeapsRule().getExistsNotColumnsClasses(); - for ( int i = 0, length = classes.length; i < length; i++ ) { - workingMemory.getFactTable( classes[i] ).removeTuple( tuple ); - } // fire regular rule super.fireActivation( activation ); } } -} \ No newline at end of file +} Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsTuple.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsTuple.java 2006-04-27 03:19:05 UTC (rev 3985) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsTuple.java 2006-04-27 03:22:58 UTC (rev 3986) @@ -17,29 +17,25 @@ */ import java.io.Serializable; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; import org.drools.FactHandle; import org.drools.common.InternalFactHandle; +import org.drools.common.LogicalDependency; import org.drools.rule.Declaration; import org.drools.spi.Activation; import org.drools.spi.PropagationContext; import org.drools.spi.Tuple; +import org.drools.util.LinkedList; /** * Leaps Tuple implementation * * @author Alexander Bagerman */ -class LeapsTuple - implements - Tuple, - Serializable { +class LeapsTuple implements Tuple, Serializable { private static final long serialVersionUID = 1L; - private final PropagationContext context; + private PropagationContext context; private boolean readyForActivation; @@ -49,12 +45,12 @@ private FactHandleImpl[] existsFactHandles = null; - private Set logicalDependencies; - private Activation activation; private final LeapsRule leapsRule; + private LinkedList justified; + /** * agendaItem parts */ @@ -273,17 +269,19 @@ return this.context; } - void addLogicalDependency(FactHandle handle) { - if ( this.logicalDependencies == null ) { - this.logicalDependencies = new HashSet(); + public void addLogicalDependency(LogicalDependency node) { + if ( this.justified == null ) { + this.justified = new LinkedList(); } - this.logicalDependencies.add( handle ); + + this.justified.add( node ); } - Iterator getLogicalDependencies() { - if ( this.logicalDependencies != null ) { - return this.logicalDependencies.iterator(); - } - return null; + public LinkedList getLogicalDependencies() { + return this.justified; } -} \ No newline at end of file + + protected void setContext( PropagationContext context ) { + this.context = context; + } +} Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/Token.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/Token.java 2006-04-27 03:19:05 UTC (rev 3985) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/Token.java 2006-04-27 03:22:58 UTC (rev 3986) @@ -72,9 +72,6 @@ this.rules = this.workingMemory.getFactTable( this.dominantFactHandle.getObject().getClass()).getRulesIterator(); } - else { - this.rules = this.workingMemory.getNoRequiredColumnsLeapsRules(); - } } return this.rules; } @@ -258,4 +255,4 @@ public PropagationContextImpl getPropagationContext() { return propagationContext; } -} \ No newline at end of file +} Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/WorkingMemoryImpl.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/WorkingMemoryImpl.java 2006-04-27 03:19:05 UTC (rev 3985) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/WorkingMemoryImpl.java 2006-04-27 03:22:58 UTC (rev 3986) @@ -28,6 +28,7 @@ import org.drools.FactException; import org.drools.FactHandle; +import org.drools.NoSuchFactObjectException; import org.drools.QueryResults; import org.drools.WorkingMemory; import org.drools.common.AbstractWorkingMemory; @@ -38,7 +39,6 @@ import org.drools.common.PropagationContextImpl; import org.drools.common.ScheduledAgendaItem; import org.drools.leaps.conflict.DefaultConflictResolver; -import org.drools.leaps.util.TableIterator; import org.drools.leaps.util.TokenStack; import org.drools.rule.Query; import org.drools.rule.Rule; @@ -73,9 +73,6 @@ private final Map queryResults; - // rules consisting only of not and exists - private final RuleTable noRequiredColumnsLeapsRules = new RuleTable( DefaultConflictResolver.getInstance().getRuleConflictResolver() ); - private final IdentityMap leapsRulesToHandlesMap = new IdentityMap(); /** @@ -144,7 +141,7 @@ public List getObjects(Class objectClass) { List list = new LinkedList(); for ( Iterator it = this.getFactTable( objectClass ).iterator(); it.hasNext(); ) { - list.add( it.next() ); + list.add( ((FactHandleImpl)it.next()).getObject() ); } return list; @@ -210,33 +207,47 @@ * * @see WorkingMemory */ - public FactHandle assertObject(Object object, + public FactHandle assertObject( Object object, boolean dynamic, boolean logical, Rule rule, - Activation activation) throws FactException { + Activation activation ) throws FactException { + // check if the object already exists in the WM FactHandleImpl handle = (FactHandleImpl) this.identityMap.get( object ); - // return if the handle exists and this is a logical assertion - if ( (handle != null) && (logical) ) { - return handle; + // lets see if the object is already logical asserted + FactStatus logicalState = (FactStatus) this.equalsMap.get( object ); + if (logicalState == null) { + logicalState = STATUS_NEW; } - // lets see if the object is already logical asserted - Object logicalState = this.equalsMap.get( object ); + // This object is already STATED, we cannot make it justifieable + if (( logical ) && ( logicalState.getStatus( ) == WorkingMemoryImpl.STATED )) { + return null; + } + // return if there is already a logical handle + if (( logical ) && ( logicalState.getStatus( ) == WorkingMemoryImpl.JUSTIFIED )) { + addLogicalDependency( logicalState.getHandle( ), + activation, + activation.getPropagationContext( ), + rule ); + return logicalState.getHandle( ); + } + // if we have a handle and this STATED fact was previously STATED - if ( (handle != null) && (!logical) && logicalState == AbstractWorkingMemory.STATED ) { + if ( (handle != null) && (!logical) && (logicalState.getStatus() == WorkingMemoryImpl.STATED) ) { return handle; } if ( !logical ) { // If this stated assertion already has justifications then we need // to cancel them - if ( logicalState instanceof FactHandleImpl ) { - handle = (FactHandleImpl) logicalState; - handle.removeAllLogicalDependencies(); + if ( logicalState.getStatus() == WorkingMemoryImpl.JUSTIFIED ) { + handle = (FactHandleImpl)logicalState.getHandle(); + + removeLogicalDependencies( handle ); } else { handle = (FactHandleImpl) newFactHandle( object ); } @@ -244,19 +255,22 @@ putObject( handle, object ); - this.equalsMap.put( object, - AbstractWorkingMemory.STATED ); + if ( logicalState != WorkingMemoryImpl.STATUS_NEW ) { + // make sure status is stated + logicalState.setStatus( WorkingMemoryImpl.STATED ); + logicalState.incCounter(); + } else { + this.equalsMap.put( object, + new FactStatus( WorkingMemoryImpl.STATED, + 1 ) ); + } if ( dynamic ) { addPropertyChangeListener( object ); } + } else { - // This object is already STATED, we cannot make it justifieable - if ( logicalState == AbstractWorkingMemory.STATED ) { - return null; - } - - handle = (FactHandleImpl) logicalState; + handle = (FactHandleImpl)logicalState.getHandle(); // we create a lookup handle for the first asserted equals object // all future equals objects will use that handle if ( handle == null ) { @@ -266,15 +280,28 @@ object ); this.equalsMap.put( object, - handle ); + new FactStatus( WorkingMemoryImpl.JUSTIFIED, + handle ) ); } + + + addLogicalDependency( handle, + activation, + activation.getPropagationContext(), + rule ); - // adding logical dependency - LeapsTuple tuple = (LeapsTuple) activation.getTuple(); - tuple.addLogicalDependency( handle ); - handle.addLogicalDependency( tuple ); } + // new leaps stack token + PropagationContextImpl context = new PropagationContextImpl( nextPropagationIdCounter(), + PropagationContext.ASSERTION, + rule, + activation ); + + this.pushTokenOnStack( handle, new Token( this, handle, context ) ); + + this.workingMemoryEventSupport.fireObjectAsserted( context, handle, object ); + // determine what classes it belongs to put it into the "table" on // class name key Class objectClass = object.getClass(); @@ -284,28 +311,33 @@ factTable.add( handle ); // inspect all tuples for exists and not conditions and activate / // deactivate agenda items - for ( Iterator tuples = factTable.getTuplesIterator(); tuples.hasNext(); ) { - LeapsTuple tuple = (LeapsTuple) tuples.next(); - if ( !tuple.isActivationNull() ) { + for (Iterator tuples = factTable.getTuplesIterator( ); tuples.hasNext( );) { + LeapsTuple tuple = (LeapsTuple) tuples.next( ); + boolean tupleWasReadyForActivation = tuple.isReadyForActivation( ); + if (!tuple.isActivationNull( )) { // check not constraints only on activated tuples to see if // we need to deactivate - ColumnConstraints[] not = tuple.getLeapsRule().getNotColumnConstraints(); - for ( int i = 0, length = not.length; i < length; i++ ) { + ColumnConstraints[] not = tuple.getLeapsRule( ) + .getNotColumnConstraints( ); + for (int i = 0, length = not.length; i < length; i++) { ColumnConstraints constraint = not[i]; - if (!tuple.isBlockingNotFactHandle(i) - && constraint.getClassType().isAssignableFrom( objectClass ) - && constraint.isAllowed(handle, tuple, this)) { - tuple.setBlockingNotFactHandle(handle, i); - handle.addNotTuple(tuple, i); + if (!tuple.isBlockingNotFactHandle( i ) + && constraint.getClassType( ) + .isAssignableFrom( objectClass ) + && constraint.isAllowed( handle, tuple, this )) { + tuple.setBlockingNotFactHandle( handle, i ); + handle.addNotTuple( tuple, i ); } } // check and see if we need de-activate - if ( !tuple.isReadyForActivation() ) { - if ( tuple.getLeapsRule().getRule() instanceof Query ) { + if (!tuple.isReadyForActivation( )) { + if (tuple.getLeapsRule( ).getRule( ) instanceof Query) { // put query results to the working memory location - removeFromQueryResults( tuple.getLeapsRule().getRule().getName(), - tuple ); - } else { + removeFromQueryResults( tuple.getLeapsRule( ) + .getRule( ) + .getName( ), tuple ); + } + else { // time to pull from agenda invalidateActivation( tuple ); } @@ -325,28 +357,21 @@ } } // check and see if we need activate - if (tuple.isReadyForActivation()) { + // activate only if tuple was not ready for it before + if (tuple.isReadyForActivation() && !tupleWasReadyForActivation) { // ready to activate + tuple.setContext( new PropagationContextImpl( nextPropagationIdCounter( ), + PropagationContext.ASSERTION, + tuple.getLeapsRule( ) + .getRule( ), + null ) ); + this.assertTuple(tuple); } } } } - // new leaps stack token - PropagationContextImpl context = new PropagationContextImpl( nextPropagationIdCounter(), - PropagationContext.ASSERTION, - rule, - activation ); - - this.pushTokenOnStack( handle, new Token( this, - handle, - context ) ); - - this.workingMemoryEventSupport.fireObjectAsserted( context, - handle, - object ); - return handle; } @@ -358,26 +383,25 @@ * @param object * The object. */ - Object putObject(FactHandle handle, + void putObject(FactHandle handle, Object object) { this.identityMap.put( object, handle ); - - return this.objects.put( ((FactHandleImpl) handle).getId(), - object ); - } Object removeObject(FactHandle handle) { this.identityMap.remove( ((FactHandleImpl) handle).getObject() ); - return this.objects.remove( ((FactHandleImpl) handle).getId() ); - + return ((FactHandleImpl) handle).getObject(); } /** + * copies reteoo behaviour in regards to logical assertion + * and does checking on available tuples to see if any needs + * invalidation / activation as a result of this retraction + * * @see WorkingMemory */ public void retractObject(FactHandle handle, @@ -387,6 +411,26 @@ Activation activation) throws FactException { // removePropertyChangeListener( handle ); + // + // end leaps specific actions + // + Object oldObject = removeObject( handle ); + + /* check to see if this was a logical asserted object */ + if ( removeLogical ) { + removeLogicalDependencies( handle ); + } + + if ( removeLogical || updateEqualsMap ) { + FactStatus status = (FactStatus) this.equalsMap.get( oldObject ); + if ( status != null ) { + status.decCounter(); + if ( status.getCounter() <= 0 ) { + this.equalsMap.remove( oldObject ); + } + } + } + /* * leaps specific actions */ @@ -410,6 +454,7 @@ } // 1. remove fact for nots and exists tuples + IdentityMap tuplesNotReadyForActivation = new IdentityMap(); FactHandleTupleAssembly assembly; LeapsTuple tuple; Iterator it; @@ -418,6 +463,9 @@ for ( ; it.hasNext(); ) { assembly = (FactHandleTupleAssembly) it.next(); tuple = assembly.getTuple(); + if(!tuple.isReadyForActivation()) { + tuplesNotReadyForActivation.put(tuple, tuple); + } tuple.removeBlockingNotFactHandle(assembly.getIndex()); TokenEvaluator.evaluateNotCondition(new FactHandleImpl( ((FactHandleImpl) handle).getId() + 1, null), assembly.getIndex(), @@ -429,6 +477,9 @@ for ( ; it.hasNext(); ) { assembly = (FactHandleTupleAssembly) it.next(); tuple = assembly.getTuple(); + if(!tuple.isReadyForActivation()) { + tuplesNotReadyForActivation.put(tuple, tuple); + } tuple.removeExistsFactHandle(assembly.getIndex()); TokenEvaluator.evaluateExistsCondition(new FactHandleImpl( ((FactHandleImpl) handle).getId() + 1, null), assembly.getIndex(), @@ -448,8 +499,16 @@ } for ( ; chain.hasNext(); ) { tuple = ((FactHandleTupleAssembly) chain.next()).getTuple(); - if ( tuple.isReadyForActivation() && tuple.isActivationNull() ) { + // can assert only tuples that were not eligible for activation + // before retraction + if ( tuple.isReadyForActivation() && tuple.isActivationNull() + && tuplesNotReadyForActivation.containsKey(tuple)) { // ready to activate + tuple.setContext( new PropagationContextImpl( nextPropagationIdCounter( ), + PropagationContext.ASSERTION, + tuple.getLeapsRule( ) + .getRule( ), + null ) ); this.assertTuple( tuple ); } else { if ( tuple.getLeapsRule().getRule() instanceof Query ) { @@ -466,21 +525,7 @@ // remove it from stack this.removeTokenFromStack( (FactHandleImpl) handle ); - // - // end leaps specific actions - // - Object oldObject = removeObject( handle ); - - /* check to see if this was a logical asserted object */ - if ( removeLogical ) { - this.equalsMap.remove( oldObject ); - } - - if ( updateEqualsMap ) { - this.equalsMap.remove( oldObject ); - } - - // not applicable to leaps implementation + // even support PropagationContextImpl context = new PropagationContextImpl( nextPropagationIdCounter(), PropagationContext.RETRACTION, rule, @@ -491,28 +536,28 @@ oldObject ); } - private void invalidateActivation(LeapsTuple tuple) { - if ( !tuple.isReadyForActivation() && !tuple.isActivationNull() ) { - Activation activation = tuple.getActivation(); + /** + * used when assertion / retraction adds invalidating conditions that + * make tuple ineligible for firing + * + * @param tuple + */ + private final void invalidateActivation( LeapsTuple tuple ) { + Activation activation = tuple.getActivation( ); + if (!tuple.isReadyForActivation( ) && !tuple.isActivationNull( )) { // invalidate agenda agendaItem - if ( activation.isActivated() ) { - activation.remove(); - getAgendaEventSupport().fireActivationCancelled( activation ); + if (activation.isActivated( )) { + activation.remove( ); + getAgendaEventSupport( ).fireActivationCancelled( activation ); } // tuple.setActivation( null ); } // remove logical dependency - FactHandleImpl factHandle; - Iterator it = tuple.getLogicalDependencies(); - if ( it != null ) { - for ( ; it.hasNext(); ) { - factHandle = (FactHandleImpl) it.next(); - factHandle.removeLogicalDependency( tuple ); - if ( !factHandle.isLogicalyValid() ) { - this.retractObject( factHandle ); - } - } + if (activation != null) { + this.removeLogicalDependencies( activation, + tuple.getContext( ), + tuple.getLeapsRule( ).getRule( ) ); } } @@ -526,22 +571,26 @@ this.retractObject( handle ); - this.assertObject( object, - false, - false, - rule, - activation ); + Object originalObject = removeObject( handle ); - /* - * this.ruleBase.modifyObject( handle, object, this ); - */ - this.workingMemoryEventSupport.fireObjectModified( new PropagationContextImpl( nextPropagationIdCounter(), - PropagationContext.MODIFICATION, - rule, - activation ), - handle, - ((FactHandleImpl) handle).getObject(), - object ); + if ( originalObject == null ) { + throw new NoSuchFactObjectException( handle ); + } + + /* check to see if this is a logically asserted object */ + FactHandleImpl handleImpl = (FactHandleImpl) this.assertObject( object, false, + false, rule, activation ); + + if ( this.justified.get( handleImpl.getId() ) != null ) { + this.equalsMap.remove( originalObject ); + this.equalsMap.put( object, + new FactStatus( WorkingMemoryImpl.JUSTIFIED, + handleImpl ) ); + } + + this.workingMemoryEventSupport.fireObjectModified( new PropagationContextImpl( + nextPropagationIdCounter( ), PropagationContext.MODIFICATION, rule, + activation ), handle, ( (FactHandleImpl) handle ).getObject( ), object ); } /** @@ -554,8 +603,7 @@ /** * algorithm stack. */ - private TokenStack mainStack = new TokenStack(); -// private Stack stack = new Stack(); + private final TokenStack mainStack = new TokenStack(); /** * to store facts to cursor over it @@ -568,7 +616,7 @@ * * @return */ - protected List getFactTablesList(Class c) { + protected final List getFactTablesList(Class c) { ArrayList list = new ArrayList(); // interfaces Class[] interfaces = c.getInterfaces(); @@ -592,7 +640,7 @@ * @param fact handle * @param token */ - protected void pushTokenOnStack(FactHandleImpl factHandle, Token token) { + protected final void pushTokenOnStack(FactHandleImpl factHandle, Token token) { this.mainStack.push( token ); } @@ -601,7 +649,7 @@ * * @param fact handle */ - protected void removeTokenFromStack(FactHandleImpl factHandle) { + protected final void removeTokenFromStack(FactHandleImpl factHandle) { this.mainStack.remove( factHandle.getId() ); } @@ -610,7 +658,7 @@ * * @param fact handle */ - protected Token peekTokenOnTop(){ + protected final Token peekTokenOnTop(){ return (Token)this.mainStack.peek(); } /** @@ -661,24 +709,24 @@ rule = (LeapsRule) it.next(); // some times rules do not have "normal" constraints and only // not and exists - if ( rule.getNumberOfColumns() > 0 ) { - ruleHandlesList = new ArrayList(); - for ( int i = 0; i < rule.getNumberOfColumns(); i++ ) { - ruleHandle = new RuleHandle( ((HandleFactory) this.handleFactory).getNextId(), + if (rule.getNumberOfColumns( ) > 0) { + ruleHandlesList = new ArrayList( ); + for (int i = 0; i < rule.getNumberOfColumns( ); i++) { + ruleHandle = new RuleHandle( ( (HandleFactory) this.handleFactory ).getNextId( ), rule, i ); // - this.getFactTable( rule.getColumnClassObjectTypeAtPosition( i ) ).addRule( this, - ruleHandle ); + this.getFactTable( rule.getColumnClassObjectTypeAtPosition( i ) ) + .addRule( this, ruleHandle ); // ruleHandlesList.add( ruleHandle ); } - this.leapsRulesToHandlesMap.put( rule, - ruleHandlesList ); - } else { + this.leapsRulesToHandlesMap.put( rule, ruleHandlesList ); + } + else { // to pick up rules that do not require columns, only not // and exists - PropagationContextImpl context = new PropagationContextImpl( nextPropagationIdCounter(), + PropagationContextImpl context = new PropagationContextImpl( nextPropagationIdCounter( ), PropagationContext.ASSERTION, null, null ); @@ -709,10 +757,7 @@ // this.getFactTable( rule.getColumnClassObjectTypeAtPosition( i ) ).removeRule( ruleHandle ); } - } else { - ruleHandle = (RuleHandle) this.leapsRulesToHandlesMap.remove( rule ); - this.noRequiredColumnsLeapsRules.remove( ruleHandle ); - } + } } } } @@ -721,75 +766,86 @@ * main loop * */ - public void fireAllRules(AgendaFilter agendaFilter) throws FactException { + public final synchronized void fireAllRules( AgendaFilter agendaFilter ) + throws FactException { // If we're already firing a rule, then it'll pick up // the firing for any other assertObject(..) that get // nested inside, avoiding concurrent-modification // exceptions, depending on code paths of the actions. - if ( !this.firing ) { + if (!this.firing) { try { this.firing = true; - // normal rules with required columns - while ( !this.mainStack.empty() ) { - Token token = (Token) this.peekTokenOnTop(); - boolean done = false; - while ( !done ) { - if ( !token.isResume() ) { - if ( token.hasNextRuleHandle() ) { - token.nextRuleHandle(); - } else { - // we do not pop because something might get - // asserted - // and placed on hte top of the stack during - // firing - this.removeTokenFromStack( token.getDominantFactHandle() ); - done = true; - } - } - if ( !done ) { - try { - // ok. now we have tuple, dominant fact and - // rules and ready to seek to checks if any - // agendaItem - // matches on current rule - TokenEvaluator.evaluate( token ); - // something was found so set marks for - // resume processing - if ( token.getDominantFactHandle() != null ) { - token.setResume( true ); + boolean nothingToProcess = false; + while (!nothingToProcess) { + // normal rules with required columns + while (!this.mainStack.empty( )) { + Token token = (Token) this.peekTokenOnTop( ); + boolean done = false; + while (!done) { + if (!token.isResume( )) { + if (token.hasNextRuleHandle( )) { + token.nextRuleHandle( ); + } + else { + // we do not pop because something might get + // asserted + // and placed on hte top of the stack during + // firing + this.removeTokenFromStack( token.getDominantFactHandle( ) ); done = true; } - } catch ( NoMatchesFoundException ex ) { - token.setResume( false ); } + if (!done) { + try { + // ok. now we have tuple, dominant fact and + // rules and ready to seek to checks if any + // agendaItem + // matches on current rule + TokenEvaluator.evaluate( token ); + // something was found so set marks for + // resume processing + if (token.getDominantFactHandle( ) != null) { + token.setResume( true ); + done = true; + } + } + catch (NoMatchesFoundException ex) { + token.setResume( false ); + } + } + // we put everything on agenda + // and if there is no modules or anything like it + // it would fire just activated rule + while (this.agenda.fireNextItem( agendaFilter )) { + ; + } } - // we put everything on agenda - // and if there is no modules or anything like it - // it would fire just activated rule - while ( this.agenda.fireNextItem( agendaFilter ) ) { - ; - } } + // pick activations generated by retraction or assert + // can generate activations off exists and not pending + // tuples + while (this.agenda.fireNextItem( agendaFilter )) { + ; + } + if (this.mainStack.empty( )) { + nothingToProcess = true; + } } - // pick activations generated by retraction or assert - // can generate activations off exists and not pending tuples - while ( this.agenda.fireNextItem( agendaFilter ) ) { - ; - } // mark when method was called last time - this.idLastFireAllAt = ((HandleFactory) this.handleFactory).getNextId(); + this.idLastFireAllAt = ( (HandleFactory) this.handleFactory ).getNextId( ); // set all factTables to be reseeded - for ( Enumeration e = this.factTables.elements(); e.hasMoreElements(); ) { - ((FactTable) e.nextElement()).setReseededStack( true ); + for (Enumeration e = this.factTables.elements( ); e.hasMoreElements( );) { + ( (FactTable) e.nextElement( ) ).setReseededStack( true ); } - } finally { + } + finally { this.firing = false; } } } - protected long getIdLastFireAllAt() { + protected final long getIdLastFireAllAt() { return this.idLastFireAllAt; } @@ -820,7 +876,7 @@ * @throws AssertionException * If an error occurs while asserting. */ - public void assertTuple(LeapsTuple tuple) { + public final void assertTuple(LeapsTuple tuple) { PropagationContext context = tuple.getContext(); Rule rule = tuple.getLeapsRule().getRule(); // if the current Rule is no-loop and the origin rule is the same then @@ -828,7 +884,7 @@ if ( rule.getNoLoop() && rule.equals( context.getRuleOrigin() ) ) { return; } - + // Duration dur = rule.getDuration(); Activation agendaItem; @@ -935,10 +991,6 @@ } } - protected TableIterator getNoRequiredColumnsLeapsRules() { - return noRequiredColumnsLeapsRules.iterator(); - } - public AgendaGroup getFocus() { return this.agenda.getFocus(); } @@ -955,4 +1007,4 @@ return this.agenda; } -} \ No newline at end of file +} Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/leaps/LogicalAssertionTest.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/leaps/LogicalAssertionTest.java 2006-04-27 03:19:05 UTC (rev 3985) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/leaps/LogicalAssertionTest.java 2006-04-27 03:22:58 UTC (rev 3986) @@ -187,30 +187,30 @@ // and return null assertNull( logicalHandle1 ); - // Alreyad identify same so return previously assigned handle - logicalHandle1 = this.workingMemory.assertObject( logicalString2, - false, - true, - null, - this.workingMemory.getAgenda().getActivations()[0] ); - // return the matched handle - assertSame( logicalHandle2, - logicalHandle1 ); - - this.workingMemory.retractObject( handle1 ); - - // Should keep the same handle when overriding - assertSame( logicalHandle1, - logicalHandle2 ); - - // so while new STATED assertion is equal - assertEquals( logicalString1, - this.workingMemory.getObject( logicalHandle2 ) ); - - // they are not identity same - assertNotSame( logicalString1, - this.workingMemory.getObject( logicalHandle2 ) ); - +// // Alreyad identify same so return previously assigned handle +// logicalHandle1 = this.workingMemory.assertObject( logicalString2, +// false, +// true, +// null, +// this.workingMemory.getAgenda().getActivations()[0] ); +// // return the matched handle +// assertSame( logicalHandle2, +// logicalHandle1 ); +// +// this.workingMemory.retractObject( handle1 ); +// +// // Should keep the same handle when overriding +// assertSame( logicalHandle1, +// logicalHandle2 ); +// +// // so while new STATED assertion is equal +// assertEquals( logicalString1, +// this.workingMemory.getObject( logicalHandle2 ) ); +// +// // they are not identity same +// assertNotSame( logicalString1, +// this.workingMemory.getObject( logicalHandle2 ) ); +// } public void testRetract() throws Exception { |
From: <jbo...@li...> - 2006-04-27 03:19:10
|
Author: mic...@jb... Date: 2006-04-26 23:19:05 -0400 (Wed, 26 Apr 2006) New Revision: 3985 Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Rule_Base.xml Log: Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Rule_Base.xml =================================================================== --- labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Rule_Base.xml 2006-04-27 02:12:47 UTC (rev 3984) +++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Rule_Base.xml 2006-04-27 03:19:05 UTC (rev 3985) @@ -2,5 +2,18 @@ <section> <title>Rule Base</title> - <para>uuuere</para> + <para>A rule base contains one more more packages of rules, ready to be used + (ie they have been validated/compiled etc). Typically, a rulebase would be + generated when the rules change, and the cached until the rules change + again. </para> + + <para>A rulebase instance is threadsafe, in the sense that you can have the + one instance shared accross threads in your application (which may be a web + application, for instance). The most common operation on a rulebase is to + create a newWorkingMemory. </para> + + <para>The rulebase also holds weak references to any working memories that + it has spawned, so if rules are changing (or being added/removed etc) for + long running working memories, they can be updated with the latest rules + (without necessarily having to restart the working memory). </para> </section> \ No newline at end of file |
From: <jbo...@li...> - 2006-04-27 02:12:54
|
Author: mic...@jb... Date: 2006-04-26 22:12:47 -0400 (Wed, 26 Apr 2006) New Revision: 3984 Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Why_use_a_Rule_Engine.xml Log: more doco goodness Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Why_use_a_Rule_Engine.xml =================================================================== --- labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Why_use_a_Rule_Engine.xml 2006-04-27 01:12:41 UTC (rev 3983) +++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Why_use_a_Rule_Engine.xml 2006-04-27 02:12:47 UTC (rev 3984) @@ -113,35 +113,49 @@ answer, some more explanation is required. The reason why there is no "traditional" approach is possibly one of the following: <itemizedlist> <listitem> - <para>The problem is just too fiddly for traditional code. </para> + <para>The problem is just too fiddly for traditional code.</para> <para>The problem may not be complex, but you can't see a non fragile way of building it.</para> - - </listitem> <listitem> - <para>The problem is beyond any obvious algorithm based solution.</para> + <para>The problem is beyond any obvious algorithm based + solution.</para> + + <para>It is a complex problem to solve, there are no obvious + traditional solutions or basically the problem isn't fully + understood.</para> </listitem> <listitem> - <para>The logic changes often </para> + <para>The logic changes often</para> <para>The logic itself may be simple (but doesn't have to be) but the rules change just too often. In many organisations, software releases are few and far between, and rules can help provide the "agility" that is needed, and expected these days (in a reasonably safe way).</para> + </listitem> - + <listitem> + <para>Domain experts (or business analysts) are readily available, + but are non technical.</para> + + <para>Non technical domain experts are often a wealth of knowledge + about business rules. They typically are non technical, but can be + very logical. Rules can allow them to express the logic in their own + terms. Of course, they still have to think critically and be capable + of logical thinking (many people in "soft" non technical positions + are not, so be careful, as by codifying business knowledge in rules, + you will often be exposing flaws in the way the business rules are + at present).</para> </listitem> - </itemizedlist> - </para> + </itemizedlist></para> - <para> - Of course if rules are a new technology in your project teams experience, the overhead in getting going must be factored in. Its not a trivial technology, but we try to make it easier. - </para> + <para>Of course if rules are a new technology in your project teams + experience, the overhead in getting going must be factored in. Its not a + trivial technology, but we try to make it easier.</para> <para>Typically in a modern OO application you would use a rule engine to contain key parts of your business logic (what that means of course @@ -161,6 +175,12 @@ often an integral part of an application. However, there have been successful cases of creating reusable rul eservices which are stateless.</para> + + <para>In your organisation, it is important to think about the process you + may want to/have to use for updating rules in systems that are in + production (the options are many, but different organisations have + different requirements - often they are out of the control of the + application vendors/project teams).</para> </section> <section> @@ -174,5 +194,48 @@ designed to do rules. Use the right tool for the job. Sure, a pair of pliers can be used as a hammering tool in a pinch, but that's not what it's designed for."</para> + + <para>As rule engines are dynamic (dynamic in the sense that the rules can + be stored and managed and updates as data), they are often looked at as a + solution to the problem of deploying software (most IT departments seem to + exist for the purpose of preventing software being rolled out). If this is + the reason you wish to use a rule engine, be aware that rule engines work + best when you are able to write declarative rules. As an alternative, you + can consider data-driven designs (lookup tables), or script/process + engines where the scripts are managed in a database, and able to be + updated on the fly.</para> </section> + + <section> + <title>Scripting or process engines</title> + + <para>Hopefully the preceeding sections have explained when you may want + to use a rule engine. </para> + + <para>Alternatives are script-based engines that provide the dynamicness + for "changes on the fly" (there are many solutions here) or </para> + + <para>Process engines (also capable of workflow) such as jBPM allow you to + graphically (or programmatically) describe steps in a process - those + steps can also involve decision point which are in themselves a simple + rule. Process engines and rules often can work nicely together, so its not + an either-or proposition.</para> + + <para>One key point to note with rule engines, is that some rule-engines + are really scripting engines. The downside of scripting engines is that + you are tightly coupling your application to the scripts (if they are + rules, you are effectively calling rules directly) and this may cause more + difficulty in future maintenance, as they tend to grow in complexity over + time. The upside of scripting engines is they can be easier to implement + at first, and you can get quite results (and conceptually simpler for + imperative programmers !).</para> + + <para>Many people have also implemented data-driven systems successfully + in the past (where there are control tables that store meta-data that + changes your applications behaviour) - these can work well when the + control can remain very limited. However, they can quickly grow out of + control if extended to much (such that only the original creators can + change the applications behaviour), or, they cause the application to + stagnate as they are too inflexible.</para> + </section> </section> \ No newline at end of file |
From: <jbo...@li...> - 2006-04-27 01:12:49
|
Author: mic...@jb... Date: 2006-04-26 21:12:41 -0400 (Wed, 26 Apr 2006) New Revision: 3983 Modified: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EmptyColumn.drl Log: was a bad test Modified: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EmptyColumn.drl =================================================================== --- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EmptyColumn.drl 2006-04-27 00:27:28 UTC (rev 3982) +++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EmptyColumn.drl 2006-04-27 01:12:41 UTC (rev 3983) @@ -6,7 +6,7 @@ rule "simple rule" when - Cheese( ) + cheese : Cheese( ) then - list.add( cheese ); + list.add( new Integer(5) ); end \ No newline at end of file |
Author: unibrew Date: 2006-04-26 20:27:28 -0400 (Wed, 26 Apr 2006) New Revision: 3982 Added: labs/jbossforums/trunk/forums/src/main/org/jboss/portlet/forums/ui/action/ModeratorAction.java labs/jbossforums/trunk/forums/src/resources/portal-forums-war/views/moderator/ labs/jbossforums/trunk/forums/src/resources/portal-forums-war/views/moderator/modcp_body.xhtml Modified: labs/jbossforums/trunk/forums/src/resources/portal-forums-war/WEB-INF/forums-config.xml Log: [JBFORUMS-38] Adding Moderator Control Panel View's files. Added: labs/jbossforums/trunk/forums/src/main/org/jboss/portlet/forums/ui/action/ModeratorAction.java =================================================================== --- labs/jbossforums/trunk/forums/src/main/org/jboss/portlet/forums/ui/action/ModeratorAction.java 2006-04-27 00:26:58 UTC (rev 3981) +++ labs/jbossforums/trunk/forums/src/main/org/jboss/portlet/forums/ui/action/ModeratorAction.java 2006-04-27 00:27:28 UTC (rev 3982) @@ -0,0 +1,152 @@ +/* +* JBoss, Home of Professional Open Source +* Copyright 2005, JBoss Inc., and individual contributors as indicated +* by the @authors tag. See the copyright.txt in the distribution for a +* full listing of individual contributors. +* +* This is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 2.1 of +* the License, or (at your option) any later version. +* +* This software is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this software; if not, write to the Free +* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA, or see the FSF site: http://www.fsf.org. +*/ + +package org.jboss.portlet.forums.ui.action; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.jboss.portlet.forums.model.Forum; +import org.jboss.portlet.forums.model.Topic; +import org.jboss.portlet.forums.ui.BaseController; +import org.jboss.portlet.forums.ui.Constants; +import org.jboss.portlet.forums.ui.ForumUtil; +import org.jboss.portlet.forums.ui.JSFUtil; + +/** + * @author <a href="mailto:rys...@jb...">Ryszard Kozmik</a> + */ +public class ModeratorAction +{ + + //business data being generated in this bean by executing ui actions + //this is data is created such that it can be consumed by the view components + //like facelets + private Forum forum = null; + + private Map checkboxes; + + //----------------bean configuration supplied by the forums-config.xml--------------------------------------------------------------------------------------------- + + + //----------------business data being generated for use by the view components like facelets--------------------------------------------------------------------------------------- + public Forum getForum() + { + return this.forum; + } + public String getPagination() + { + /** + * TODO: implement real code to get the pagination... + */ + //stub code + return "10"; + } + public String getPageNumber() + { + /** + * TODO: implement real code to get the pageNumber... + */ + //stub code + return "2"; + } + + public void setCheckboxes(Map checkboxes) + { + this.checkboxes = checkboxes; + } + + public Map getCheckboxes() + { + return checkboxes; + } + + //------------user preferences------------------------------------------------------------------------------------------------------------- + + //------------------------------------------------------------------------------------------------------------------------------------- + /** + * + * @author Ryszard Kozmik + */ + public ModeratorAction() + { + super(); + try + { + this.execute(); + } + catch(Exception e) + { + JSFUtil.handleException(e); + } + } + + //ui actions supported by this bean---------------------------------------------------------------------------------------------------- + + + public String deleteTopic () + { + return ""; + } + + public String moveTopic () + { + return ""; + } + + public String lockTopic () + { + return ""; + } + + public String unlockTopic () + { + return ""; + } + + private void execute() throws Exception + { + int forumId = -1; + String f = ForumUtil.getParameter(Constants.p_forumId); + if(f!=null && f.trim().length()>0) + { + forumId = Integer.parseInt(f); + } + if(forumId!=-1) + { + // start with a stub implementation + this.forum = BaseController.getForumsModule().findForumById(new Integer(forumId)); + checkboxes = new HashMap(forum.getTopicCount()); + Iterator it = forum.getTopics().iterator(); + while (it.hasNext()) + { + Topic topic = (Topic)it.next(); + checkboxes.put(topic.getId(),Boolean.FALSE); + } + } + } + //------------------------------------------------------------------------------------------------------------------------------------- + + +} Modified: labs/jbossforums/trunk/forums/src/resources/portal-forums-war/WEB-INF/forums-config.xml =================================================================== --- labs/jbossforums/trunk/forums/src/resources/portal-forums-war/WEB-INF/forums-config.xml 2006-04-27 00:26:58 UTC (rev 3981) +++ labs/jbossforums/trunk/forums/src/resources/portal-forums-war/WEB-INF/forums-config.xml 2006-04-27 00:27:28 UTC (rev 3982) @@ -131,28 +131,28 @@ </navigation-case> </navigation-rule> <navigation-rule> - <from-view-id>/views/topics/posting_body.xhtml</from-view-id> + <from-view-id>/views/topics/posting_body.xhtml.jsp</from-view-id> <!-- straight jsf calls --> <navigation-case> <from-outcome>addOption</from-outcome> - <to-view-id>/views/topics/posting_body.xhtml</to-view-id> + <to-view-id>/views/topics/posting_body.xhtml.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>updateOption</from-outcome> - <to-view-id>/views/topics/posting_body.xhtml</to-view-id> + <to-view-id>/views/topics/posting_body.xhtml.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>updateAttachment</from-outcome> - <to-view-id>/views/topics/posting_body.xhtml</to-view-id> + <to-view-id>/views/topics/posting_body.xhtml.jsp</to-view-id> </navigation-case> <!-- jsf state by method call on managed bean first --> <navigation-case> <from-outcome>cancel</from-outcome> - <to-view-id>/views/forums/viewforum_body.xhtml</to-view-id> + <to-view-id>/views/forums/viewforum_body.xhtml.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>success</from-outcome> - <to-view-id>/views/forums/viewforum_body.xhtml</to-view-id> + <to-view-id>/views/forums/viewforum_body.xhtml.jsp</to-view-id> </navigation-case> </navigation-rule> <managed-bean> @@ -170,4 +170,9 @@ <managed-bean-class>org.jboss.portlet.forums.ui.view.ViewProfile</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> + <managed-bean> + <managed-bean-name>moderator</managed-bean-name> + <managed-bean-class>org.jboss.portlet.forums.ui.action.ModeratorAction</managed-bean-class> + <managed-bean-scope>session</managed-bean-scope> + </managed-bean> </faces-config> \ No newline at end of file Added: labs/jbossforums/trunk/forums/src/resources/portal-forums-war/views/moderator/modcp_body.xhtml =================================================================== --- labs/jbossforums/trunk/forums/src/resources/portal-forums-war/views/moderator/modcp_body.xhtml 2006-04-27 00:26:58 UTC (rev 3981) +++ labs/jbossforums/trunk/forums/src/resources/portal-forums-war/views/moderator/modcp_body.xhtml 2006-04-27 00:27:28 UTC (rev 3982) @@ -0,0 +1,127 @@ +<div xmlns="http://www.w3.org/1999/xhtml" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:forums="http://www.jboss.com/products/jbossportal/forums" + class="bb" +> +<ui:include src="/views/common/common.xhtml"/> + +<!-- TODO: +<n:errors/> +<n:success/> +--> +<!-- TODO: REWRITE S_POST_DAYS_ACTION +<form method="post" action="${n:out("S_POST_DAYS_ACTION")}">--> +<h:form> + <table width="100%" cellspacing="2" cellpadding="2" border="0" align="center"> + <tr> + <td align="left"> + <span class="nav"> + <a href="" class="nav"></a> -> + <h:outputLink value="#{forums:outputLink(shared.links['forum'],true)}" styleClass="nav"> + <f:param name="f" value="#{moderator.forum.id}"/> + <h:outputText value="#{moderator.forum.name}"/> + </h:outputLink> + </span> + </td> + </tr> + </table> + + <table width="100%" cellpadding="4" cellspacing="1" border="0" class="forumline"> + <tr> + <td class="catHead" colspan="5" align="center" height="28"> + <span class="cattitle">${resource.Mod_CP}</span> + </td> + </tr> + <tr> + <td class="spaceRow" colspan="5" align="center"> + <span class="gensmall">${resource.Mod_CP_explain}</span> + </td> + </tr> + <tr> + <th width="4%" class="thLeft" nowrap="nowrap">&nbsp;</th> + <th nowrap="nowrap">&nbsp;${resource.Topics}&nbsp;</th> + <th width="8%" nowrap="nowrap">&nbsp;${resource.Replies}&nbsp;</th> + <th width="17%" nowrap="nowrap">&nbsp;${resource.Last_Post}&nbsp;</th> + <th width="5%" class="thRight" nowrap="nowrap">&nbsp;${resource.Select}&nbsp;</th> + </tr> + <c:forEach items="#{moderator.forum.topics}" var="topicrow"> + <tr> + <td class="row1" align="center" valign="middle"> + <img src="#{forums:themeURL('resourceFolderURL')}" + width="19" + height="18" + alt="${resource.Topic_Moved}" + title="${resource.Topic_Moved}"/> + </td> + <td class="row1"> + &nbsp; + <!-- TODO: NEEDS SUPPORT OF EXECUTING THEME METHODS + <span class="topictitle">${n:out("topicrow.TOPIC_TYPE")} + --> + <h:outputLink value="#{forums:outputLink(shared.links['topic'],true)}" styleClass="topictitle"> + <f:param name="t" value="${topicrow.id}"/> + <h:outputText value="${topicrow.subject}"/> + </h:outputLink> + + <!-- TODO: LOOK ABOVE </span> --> + </td> + <td class="row2" align="center" valign="middle"><span + class="postdetails">${topicrow.replies}</span></td> + <td class="row1" align="center" valign="middle"><span + class="postdetails">${topicrow.lastPostDate}</span></td> + <td class="row2" align="center" valign="middle"> + <h:selectBooleanCheckbox value="#{moderator.checkboxes[topicrow.id]}" /> + </td> + </tr> + </c:forEach> + <tr align="right"> + <td class="catBottom" colspan="5" height="29"> + + <!-- TODO: IT IS PROBABLY USELESS IN JSF IMPLEMENTATION SO IT WILL BE DELETED + ${n:out("S_HIDDEN_FIELDS")} + --> + + <h:commandButton action="#{moderator.deleteTopic}" class="liteoption" value="${resource.Delete}"> + <f:param name="f" value="#{forum.forum.id}"/> + </h:commandButton> + &nbsp; + <h:commandButton action="#{moderator.moveTopic}" class="liteoption" value="${resource.Move}"> + <f:param name="f" value="#{forum.forum.id}"/> + </h:commandButton> + &nbsp; + <h:commandButton action="#{moderator.lockTopic}" class="liteoption" value="${resource.Lock}"> + <f:param name="f" value="#{forum.forum.id}"/> + </h:commandButton> + &nbsp; + <h:commandButton action="#{moderator.unlockTopic}" class="liteoption" value="${resource.Unlock}"> + <f:param name="f" value="#{forum.forum.id}"/> + </h:commandButton> + </td> + </tr> + </table> + <table width="100%" cellspacing="2" border="0" align="center" cellpadding="2"> + <tr> + <td align="left" valign="middle"> + <span class="nav"> + <b>#{forum.pagination}</b> + </span> + </td> + <td align="right" valign="top" nowrap="nowrap"> + <span class="gensmall"></span> + <br/> + <span class="nav">#{forum.pageNumber}</span> + </td> + </tr> +</table> +</h:form> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td align="right"> + <ui:include src="/views/jumpbox.xhtml"/> + </td> + </tr> +</table> +</div> |
From: <jbo...@li...> - 2006-04-27 00:27:13
|
Author: unibrew Date: 2006-04-26 20:26:58 -0400 (Wed, 26 Apr 2006) New Revision: 3981 Modified: labs/jbossforums/trunk/forums/src/main/org/jboss/portlet/forums/ui/ForumsJSFPortlet.java Log: [JBFORUMS-38] Adding userId request parameter forwarding in JSFPortlet. Modified: labs/jbossforums/trunk/forums/src/main/org/jboss/portlet/forums/ui/ForumsJSFPortlet.java =================================================================== --- labs/jbossforums/trunk/forums/src/main/org/jboss/portlet/forums/ui/ForumsJSFPortlet.java 2006-04-26 21:16:39 UTC (rev 3980) +++ labs/jbossforums/trunk/forums/src/main/org/jboss/portlet/forums/ui/ForumsJSFPortlet.java 2006-04-27 00:26:58 UTC (rev 3981) @@ -61,6 +61,7 @@ String pollDelete = ForumUtil.getParameter(request,Constants.p_poll_delete); String attachment = ForumUtil.getParameter(request,Constants.p_attachment); String topicId = ForumUtil.getParameter(request,Constants.p_topicId); + String userId = ForumUtil.getParameter(request,Constants.p_userId); if(categoryId!=null && categoryId.trim().length()>0) { response.setRenderParameter(Constants.p_categoryId,categoryId); @@ -89,5 +90,9 @@ { response.setRenderParameter(Constants.p_topicId,topicId); } + if(userId!=null && userId.trim().length()>0) + { + response.setRenderParameter(Constants.p_userId,userId); + } } } |
From: <jbo...@li...> - 2006-04-26 21:16:47
|
Author: mar...@jb... Date: 2006-04-26 17:16:39 -0400 (Wed, 26 Apr 2006) New Revision: 3980 Modified: labs/jbossrules/trunk/drools-compiler/pom.xml Log: -antlr 3 is moved to ibiblio and group-id has been changed Modified: labs/jbossrules/trunk/drools-compiler/pom.xml =================================================================== --- labs/jbossrules/trunk/drools-compiler/pom.xml 2006-04-26 21:16:05 UTC (rev 3979) +++ labs/jbossrules/trunk/drools-compiler/pom.xml 2006-04-26 21:16:39 UTC (rev 3980) @@ -59,8 +59,8 @@ </dependency> <dependency> - <groupId>antlr</groupId> - <artifactId>antlr3</artifactId> + <groupId>org.antlr</groupId> + <artifactId>antlr</artifactId> <version>3.0ea8</version> </dependency> @@ -71,9 +71,9 @@ </dependency> <dependency> - <groupId>eclipse</groupId> - <artifactId>jdtcore</artifactId> - <version>3.2.0.v_658</version> + <groupId>org.eclipse.jdt</groupId> + <artifactId>core</artifactId> + <version>3.2.0.658</version> </dependency> |
From: <jbo...@li...> - 2006-04-26 21:16:12
|
Author: mar...@jb... Date: 2006-04-26 17:16:05 -0400 (Wed, 26 Apr 2006) New Revision: 3979 Removed: labs/jbossrules/trunk/repository/antlr/ Log: -antlr3 has been moved to ibiblio |
From: <jbo...@li...> - 2006-04-26 19:55:16
|
Author: tirelli Date: 2006-04-26 15:55:00 -0400 (Wed, 26 Apr 2006) New Revision: 3978 Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectEqualConstrLeftMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectNotEqualConstrLeftMemory.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BaseBetaLeftMemoryTestClass.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BaseBetaRightMemoryTestClass.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BooleanConstrainedLeftMemoryTest.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BooleanConstrainedRightMemoryTest.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/DefaultLeftMemoryTest.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/DefaultRightMemoryTest.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectEqualConstrLeftMemoryTest.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectEqualConstrRightMemoryTest.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectNotEqualConstrLeftMemoryTest.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectNotEqualConstrRightMemoryTest.java Log: JBRULES-242: * Fixing bug where ObjectEqualsConstrLeftMemory and ObjectNotEqualsConstrLeftMemory where not delegating calls on selectPossibleMatches() method. * Added unit test to ensure all Beta Memory implementations will have that call. Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectEqualConstrLeftMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectEqualConstrLeftMemory.java 2006-04-26 17:34:05 UTC (rev 3977) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectEqualConstrLeftMemory.java 2006-04-26 19:55:00 UTC (rev 3978) @@ -259,6 +259,11 @@ Object select = this.extractor.getValue( handle.getObject() ); Integer hash = (select != null) ? new Integer( select.hashCode() ) : new Integer( 0 ); this.selectedList = (MultiLinkedList) this.memoryMap.get( hash ); + + if ( this.childMemory != null ) { + this.childMemory.selectPossibleMatches( workingMemory, + handle ); + } } /** Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectNotEqualConstrLeftMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectNotEqualConstrLeftMemory.java 2006-04-26 17:34:05 UTC (rev 3977) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectNotEqualConstrLeftMemory.java 2006-04-26 19:55:00 UTC (rev 3978) @@ -247,6 +247,11 @@ InternalFactHandle handle) { Object select = this.extractor.getValue( handle.getObject() ); this.noMatchList = (MultiLinkedList) this.memoryMap.get( select ); + + if ( this.innerMemory != null ) { + this.innerMemory.selectPossibleMatches( workingMemory, + handle ); + } } /** Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BaseBetaLeftMemoryTestClass.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BaseBetaLeftMemoryTestClass.java 2006-04-26 17:34:05 UTC (rev 3977) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BaseBetaLeftMemoryTestClass.java 2006-04-26 19:55:00 UTC (rev 3978) @@ -21,6 +21,8 @@ import junit.framework.Assert; import junit.framework.TestCase; +import org.drools.WorkingMemory; +import org.drools.common.InternalFactHandle; import org.drools.reteoo.DefaultFactHandleFactory; import org.drools.reteoo.FactHandleImpl; import org.drools.reteoo.ReteTuple; @@ -37,21 +39,23 @@ * Created: 28/02/2006 */ public abstract class BaseBetaLeftMemoryTestClass extends TestCase { - protected WorkingMemoryImpl workingMemory; - protected BetaLeftMemory memory; - protected DummyValueObject obj0; - protected DummyValueObject obj1; - protected DummyValueObject obj2; - protected FactHandleFactory factory; - protected FactHandleImpl f0; - protected FactHandleImpl f1; - protected FactHandleImpl f2; - protected ReteTuple tuple0; - protected ReteTuple tuple1; - protected ReteTuple tuple2; + protected WorkingMemoryImpl workingMemory; + protected BetaLeftMemory memory; + protected MockBetaLeftMemory child; + protected DummyValueObject obj0; + protected DummyValueObject obj1; + protected DummyValueObject obj2; + protected FactHandleFactory factory; + protected FactHandleImpl f0; + protected FactHandleImpl f1; + protected FactHandleImpl f2; + protected ReteTuple tuple0; + protected ReteTuple tuple1; + protected ReteTuple tuple2; public BaseBetaLeftMemoryTestClass() { this.memory = null; + this.child = new MockBetaLeftMemory(); } protected void setUp() throws Exception { @@ -349,6 +353,12 @@ Assert.fail( "BetaRightMemory was not supposed to throw ClassCastException: " + e.getMessage() ); } } + + public void testSelectPossibleMatches2() { + int counter = this.child.getCounter(); + this.memory.selectPossibleMatches( this.workingMemory, this.f0 ); + Assert.assertEquals( "Should have called inner memory", counter+1, this.child.getCounter() ); + } public abstract void testIterator(); @@ -360,4 +370,64 @@ */ public abstract void testModifyObjectAttribute(); + + public static class MockBetaLeftMemory implements BetaLeftMemory { + private int callCounter = 0; + + public void add(WorkingMemory workingMemory, + MultiLinkedListNodeWrapper tuple) { + this.callCounter++; + } + + public void add(WorkingMemory workingMemory, + ReteTuple tuple) { + this.callCounter++; + } + + public boolean isEmpty() { + this.callCounter++; + return false; + } + + public boolean isPossibleMatch(MultiLinkedListNodeWrapper tuple) { + this.callCounter++; + return true; + } + + public Iterator iterator(WorkingMemory workingMemory, + InternalFactHandle handle) { + this.callCounter++; + return null; + } + + public Iterator iterator() { + this.callCounter++; + return null; + } + + public void remove(WorkingMemory workingMemory, + MultiLinkedListNodeWrapper tuple) { + this.callCounter++; + } + + public void remove(WorkingMemory workingMemory, + ReteTuple tuple) { + this.callCounter++; + } + + public void selectPossibleMatches(WorkingMemory workingMemory, + InternalFactHandle handle) { + this.callCounter++; + } + + public int size() { + this.callCounter++; + return 0; + } + + public int getCounter() { + return this.callCounter; + } + }; + } Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BaseBetaRightMemoryTestClass.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BaseBetaRightMemoryTestClass.java 2006-04-26 17:34:05 UTC (rev 3977) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BaseBetaRightMemoryTestClass.java 2006-04-26 19:55:00 UTC (rev 3978) @@ -21,6 +21,7 @@ import junit.framework.Assert; import junit.framework.TestCase; +import org.drools.WorkingMemory; import org.drools.reteoo.DefaultFactHandleFactory; import org.drools.reteoo.FactHandleImpl; import org.drools.reteoo.ObjectMatches; @@ -42,6 +43,7 @@ public abstract class BaseBetaRightMemoryTestClass extends TestCase { protected WorkingMemoryImpl workingMemory; protected BetaRightMemory memory; + protected MockBetaRightMemory child; protected DummyValueObject obj0; protected DummyValueObject obj1; protected DummyValueObject obj2; @@ -58,6 +60,7 @@ public BaseBetaRightMemoryTestClass() { this.memory = null; + this.child = new MockBetaRightMemory(); } protected void setUp() throws Exception { @@ -343,6 +346,12 @@ } } + public void testSelectPossibleMatches2() { + int counter = this.child.getCounter(); + this.memory.selectPossibleMatches( this.workingMemory, this.tuple0 ); + Assert.assertEquals( "Should have called inner memory", counter+1, this.child.getCounter() ); + } + /* * Test method for 'org.drools.reteoo.beta.DefaultRightMemory.selectPossibleMatches(WorkingMemory, ReteTuple)' */ @@ -358,4 +367,62 @@ * a remove; */ public abstract void testModifyObjectAttribute(); + + public static class MockBetaRightMemory implements BetaRightMemory { + private int callCounter = 0; + + public void add(WorkingMemory workingMemory, + ObjectMatches matches) { + this.callCounter++; + } + + public void add(WorkingMemory workingMemory, + MultiLinkedListNodeWrapper matches) { + this.callCounter++; + } + + public boolean isEmpty() { + this.callCounter++; + return false; + } + + public boolean isPossibleMatch(MultiLinkedListNodeWrapper matches) { + this.callCounter++; + return true; + } + + public Iterator iterator(WorkingMemory workingMemory, + ReteTuple tuple) { + this.callCounter++; + return null; + } + + public Iterator iterator() { + this.callCounter++; + return null; + } + + public void remove(WorkingMemory workingMemory, + ObjectMatches matches) { + this.callCounter++; + } + + public void remove(WorkingMemory workingMemory, + MultiLinkedListNodeWrapper matches) { + this.callCounter++; + } + + public void selectPossibleMatches(WorkingMemory workingMemory, + ReteTuple tuple) { + this.callCounter++; + } + + public int size() { + return 0; + } + + public int getCounter() { + return this.callCounter; + } + } } Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BooleanConstrainedLeftMemoryTest.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BooleanConstrainedLeftMemoryTest.java 2006-04-26 17:34:05 UTC (rev 3977) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BooleanConstrainedLeftMemoryTest.java 2006-04-26 19:55:00 UTC (rev 3978) @@ -52,7 +52,8 @@ this.memory = new BooleanConstrainedLeftMemory( extractor, declaration, - evaluator ); + evaluator, + this.child); } protected void tearDown() throws Exception { Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BooleanConstrainedRightMemoryTest.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BooleanConstrainedRightMemoryTest.java 2006-04-26 17:34:05 UTC (rev 3977) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/BooleanConstrainedRightMemoryTest.java 2006-04-26 19:55:00 UTC (rev 3978) @@ -51,11 +51,10 @@ Evaluator evaluator = EvaluatorFactory.getEvaluator( Evaluator.BOOLEAN_TYPE, Evaluator.EQUAL ); - BetaRightMemory defaultMem = new DefaultRightMemory(); this.memory = new BooleanConstrainedRightMemory( extractor, declaration, evaluator, - defaultMem ); + this.child ); } protected void tearDown() throws Exception { Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/DefaultLeftMemoryTest.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/DefaultLeftMemoryTest.java 2006-04-26 17:34:05 UTC (rev 3977) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/DefaultLeftMemoryTest.java 2006-04-26 19:55:00 UTC (rev 3978) @@ -41,6 +41,10 @@ super.tearDown(); } + public void testSelectPossibleMatches2() { + // do nothing as there is no child memory + } + /* * Test method for 'org.drools.reteoo.beta.DefaultLeftMemory.iterator(WorkingMemory, FactHandleImpl)' */ Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/DefaultRightMemoryTest.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/DefaultRightMemoryTest.java 2006-04-26 17:34:05 UTC (rev 3977) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/DefaultRightMemoryTest.java 2006-04-26 19:55:00 UTC (rev 3978) @@ -47,6 +47,10 @@ super.tearDown(); } + public void testSelectPossibleMatches2() { + // do nothing as there is no child memory + } + /* * Test method for 'org.drools.reteoo.beta.DefaultRightMemory.iterator(WorkingMemory, ReteTuple)' */ Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectEqualConstrLeftMemoryTest.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectEqualConstrLeftMemoryTest.java 2006-04-26 17:34:05 UTC (rev 3977) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectEqualConstrLeftMemoryTest.java 2006-04-26 19:55:00 UTC (rev 3978) @@ -51,7 +51,8 @@ this.memory = new ObjectEqualConstrLeftMemory( extractor, declaration, - evaluator ); + evaluator, + this.child); } protected void tearDown() throws Exception { Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectEqualConstrRightMemoryTest.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectEqualConstrRightMemoryTest.java 2006-04-26 17:34:05 UTC (rev 3977) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectEqualConstrRightMemoryTest.java 2006-04-26 19:55:00 UTC (rev 3978) @@ -51,11 +51,10 @@ Evaluator evaluator = EvaluatorFactory.getEvaluator( Evaluator.OBJECT_TYPE, Evaluator.EQUAL ); - BetaRightMemory defaultMem = new DefaultRightMemory(); this.memory = new ObjectEqualConstrRightMemory( extractor, declaration, evaluator, - defaultMem ); + this.child ); } protected void tearDown() throws Exception { Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectNotEqualConstrLeftMemoryTest.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectNotEqualConstrLeftMemoryTest.java 2006-04-26 17:34:05 UTC (rev 3977) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectNotEqualConstrLeftMemoryTest.java 2006-04-26 19:55:00 UTC (rev 3978) @@ -52,7 +52,8 @@ this.memory = new ObjectNotEqualConstrLeftMemory( extractor, declaration, - evaluator ); + evaluator, + this.child); } protected void tearDown() throws Exception { Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectNotEqualConstrRightMemoryTest.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectNotEqualConstrRightMemoryTest.java 2006-04-26 17:34:05 UTC (rev 3977) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/beta/ObjectNotEqualConstrRightMemoryTest.java 2006-04-26 19:55:00 UTC (rev 3978) @@ -51,11 +51,10 @@ Evaluator evaluator = EvaluatorFactory.getEvaluator( Evaluator.OBJECT_TYPE, Evaluator.NOT_EQUAL ); - BetaRightMemory defaultMem = new DefaultRightMemory(); this.memory = new ObjectNotEqualConstrRightMemory( extractor, declaration, evaluator, - defaultMem ); + this.child ); } protected void tearDown() throws Exception { |
From: <jbo...@li...> - 2006-04-26 17:34:10
|
Author: szimano Date: 2006-04-26 13:34:05 -0400 (Wed, 26 Apr 2006) New Revision: 3977 Modified: labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/java/org/jboss/wiki/fileaccess/WikiFileAccessFilter.java Log: check if utf character is a letter JBWIKI-86 Modified: labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/java/org/jboss/wiki/fileaccess/WikiFileAccessFilter.java =================================================================== --- labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/java/org/jboss/wiki/fileaccess/WikiFileAccessFilter.java 2006-04-26 17:28:22 UTC (rev 3976) +++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/java/org/jboss/wiki/fileaccess/WikiFileAccessFilter.java 2006-04-26 17:34:05 UTC (rev 3977) @@ -219,8 +219,9 @@ for (int i = 0; i < tokens.length; i++) // uppercase or UTF character - if (!(Character.isUpperCase(tokens[i].charAt(0)) || tokens[i] - .charAt(0) > 127)) { + if (!(Character.isUpperCase(tokens[i].charAt(0)) || (tokens[i] + .charAt(0) > 127 && Character.isLetter(tokens[i] + .charAt(0))))) { isAllUpperCase = false; break; } @@ -233,7 +234,8 @@ } if (Character.isUpperCase(tokens[tokens.length - 1].charAt(0)) - || tokens[tokens.length - 1].charAt(0) > 127) { + || (tokens[tokens.length - 1].charAt(0) > 127 && Character + .isLetter(tokens[tokens.length - 1].charAt(0)))) { httpResponse.sendRedirect(hostURL + wikiHome + "&page=" + pageName.substring(1) + ((version != -1) ? "&version=" + version : "") |
From: <jbo...@li...> - 2006-04-26 17:28:26
|
Author: szimano Date: 2006-04-26 13:28:22 -0400 (Wed, 26 Apr 2006) New Revision: 3976 Modified: labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/WikiEngine.java Log: removed trash from output Modified: labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/WikiEngine.java =================================================================== --- labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/WikiEngine.java 2006-04-26 17:25:40 UTC (rev 3975) +++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/WikiEngine.java 2006-04-26 17:28:22 UTC (rev 3976) @@ -531,7 +531,7 @@ Map<String, Integer> resPages = new HashMap<String, Integer>(); - log.info(langCode); + log.debug(langCode); Set<String> pages = languageDataSources.get(langCode) .getMediaDataSource().getAllPageNames(); |
Author: szimano Date: 2006-04-26 13:25:40 -0400 (Wed, 26 Apr 2006) New Revision: 3975 Modified: labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/java/org/jboss/wiki/WikiPortlet.java labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/java/org/jboss/wiki/fileaccess/WikiFileAccessFilter.java labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/web/WEB-INF/jsp/Edit.jsp labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/FileDSCommons.java labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/FileMediaDataSource.java labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/RenamePageWatcher.java labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/WikiEngine.java Log: utf-8 page names working ! http://jira.jboss.com/jira/browse/JBWIKI-86 Modified: labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/java/org/jboss/wiki/WikiPortlet.java =================================================================== --- labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/java/org/jboss/wiki/WikiPortlet.java 2006-04-26 14:56:28 UTC (rev 3974) +++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/java/org/jboss/wiki/WikiPortlet.java 2006-04-26 17:25:40 UTC (rev 3975) @@ -23,29 +23,29 @@ import java.io.File; import java.io.FileInputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.StringReader; -import java.io.StringWriter; import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import javax.portlet.*; +import javax.portlet.ActionRequest; +import javax.portlet.ActionResponse; +import javax.portlet.GenericPortlet; +import javax.portlet.PortletException; +import javax.portlet.RenderRequest; +import javax.portlet.RenderResponse; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.PortletDiskFileUpload; import org.jboss.logging.Logger; import org.jboss.wiki.exceptions.EditSessionExpired; import org.jboss.wiki.exceptions.EditingNotAllowedException; import org.jboss.wiki.exceptions.WikiManagementNotFoundException; import org.jboss.wiki.exceptions.WikiSaveException; import org.jboss.wiki.management.WikiServiceMenagement; -import org.apache.commons.fileupload.PortletDiskFileUpload; -import org.apache.commons.fileupload.FileUploadException; -import org.apache.commons.fileupload.FileItem; /** * The WikiPortlet. @@ -277,10 +277,6 @@ String editedPageName = convertedParameters.get("editedPage"); - log.info("Edited name: " + editedPageName - + " name (not converted): " - + convertedParameters.get("editedPage")); - // unlock page WikiPage edPage = wikiEngine.getByName(editedPageName, wikiContext, (String) convertedParameters.get("language")); Modified: labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/java/org/jboss/wiki/fileaccess/WikiFileAccessFilter.java =================================================================== --- labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/java/org/jboss/wiki/fileaccess/WikiFileAccessFilter.java 2006-04-26 14:56:28 UTC (rev 3974) +++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/java/org/jboss/wiki/fileaccess/WikiFileAccessFilter.java 2006-04-26 17:25:40 UTC (rev 3975) @@ -150,9 +150,10 @@ + request.getServerPort()); wikiSession.setAttribute("hostURL", hostURL); - - String requestURI = URLDecoder.decode(httpRequest.getRequestURI(), "UTF-8"); + String requestURI = URLDecoder.decode(httpRequest.getRequestURI(), + "UTF-8"); + // get off "/wiki/" from the begining requestURI = requestURI.substring("/wiki/".length()); @@ -191,32 +192,35 @@ } // check if user is browsing different then default language - if (wikiEngine.getUsedLanguageCodes().containsKey(tokens[0].toUpperCase())) { + if (wikiEngine.getUsedLanguageCodes().containsKey( + tokens[0].toUpperCase())) { langCode = tokens[0].toUpperCase(); // redo tokens but without language - if (requestURI.startsWith(tokens[0]+ "/")) { - requestURI = requestURI.substring((tokens[0] + "/").length()); - } - else { + if (requestURI.startsWith(tokens[0] + "/")) { + requestURI = requestURI.substring((tokens[0] + "/") + .length()); + } else { requestURI = requestURI.substring((tokens[0]).length()); } - + tokens = requestURI.split("[/]"); - + if ((tokens.length == 1) && (tokens[0].equals(""))) { // show Main page - as there is no place to go specified :) - httpResponse.sendRedirect(hostURL + wikiHome + "&language=" + langCode); + httpResponse.sendRedirect(hostURL + wikiHome + "&language=" + + langCode); return; } } - + // check if all tokens are UpperCase (meanins they are all wiki // pages) boolean isAllUpperCase = true; for (int i = 0; i < tokens.length; i++) - //uppercase or UTF character - if (!Character.isUpperCase(tokens[i].charAt(0)) || tokens[i].charAt(0) > 127) { + // uppercase or UTF character + if (!(Character.isUpperCase(tokens[i].charAt(0)) || tokens[i] + .charAt(0) > 127)) { isAllUpperCase = false; break; } @@ -227,12 +231,13 @@ for (int i = 0; i < tokens.length; i++) { pageName += "/" + URLEncoder.encode(tokens[i], "UTF-8"); } - - if (Character.isUpperCase(tokens[tokens.length - 1].charAt(0))) { + + if (Character.isUpperCase(tokens[tokens.length - 1].charAt(0)) + || tokens[tokens.length - 1].charAt(0) > 127) { httpResponse.sendRedirect(hostURL + wikiHome + "&page=" + pageName.substring(1) + ((version != -1) ? "&version=" + version : "") - + "&language="+langCode); + + "&language=" + langCode); } else { PrintWriter out = httpResponse.getWriter(); httpResponse.setContentType("text/html"); @@ -301,17 +306,16 @@ httpResponse.setContentLength(page.getPageContent() .length()); - + httpResponse.getWriter().print(page.getPageContent()); httpResponse.getWriter().flush(); } else { // show error response httpResponse.setContentType("text/html"); - httpResponse - .getWriter() - .println( - "<html><body><h3>ERROR</h3><br />\nThere is no such wikiType: "+wikiTypeName+"</body></html>"); + httpResponse.getWriter().println( + "<html><body><h3>ERROR</h3><br />\nThere is no such wikiType: " + + wikiTypeName + "</body></html>"); } } else { httpResponse.setContentType("text/html"); Modified: labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/web/WEB-INF/jsp/Edit.jsp =================================================================== --- labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/web/WEB-INF/jsp/Edit.jsp 2006-04-26 14:56:28 UTC (rev 3974) +++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/forge-wiki/src/web/WEB-INF/jsp/Edit.jsp 2006-04-26 17:25:40 UTC (rev 3975) @@ -30,7 +30,7 @@ <hr /> <div style="color:#FF0000"><%=lockMsg%></div> -<form method="post" action="<%=actionURL%>" accept-charset="utf-8"> +<form method="post" action="<%=actionURL%>" accept-charset="UTF-8"> Language: <%=curLang %> <textarea name="wikiContent" rows="40" cols="80" style="width:100%;"><%=wikiContent%></textarea> <input type="hidden" name="editedPage" value="<%=wikiPage%>" /> Modified: labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/FileDSCommons.java =================================================================== --- labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/FileDSCommons.java 2006-04-26 14:56:28 UTC (rev 3974) +++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/FileDSCommons.java 2006-04-26 17:25:40 UTC (rev 3975) @@ -27,51 +27,25 @@ public class FileDSCommons { - private static final String UNICODE = "uuuniCode"; - - private static String byteToHex(byte b) { - // Returns hex String representation of byte b - char hexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f' }; - char[] array = { hexDigit[(b >> 4) & 0x0f], hexDigit[b & 0x0f] }; - return new String(array); - } // end of method byteToHex - - private static String charToHex(char c) { - // Returns hex String representation of char c - byte hi = (byte) (c >>> 8); - byte lo = (byte) (c & 0xff); - return byteToHex(hi) + byteToHex(lo); - } // end of method - - private static String toEscape(char c) { // instead of this method - // charToHex() can be used - // int n = (int)c; - // String body = Integer.toHexString(n); - String body = charToHex(c); // instead of this the above can be used - String zeros = "000"; - return (UNICODE + zeros.substring(0, 4 - body.length()) + body); - } + private static final String SLASH = "/"; - private static String translateString(String s) { - StringBuilder builder = new StringBuilder(); - - for (int i = 0; i < s.length(); i++) { - if (s.charAt(i) > 127) { - builder.append(toEscape(s.charAt(i))); - } - else { - builder.append(s.charAt(i)); - } + private static final String ENCODING = "UTF-8"; + + private static String translatedSlash; + + static { + try { + translatedSlash = URLEncoder.encode(SLASH, ENCODING); + } catch (UnsupportedEncodingException e) { + // there's nothing we can do + e.printStackTrace(); } - - return builder.toString(); } public static String translateToFileName(String pageName) { - //return translateString(pageName); + try { - return URLEncoder.encode(pageName, "UTF-8"); + return URLEncoder.encode(pageName, ENCODING).replaceAll(translatedSlash, SLASH); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return pageName; @@ -79,9 +53,9 @@ } public static String translateToPageName(String fileName) { - //return fileName.replaceAll(UNICODE, "\\u"); + try { - return URLDecoder.decode(fileName, "UTF-8"); + return URLDecoder.decode(fileName.replaceAll(SLASH, translatedSlash), ENCODING); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return fileName; Modified: labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/FileMediaDataSource.java =================================================================== --- labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/FileMediaDataSource.java 2006-04-26 14:56:28 UTC (rev 3974) +++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/FileMediaDataSource.java 2006-04-26 17:25:40 UTC (rev 3975) @@ -244,15 +244,15 @@ newPageFile = new File(pathToMedia + "/OLD/" + uidTranslated + "/page.properties"); - FileOutputStream pageWriter = new FileOutputStream(newPageFile); + FileOutputStream pageProps = new FileOutputStream(newPageFile); Properties properties = new Properties(); properties.setProperty(page.getLastVersion() + ".author", page .getLastAuthor().getName()); - properties.store(pageWriter, SAVE_COMMENT); + properties.store(pageProps, SAVE_COMMENT); - pageWriter.close(); + pageProps.close(); String pageDirName = pathToMedia; String[] pageNames = uidTranslated.split("/"); @@ -265,8 +265,8 @@ pageDir.mkdirs(); - pageWriter = new FileOutputStream(new File(pathToMedia + "/" - + uidTranslated + ".txt")); + FileWriter pageWriter = new FileWriter(new File(pathToMedia + + "/" + uidTranslated + ".txt")); String pageContent = page.getContent(); @@ -602,8 +602,9 @@ File pageFile = new File(pathToMedia + "/" + FileDSCommons.translateToFileName(pageName) + ".txt"); - log.debug("PAGE EXISTS ("+pageName+"): "+pathToMedia + "/" - + FileDSCommons.translateToFileName(pageName) + ".txt FILE: "+pageFile.getAbsolutePath()); + log.debug("PAGE EXISTS (" + pageName + "): " + pathToMedia + "/" + + FileDSCommons.translateToFileName(pageName) + ".txt FILE: " + + pageFile.getAbsolutePath()); if (pageFile.exists()) { return true; } else { @@ -623,18 +624,25 @@ File attDir = new File(pathToMedia + "/" + directory); File[] pageFiles = attDir.listFiles(); + int i; - for (int i = 0; i < pageFiles.length; i++) { + for (i = 0; i < pageFiles.length; i++) { if ((pageFiles[i].isFile()) && (pageFiles[i].getName().endsWith(".txt"))) { // String[] tokens = pageFiles[i].getName().split("/"); - attSet.add((directory + "/" + pageFiles[i].getName().substring( - 0, pageFiles[i].getName().length() - ".txt".length())) - .substring(1)); + attSet + .add((FileDSCommons.translateToPageName(directory) + + "/" + FileDSCommons + .translateToPageName(pageFiles[i].getName() + .substring( + 0, + pageFiles[i].getName().length() + - ".txt".length()))) + .substring(1)); } } - for (int i = 0; i < pageFiles.length; i++) { + for (i = 0; i < pageFiles.length; i++) { if ((pageFiles[i].isDirectory()) && (!pageFiles[i].getName().endsWith("-att"))) { @@ -665,7 +673,8 @@ public Set<String> getPagesFor(String pageName) { Set<String> pages = new TreeSet<String>(); - File pageDir = new File(pathToMedia + "/" + pageName); + File pageDir = new File(pathToMedia + "/" + + FileDSCommons.translateToFileName(pageName)); if ((pageDir.exists()) && (pageDir.isDirectory())) { getPagesInside(pageDir, pages, pageName); @@ -682,13 +691,16 @@ && (subFiles[i].getName().endsWith(".txt"))) { pages.add(prefix + "/" - + subFiles[i].getName().substring( - 0, - subFiles[i].getName().length() - - ".txt".length())); + + FileDSCommons.translateToPageName(subFiles[i] + .getName().substring( + 0, + subFiles[i].getName().length() + - ".txt".length()))); } else if (subFiles[i].isDirectory()) { - getPagesInside(subFiles[i], pages, prefix + "/" - + subFiles[i].getName()); + getPagesInside(subFiles[i], pages, prefix + + "/" + + FileDSCommons.translateToPageName(subFiles[i] + .getName())); } } } Modified: labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/RenamePageWatcher.java =================================================================== --- labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/RenamePageWatcher.java 2006-04-26 14:56:28 UTC (rev 3974) +++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/RenamePageWatcher.java 2006-04-26 17:25:40 UTC (rev 3975) @@ -65,26 +65,23 @@ e.printStackTrace(); } } else { - try { - wikiEngine.getS().acquire(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + + synchronized (wikiEngine) { - for (int i = 0; i < uids.size(); i++) { - try { - wikiPageDictionary - .rename(uids.get(i), realNames.get(i)); - } catch (PageRenamingException e) { - e.printStackTrace(); + for (int i = 0; i < uids.size(); i++) { + try { + wikiPageDictionary.rename(uids.get(i), realNames + .get(i)); + } catch (PageRenamingException e) { + e.printStackTrace(); + } } - } - // clear tables - uids.clear(); - realNames.clear(); + // clear tables + uids.clear(); + realNames.clear(); - wikiEngine.getS().release(); + } runs = false; @@ -96,7 +93,7 @@ + pageToRemove, e); } } - + // clear pages to remove pagesToRemove.clear(); } Modified: labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/WikiEngine.java =================================================================== --- labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/WikiEngine.java 2006-04-26 14:56:28 UTC (rev 3974) +++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/wiki/WikiEngine.java 2006-04-26 17:25:40 UTC (rev 3975) @@ -85,7 +85,7 @@ private Set<Integer> editedPages; - private Semaphore s = new Semaphore(1); + //private Semaphore s = new Semaphore(1); private Class credentialsClass; @@ -127,11 +127,11 @@ public synchronized WikiPage getByName(String pageName, WikiContext wikiContext, LanguageDataSource dataSource) { - try { + /*try { s.acquire(); } catch (InterruptedException e) { e.printStackTrace(); - } + }*/ String realPageName = getUid(pageName, dataSource.getLanguageCode()); @@ -139,7 +139,7 @@ if (!dataSource.getMediaDataSource().preGet()) { log.error("Couldn't get page"); - s.release(); + //s.release(); return null; } @@ -160,7 +160,7 @@ if (((wikiContext != null) && (ret != null) && (!ret.isViewable(wikiContext.getUser())) && (!wikiContext .getUser().isAdmin()))) { - s.release(); + //s.release(); ret = new WikiPage(realPageName, null, "I am sorry, but you are not allowed to see this page", 0, 0, new Date(), this, false, false, null, null, 0, @@ -177,10 +177,10 @@ if (ret != null) { if (wikiContext != null) { - s.release(); + //s.release(); return wikiContext.process(ret); } else { - s.release(); + //s.release(); return ret; } } else { @@ -193,10 +193,10 @@ } if (wikiContext != null) { - s.release(); + //s.release(); return wikiContext.process(ret); } else { - s.release(); + //s.release(); return ret; } } @@ -210,11 +210,11 @@ public synchronized WikiPage getByName(String pageName, WikiContext wikiContext, int version, LanguageDataSource dataSource) { - try { + /*try { s.acquire(); } catch (InterruptedException e) { e.printStackTrace(); - } + }*/ String realPageName = getUid(pageName, dataSource.getLanguageCode()); @@ -236,10 +236,10 @@ if (ret != null) { if (wikiContext != null) { - s.release(); + //s.release(); return wikiContext.process(ret); } else { - s.release(); + //s.release(); return ret; } } else { @@ -250,7 +250,7 @@ * (wikiContext != null) { return wikiContext.process(ret); } else { * return ret; } */ - s.release(); + //s.release(); return null; } } @@ -981,9 +981,9 @@ editedPages.add(editSessionId); } - public Semaphore getS() { + /*public Semaphore getS() { return s; - } + }*/ public HashMap<String, String> getPagesWaiting(String langCode) { return languageDataSources.get(langCode).getRenamePageWatcher() |
Author: tirelli Date: 2006-04-26 10:56:28 -0400 (Wed, 26 Apr 2006) New Revision: 3974 Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/BetaLeftMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/BooleanConstrainedLeftMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/BooleanConstrainedRightMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/DefaultLeftMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/DefaultRightMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectEqualConstrLeftMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectEqualConstrRightMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectNotEqualConstrLeftMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectNotEqualConstrRightMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/LinkedList.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Chosen.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Context.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Count.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Guest.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Hobby.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/LastSeat.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Path.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Seating.java labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Sex.java Log: Improving performance Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/BetaLeftMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/BetaLeftMemory.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/BetaLeftMemory.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -20,7 +20,6 @@ import org.drools.WorkingMemory; import org.drools.common.InternalFactHandle; -import org.drools.reteoo.FactHandleImpl; import org.drools.reteoo.ReteTuple; import org.drools.util.MultiLinkedListNodeWrapper; Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/BooleanConstrainedLeftMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/BooleanConstrainedLeftMemory.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/BooleanConstrainedLeftMemory.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -21,7 +21,6 @@ import org.drools.WorkingMemory; import org.drools.common.InternalFactHandle; -import org.drools.reteoo.FactHandleImpl; import org.drools.reteoo.ReteTuple; import org.drools.rule.Declaration; import org.drools.spi.Evaluator; @@ -80,7 +79,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#add(org.drools.WorkingMemory, org.drools.reteoo.ReteTuple) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, ReteTuple tuple) { boolean select = ((Boolean) declaration.getValue( tuple.get( this.column ).getObject() )).booleanValue(); if ( select == true ) { @@ -100,7 +99,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#remove(org.drools.reteoo.ReteTuple) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, ReteTuple tuple) { if ( this.childMemory != null ) { this.childMemory.remove( workingMemory, @@ -114,7 +113,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#add(org.drools.reteoo.ReteTuple) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, MultiLinkedListNodeWrapper tuple) { boolean partition = ((Boolean) declaration.getValue( ((ReteTuple) tuple.getNode()).get( this.column ).getObject() )).booleanValue(); if ( partition == true ) { @@ -134,7 +133,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#remove(org.drools.reteoo.ReteTuple) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, MultiLinkedListNodeWrapper tuple) { if ( this.childMemory != null ) { this.childMemory.remove( workingMemory, @@ -148,7 +147,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#isEmpty() */ - public boolean isEmpty() { + public final boolean isEmpty() { return (trueList.isEmpty()) && (falseList.isEmpty()); } @@ -157,24 +156,26 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#iterator(org.drools.WorkingMemory, org.drools.reteoo.FactHandleImpl) */ - public Iterator iterator(final WorkingMemory workingMemory, + public final Iterator iterator(final WorkingMemory workingMemory, final InternalFactHandle handle) { this.selectPossibleMatches( workingMemory, handle ); Iterator iterator = new Iterator() { - Iterator it = selectedList.iterator(); - MultiLinkedListNode current = null; - MultiLinkedListNode next = null; + MultiLinkedListNode current = null; + MultiLinkedListNode next = null; + MultiLinkedListNode candidate = (MultiLinkedListNode) selectedList.getFirst(); - public boolean hasNext() { + public final boolean hasNext() { boolean hasnext = false; if ( next == null ) { - while ( it.hasNext() ) { - next = (MultiLinkedListNode) it.next(); - if ( (childMemory == null) || (childMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) next.getChild() )) ) { + while ( candidate != null ) { + if ( (childMemory == null) || (childMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) candidate.getChild() )) ) { hasnext = true; + next = candidate; + candidate = (MultiLinkedListNode) candidate.getNext(); break; } + candidate = (MultiLinkedListNode) candidate.getNext(); } } else { hasnext = true; @@ -182,7 +183,7 @@ return hasnext; } - public Object next() { + public final Object next() { if ( this.next == null ) { this.hasNext(); } @@ -194,7 +195,7 @@ return this.current; } - public void remove() { + public final void remove() { if ( this.current != null ) { BooleanConstrainedLeftMemory.this.remove( workingMemory, (ReteTuple) current ); @@ -210,7 +211,7 @@ /** * @inheritDoc */ - public Iterator iterator() { + public final Iterator iterator() { return new Iterator() { Iterator trueIt = trueList.iterator(); Iterator falseIt = falseList.iterator(); @@ -219,7 +220,7 @@ ReteTuple current = null; ReteTuple next = null; - public boolean hasNext() { + public final boolean hasNext() { boolean hasnext = false; if ( next == null ) { if ( (currentTrue == null) && (trueIt.hasNext()) ) { @@ -254,7 +255,7 @@ return hasnext; } - public Object next() { + public final Object next() { if ( this.next == null ) { this.hasNext(); } @@ -266,7 +267,7 @@ return this.current; } - public void remove() { + public final void remove() { throw new UnsupportedOperationException( "Not possible to call remove when iterating over all elements" ); } }; @@ -277,7 +278,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#selectPossibleMatches(org.drools.WorkingMemory, org.drools.reteoo.FactHandleImpl) */ - public void selectPossibleMatches(WorkingMemory workingMemory, + public final void selectPossibleMatches(WorkingMemory workingMemory, InternalFactHandle handle) { boolean select = ((Boolean) this.extractor.getValue( handle.getObject() )).booleanValue(); select = (evaluator.getOperator()) == Evaluator.EQUAL ? select : !select; @@ -297,7 +298,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#isPossibleMatch(org.drools.util.MultiLinkedListNodeWrapper) */ - public boolean isPossibleMatch(MultiLinkedListNodeWrapper tuple) { + public final boolean isPossibleMatch(MultiLinkedListNodeWrapper tuple) { boolean isPossible = ((this.selectedList != null) && (tuple.getLinkedList() == this.selectedList)); if ( (isPossible) && (this.childMemory != null) ) { isPossible = this.childMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) tuple.getChild() ); @@ -305,7 +306,7 @@ return isPossible; } - public int size() { + public final int size() { return this.trueList.size() + this.falseList.size(); } Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/BooleanConstrainedRightMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/BooleanConstrainedRightMemory.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/BooleanConstrainedRightMemory.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -81,7 +81,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#add(org.drools.WorkingMemory, org.drools.reteoo.ObjectMatches) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, ObjectMatches matches) { MultiLinkedList list = this.getMatchingList( workingMemory, matches.getFactHandle() ); @@ -101,7 +101,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#remove(org.drools.WorkingMemory, org.drools.reteoo.ObjectMatches) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, ObjectMatches matches) { if ( this.childMemory != null ) { this.childMemory.remove( workingMemory, @@ -116,7 +116,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#add(org.drools.WorkingMemory, org.drools.util.MultiLinkedListNodeWrapper) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, MultiLinkedListNodeWrapper wrapper) { ObjectMatches matches = (ObjectMatches) wrapper.getNode(); MultiLinkedList list = this.getMatchingList( workingMemory, @@ -136,7 +136,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#remove(org.drools.WorkingMemory, org.drools.util.MultiLinkedListNodeWrapper) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, MultiLinkedListNodeWrapper wrapper) { if ( this.childMemory != null ) { this.childMemory.remove( workingMemory, @@ -150,24 +150,26 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#iterator(org.drools.WorkingMemory, org.drools.reteoo.ReteTuple) */ - public Iterator iterator(final WorkingMemory workingMemory, + public final Iterator iterator(final WorkingMemory workingMemory, final ReteTuple tuple) { this.selectPossibleMatches( workingMemory, tuple ); Iterator iterator = new Iterator() { - Iterator it = selectedList.iterator(); - ObjectMatches current = null; - ObjectMatches next = null; + ObjectMatches current = null; + ObjectMatches next = null; + ObjectMatches candidate = (ObjectMatches) selectedList.getFirst(); - public boolean hasNext() { + public final boolean hasNext() { boolean hasnext = false; if ( next == null ) { - while ( it.hasNext() ) { - next = (ObjectMatches) it.next(); - if ( (childMemory == null) || (childMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) next.getChild() )) ) { + while ( candidate != null ) { + if ( (childMemory == null) || (childMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) candidate.getChild() )) ) { hasnext = true; + next = candidate; + candidate = (ObjectMatches) candidate.getNext(); break; } + candidate = (ObjectMatches) candidate.getNext(); } } else { hasnext = true; @@ -175,7 +177,7 @@ return hasnext; } - public Object next() { + public final Object next() { if ( this.next == null ) { this.hasNext(); } @@ -187,7 +189,7 @@ return this.current; } - public void remove() { + public final void remove() { throw new UnsupportedOperationException( "Iterator.remove() should not be used to remove right side objects from right memory." ); } @@ -200,7 +202,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#isEmpty() */ - public boolean isEmpty() { + public final boolean isEmpty() { return this.trueList.isEmpty() && this.falseList.isEmpty(); } @@ -210,7 +212,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#selectPossibleMatches(org.drools.WorkingMemory, org.drools.reteoo.ReteTuple) */ - public void selectPossibleMatches(WorkingMemory workingMemory, + public final void selectPossibleMatches(WorkingMemory workingMemory, ReteTuple tuple) { boolean select = ((Boolean) declaration.getValue( tuple.get( this.column ).getObject() )).booleanValue(); select = (evaluator.getOperator()) == Evaluator.EQUAL ? select : !select; @@ -228,7 +230,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#isPossibleMatch(org.drools.util.MultiLinkedListNodeWrapper) */ - public boolean isPossibleMatch(MultiLinkedListNodeWrapper matches) { + public final boolean isPossibleMatch(MultiLinkedListNodeWrapper matches) { boolean ret = false; if ( this.selectedList != null ) { ret = matches.getLinkedList() == this.selectedList; @@ -246,7 +248,7 @@ * @param handle * @return */ - private MultiLinkedList getMatchingList(WorkingMemory workingMemory, + private final MultiLinkedList getMatchingList(WorkingMemory workingMemory, FactHandleImpl handle) { boolean select = ((Boolean) this.extractor.getValue( handle.getObject() )).booleanValue(); MultiLinkedList list = (select == true) ? this.trueList : this.falseList; @@ -259,14 +261,14 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#size() */ - public int size() { + public final int size() { return this.trueList.size() + this.falseList.size(); } /** * @inheritDoc */ - public Iterator iterator() { + public final Iterator iterator() { TreeSet set = new TreeSet( new Comparator() { public int compare(Object arg0, Object arg1) { Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/DefaultLeftMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/DefaultLeftMemory.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/DefaultLeftMemory.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -20,7 +20,6 @@ import org.drools.WorkingMemory; import org.drools.common.InternalFactHandle; -import org.drools.reteoo.FactHandleImpl; import org.drools.reteoo.ReteTuple; import org.drools.util.MultiLinkedList; import org.drools.util.MultiLinkedListNodeWrapper; @@ -49,7 +48,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#add(org.drools.WorkingMemory, org.drools.util.MultiLinkedListNodeWrapper) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, MultiLinkedListNodeWrapper tuple) { this.memory.add( tuple ); } @@ -57,7 +56,7 @@ /** * @inheritDoc */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, MultiLinkedListNodeWrapper tuple) { this.memory.remove( tuple ); } @@ -65,7 +64,7 @@ /** * @inheritDoc */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, ReteTuple tuple) { this.memory.add( tuple ); } @@ -73,7 +72,7 @@ /** * @inheritDoc */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, ReteTuple tuple) { this.memory.remove( tuple ); } @@ -81,7 +80,7 @@ /** * @inheritDoc */ - public Iterator iterator(WorkingMemory workingMemory, + public final Iterator iterator(WorkingMemory workingMemory, InternalFactHandle handle) { return this.memory.iterator(); } @@ -89,21 +88,21 @@ /** * @inheritDoc */ - public Iterator iterator() { + public final Iterator iterator() { return this.memory.iterator(); } /** * @inheritDoc */ - public boolean isEmpty() { + public final boolean isEmpty() { return this.memory.isEmpty(); } /** * @inheritDoc */ - public void selectPossibleMatches(WorkingMemory workingMemory, + public final void selectPossibleMatches(WorkingMemory workingMemory, InternalFactHandle handle) { // nothing to do. all tuples are possible matches } @@ -111,14 +110,14 @@ /** * @inheritDoc */ - public boolean isPossibleMatch(MultiLinkedListNodeWrapper tuple) { + public final boolean isPossibleMatch(MultiLinkedListNodeWrapper tuple) { return tuple.getLinkedList() == this.memory; } /** * @inheritDoc */ - public int size() { + public final int size() { return this.memory.size(); } Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/DefaultRightMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/DefaultRightMemory.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/DefaultRightMemory.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -48,7 +48,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#add(org.drools.WorkingMemory, org.drools.reteoo.ObjectMatches) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, ObjectMatches matches) { this.memory.add( matches ); } @@ -59,7 +59,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#remove(org.drools.WorkingMemory, org.drools.reteoo.ObjectMatches) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, ObjectMatches matches) { matches.getLinkedList().remove( matches ); } @@ -70,7 +70,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#add(org.drools.WorkingMemory, org.drools.util.MultiLinkedListNodeWrapper) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, MultiLinkedListNodeWrapper wrapper) { this.memory.add( wrapper ); } @@ -81,7 +81,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#remove(org.drools.WorkingMemory, org.drools.util.MultiLinkedListNodeWrapper) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, MultiLinkedListNodeWrapper wrapper) { wrapper.getLinkedList().remove( wrapper ); } @@ -91,11 +91,9 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#iterator(org.drools.WorkingMemory, org.drools.reteoo.ReteTuple) */ - public Iterator iterator(final WorkingMemory workingMemory, + public final Iterator iterator(final WorkingMemory workingMemory, final ReteTuple tuple) { - this.selectPossibleMatches( workingMemory, - tuple ); - return this.iterator(); + return this.memory.iterator(); } /** @@ -103,7 +101,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#isEmpty() */ - public boolean isEmpty() { + public final boolean isEmpty() { return this.memory.isEmpty(); } @@ -113,7 +111,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#selectPossibleMatches(org.drools.WorkingMemory, org.drools.reteoo.ReteTuple) */ - public void selectPossibleMatches(WorkingMemory workingMemory, + public final void selectPossibleMatches(WorkingMemory workingMemory, ReteTuple tuple) { // nothing to do } @@ -124,7 +122,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#isPossibleMatch(org.drools.util.MultiLinkedListNodeWrapper) */ - public boolean isPossibleMatch(MultiLinkedListNodeWrapper matches) { + public final boolean isPossibleMatch(MultiLinkedListNodeWrapper matches) { return matches.getLinkedList() == this.memory; } @@ -134,7 +132,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#size() */ - public int size() { + public final int size() { return this.memory.size(); } @@ -143,7 +141,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#iterator() */ - public Iterator iterator() { + public final Iterator iterator() { return memory.iterator(); } Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectEqualConstrLeftMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectEqualConstrLeftMemory.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectEqualConstrLeftMemory.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -26,7 +26,6 @@ import org.drools.WorkingMemory; import org.drools.common.InternalFactHandle; -import org.drools.reteoo.FactHandleImpl; import org.drools.reteoo.ReteTuple; import org.drools.rule.Declaration; import org.drools.spi.Evaluator; @@ -83,7 +82,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#add(org.drools.WorkingMemory, org.drools.reteoo.ReteTuple) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, ReteTuple tuple) { MultiLinkedList list = getTupleBucket( workingMemory, tuple ); @@ -101,7 +100,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#remove(org.drools.reteoo.ReteTuple) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, ReteTuple tuple) { if ( this.childMemory != null ) { this.childMemory.remove( workingMemory, @@ -120,7 +119,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#add(org.drools.reteoo.ReteTuple) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, MultiLinkedListNodeWrapper tuple) { MultiLinkedList list = this.getTupleBucket( workingMemory, (ReteTuple) tuple.getNode() ); @@ -141,7 +140,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#remove(org.drools.reteoo.ReteTuple) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, MultiLinkedListNodeWrapper tuple) { if ( this.childMemory != null ) { this.childMemory.remove( workingMemory, @@ -163,7 +162,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#isEmpty() */ - public boolean isEmpty() { + public final boolean isEmpty() { return memoryMap.isEmpty(); } @@ -172,26 +171,28 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#iterator(org.drools.WorkingMemory, org.drools.reteoo.FactHandleImpl) */ - public Iterator iterator(final WorkingMemory workingMemory, + public final Iterator iterator(final WorkingMemory workingMemory, final InternalFactHandle handle) { this.selectPossibleMatches( workingMemory, handle ); Iterator iterator = null; if ( this.selectedList != null ) { iterator = new Iterator() { - Iterator it = selectedList.iterator(); - MultiLinkedListNode current = null; - MultiLinkedListNode next = null; - - public boolean hasNext() { + MultiLinkedListNode current = null; + MultiLinkedListNode next = null; + MultiLinkedListNode candidate = (MultiLinkedListNode) selectedList.getFirst(); + + public final boolean hasNext() { boolean hasnext = false; if ( next == null ) { - while ( it.hasNext() ) { - next = (MultiLinkedListNode) it.next(); - if ( (childMemory == null) || (childMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) next.getChild() )) ) { + while ( candidate != null ) { + if ( (childMemory == null) || (childMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) candidate.getChild() )) ) { hasnext = true; + next = candidate; + candidate = (MultiLinkedListNode) candidate.getNext(); break; } + candidate = (MultiLinkedListNode) candidate.getNext(); } } else { hasnext = true; @@ -199,7 +200,7 @@ return hasnext; } - public Object next() { + public final Object next() { if ( this.next == null ) { this.hasNext(); } @@ -211,7 +212,7 @@ return this.current; } - public void remove() { + public final void remove() { if ( this.current != null ) { ObjectEqualConstrLeftMemory.this.remove( workingMemory, (ReteTuple) current ); @@ -230,7 +231,7 @@ /** * @inheritDoc */ - public Iterator iterator() { + public final Iterator iterator() { TreeSet set = new TreeSet( new Comparator() { public int compare(Object arg0, Object arg1) { @@ -253,7 +254,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#selectPossibleMatches(org.drools.WorkingMemory, org.drools.reteoo.FactHandleImpl) */ - public void selectPossibleMatches(WorkingMemory workingMemory, + public final void selectPossibleMatches(WorkingMemory workingMemory, InternalFactHandle handle) { Object select = this.extractor.getValue( handle.getObject() ); Integer hash = (select != null) ? new Integer( select.hashCode() ) : new Integer( 0 ); @@ -265,7 +266,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#isPossibleMatch(org.drools.util.MultiLinkedListNodeWrapper) */ - public boolean isPossibleMatch(MultiLinkedListNodeWrapper tuple) { + public final boolean isPossibleMatch(MultiLinkedListNodeWrapper tuple) { return ((this.selectedList != null) && (tuple != null) && (tuple.getLinkedList() == this.selectedList)); } @@ -277,7 +278,7 @@ * @param tuple * @return */ - private MultiLinkedList getTupleBucket(WorkingMemory workingMemory, + private final MultiLinkedList getTupleBucket(WorkingMemory workingMemory, ReteTuple tuple) { Integer hash = getTupleHash( workingMemory, tuple ); @@ -297,14 +298,14 @@ * @param tuple * @return */ - private Integer getTupleHash(WorkingMemory workingMemory, + private final Integer getTupleHash(WorkingMemory workingMemory, ReteTuple tuple) { Object select = declaration.getValue( tuple.get( this.column ).getObject() ); Integer hash = (select != null) ? new Integer( select.hashCode() ) : new Integer( 0 ); return hash; } - public int size() { + public final int size() { return this.size; } @@ -312,7 +313,7 @@ * Remove a clean memory entry * @param list */ - private void removeMemoryEntry(LinkedList list) { + private final void removeMemoryEntry(LinkedList list) { Object hash = ((KeyMultiLinkedList) list).getKey(); this.memoryMap.remove( hash ); } @@ -324,7 +325,7 @@ * * @return */ - public boolean isClean() { + public final boolean isClean() { boolean ret = true; for ( Iterator i = this.memoryMap.values().iterator(); i.hasNext(); ) { MultiLinkedList list = (MultiLinkedList) i.next(); @@ -336,7 +337,7 @@ return ret; } - private static class KeyMultiLinkedList extends MultiLinkedList { + private static final class KeyMultiLinkedList extends MultiLinkedList { private final Object key; public KeyMultiLinkedList(Object key) { Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectEqualConstrRightMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectEqualConstrRightMemory.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectEqualConstrRightMemory.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -84,7 +84,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#add(org.drools.WorkingMemory, org.drools.reteoo.ObjectMatches) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, ObjectMatches matches) { MultiLinkedList list = this.getFactList( workingMemory, matches.getFactHandle() ); @@ -104,7 +104,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#remove(org.drools.WorkingMemory, org.drools.reteoo.ObjectMatches) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, ObjectMatches matches) { if ( this.childMemory != null ) { this.childMemory.remove( workingMemory, @@ -125,7 +125,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#add(org.drools.WorkingMemory, org.drools.util.MultiLinkedListNodeWrapper) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, MultiLinkedListNodeWrapper wrapper) { ObjectMatches matches = (ObjectMatches) wrapper.getNode(); MultiLinkedList list = this.getFactList( workingMemory, @@ -146,7 +146,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#remove(org.drools.WorkingMemory, org.drools.util.MultiLinkedListNodeWrapper) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, MultiLinkedListNodeWrapper matches) { if ( this.childMemory != null ) { this.childMemory.remove( workingMemory, @@ -165,26 +165,28 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#iterator(org.drools.WorkingMemory, org.drools.reteoo.ReteTuple) */ - public Iterator iterator(final WorkingMemory workingMemory, + public final Iterator iterator(final WorkingMemory workingMemory, final ReteTuple tuple) { this.selectPossibleMatches( workingMemory, tuple ); Iterator iterator = null; if ( this.selectedList != null ) { iterator = new Iterator() { - Iterator it = selectedList.iterator(); - ObjectMatches current = null; - ObjectMatches next = null; + ObjectMatches current = null; + ObjectMatches next = null; + ObjectMatches candidate = (ObjectMatches) selectedList.getFirst(); - public boolean hasNext() { + public final boolean hasNext() { boolean hasnext = false; if ( next == null ) { - while ( it.hasNext() ) { - next = (ObjectMatches) it.next(); - if ( (childMemory == null) || (childMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) next.getChild() )) ) { + while ( candidate != null ) { + if ( (childMemory == null) || (childMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) candidate.getChild() )) ) { hasnext = true; + next = candidate; + candidate = (ObjectMatches) candidate.getNext(); break; } + candidate = (ObjectMatches) candidate.getNext(); } } else { hasnext = true; @@ -192,7 +194,7 @@ return hasnext; } - public Object next() { + public final Object next() { if ( this.next == null ) { this.hasNext(); } @@ -204,7 +206,7 @@ return this.current; } - public void remove() { + public final void remove() { throw new UnsupportedOperationException( "Iterator.remove() should not be used to remove right side objects from right memory." ); } }; @@ -219,7 +221,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#isEmpty() */ - public boolean isEmpty() { + public final boolean isEmpty() { return this.memoryMap.isEmpty(); } @@ -228,7 +230,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#selectPossibleMatches(org.drools.WorkingMemory, org.drools.reteoo.ReteTuple) */ - public void selectPossibleMatches(WorkingMemory workingMemory, + public final void selectPossibleMatches(WorkingMemory workingMemory, ReteTuple tuple) { Object select = declaration.getValue( tuple.get( this.column ).getObject() ); Integer hash = (select != null) ? new Integer( select.hashCode() ) : new Integer( 0 ); @@ -240,7 +242,7 @@ } } - public boolean isPossibleMatch(MultiLinkedListNodeWrapper wrapper) { + public final boolean isPossibleMatch(MultiLinkedListNodeWrapper wrapper) { boolean ret = false; if ( this.selectedList != null ) { ret = wrapper.getLinkedList() == this.selectedList; @@ -258,7 +260,7 @@ * @param handle * @return */ - private MultiLinkedList getFactList(WorkingMemory workingMemory, + private final MultiLinkedList getFactList(WorkingMemory workingMemory, InternalFactHandle handle) { Object select = this.extractor.getValue( handle.getObject() ); Integer hash = (select != null) ? new Integer( select.hashCode() ) : new Integer( 0 ); @@ -271,12 +273,12 @@ return list; } - private void removeMapEntry(KeyMultiLinkedList list) { + private final void removeMapEntry(KeyMultiLinkedList list) { Object hash = list.getKey(); this.memoryMap.remove( hash ); } - public int size() { + public final int size() { return this.memorySize; } @@ -287,7 +289,7 @@ * * @return */ - public boolean isClean() { + public final boolean isClean() { boolean ret = true; for ( Iterator i = this.memoryMap.values().iterator(); i.hasNext(); ) { MultiLinkedList list = (MultiLinkedList) i.next(); @@ -302,7 +304,7 @@ /** * @inheritDoc */ - public Iterator iterator() { + public final Iterator iterator() { TreeSet set = new TreeSet( new Comparator() { public int compare(Object arg0, Object arg1) { Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectNotEqualConstrLeftMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectNotEqualConstrLeftMemory.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectNotEqualConstrLeftMemory.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -23,7 +23,6 @@ import org.drools.WorkingMemory; import org.drools.common.InternalFactHandle; -import org.drools.reteoo.FactHandleImpl; import org.drools.reteoo.ReteTuple; import org.drools.rule.Declaration; import org.drools.spi.Evaluator; @@ -80,7 +79,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#add(org.drools.WorkingMemory, org.drools.reteoo.ReteTuple) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, ReteTuple tuple) { this.memoryMasterList.add( tuple ); @@ -103,7 +102,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#remove(org.drools.reteoo.ReteTuple) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, ReteTuple tuple) { if ( this.innerMemory != null ) { this.innerMemory.remove( workingMemory, @@ -122,7 +121,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#add(org.drools.reteoo.ReteTuple) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, MultiLinkedListNodeWrapper tuple) { this.memoryMasterList.add( tuple ); @@ -147,7 +146,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#remove(org.drools.reteoo.ReteTuple) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, MultiLinkedListNodeWrapper tuple) { if ( this.innerMemory != null ) { this.innerMemory.remove( workingMemory, @@ -168,7 +167,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#isEmpty() */ - public boolean isEmpty() { + public final boolean isEmpty() { return memoryMasterList.isEmpty(); } @@ -177,26 +176,28 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#iterator(org.drools.WorkingMemory, org.drools.reteoo.FactHandleImpl) */ - public Iterator iterator(final WorkingMemory workingMemory, + public final Iterator iterator(final WorkingMemory workingMemory, final InternalFactHandle handle) { this.selectPossibleMatches( workingMemory, handle ); Iterator iterator = new Iterator() { - Iterator it = memoryMasterList.iterator(); - MultiLinkedListNode current = null; - MultiLinkedListNode next = null; + MultiLinkedListNode current = null; + MultiLinkedListNode next = null; + MultiLinkedListNode candidate = (MultiLinkedListNode) memoryMasterList.getFirst(); - public boolean hasNext() { + public final boolean hasNext() { boolean hasnext = false; if ( next == null ) { - while ( it.hasNext() ) { - next = (MultiLinkedListNode) it.next(); - if ( next.getChild().getLinkedList() != noMatchList ) { - if ( (innerMemory == null) || (innerMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) next.getChild().getChild() )) ) { + while ( candidate != null ) { + if ( candidate.getChild().getLinkedList() != noMatchList ) { + if ( (innerMemory == null) || (innerMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) candidate.getChild().getChild() )) ) { hasnext = true; + next = candidate; + candidate = (MultiLinkedListNode) candidate.getNext(); break; } } + candidate = (MultiLinkedListNode) candidate.getNext(); } } else { hasnext = true; @@ -204,7 +205,7 @@ return hasnext; } - public Object next() { + public final Object next() { if ( this.next == null ) { this.hasNext(); } @@ -216,7 +217,7 @@ return this.current; } - public void remove() { + public final void remove() { if ( this.current != null ) { // Iterator is always called on the outer most memory, // so elements shall always be ReteTuples @@ -233,7 +234,7 @@ /** * @inheritDoc */ - public Iterator iterator() { + public final Iterator iterator() { return this.memoryMasterList.iterator(); } @@ -242,7 +243,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#selectPossibleMatches(org.drools.WorkingMemory, org.drools.reteoo.FactHandleImpl) */ - public void selectPossibleMatches(WorkingMemory workingMemory, + public final void selectPossibleMatches(WorkingMemory workingMemory, InternalFactHandle handle) { Object select = this.extractor.getValue( handle.getObject() ); this.noMatchList = (MultiLinkedList) this.memoryMap.get( select ); @@ -253,7 +254,7 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#isPossibleMatch(org.drools.util.MultiLinkedListNodeWrapper) */ - public boolean isPossibleMatch(MultiLinkedListNodeWrapper tuple) { + public final boolean isPossibleMatch(MultiLinkedListNodeWrapper tuple) { boolean ret = false; if ( (tuple != null) && (tuple.getChild() != null) && (tuple.getChild().getLinkedList() != null) ) { ret = (tuple.getChild().getLinkedList() != this.noMatchList); @@ -272,7 +273,7 @@ * @param tuple * @return */ - private MultiLinkedList getTupleBucket(WorkingMemory workingMemory, + private final MultiLinkedList getTupleBucket(WorkingMemory workingMemory, ReteTuple tuple) { Object key = getTupleKey( workingMemory, tuple ); @@ -292,7 +293,7 @@ * @param tuple * @return */ - private Object getTupleKey(WorkingMemory workingMemory, + private final Object getTupleKey(WorkingMemory workingMemory, ReteTuple tuple) { Object select = declaration.getValue( tuple.get( this.column ).getObject() ); return select; @@ -304,14 +305,14 @@ * * @see org.drools.reteoo.beta.BetaLeftMemory#size() */ - public int size() { + public final int size() { return this.memoryMasterList.size(); } /** * @param list */ - private void removeMemoryEntry(LinkedList list) { + private final void removeMemoryEntry(LinkedList list) { this.memoryMap.remove( ((KeyMultiLinkedList) list).getKey() ); } @@ -322,7 +323,7 @@ * * @return */ - public boolean isClean() { + public final boolean isClean() { boolean ret = true; for ( Iterator i = this.memoryMap.values().iterator(); i.hasNext(); ) { MultiLinkedList list = (MultiLinkedList) i.next(); Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectNotEqualConstrRightMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectNotEqualConstrRightMemory.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/beta/ObjectNotEqualConstrRightMemory.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -23,7 +23,6 @@ import org.drools.WorkingMemory; import org.drools.common.InternalFactHandle; -import org.drools.reteoo.FactHandleImpl; import org.drools.reteoo.ObjectMatches; import org.drools.reteoo.ReteTuple; import org.drools.rule.Declaration; @@ -81,7 +80,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#add(org.drools.WorkingMemory, org.drools.reteoo.ObjectMatches) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, ObjectMatches matches) { // adding to master list this.memoryMasterList.add( matches ); @@ -109,7 +108,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#remove(org.drools.WorkingMemory, org.drools.reteoo.ObjectMatches) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, ObjectMatches matches) { if ( this.childMemory != null ) { // removing from inner indexes @@ -137,7 +136,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#add(org.drools.WorkingMemory, org.drools.util.MultiLinkedListNodeWrapper) */ - public void add(WorkingMemory workingMemory, + public final void add(WorkingMemory workingMemory, MultiLinkedListNodeWrapper matches) { ObjectMatches om = (ObjectMatches) matches.getNode(); @@ -167,7 +166,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#remove(org.drools.WorkingMemory, org.drools.util.MultiLinkedListNodeWrapper) */ - public void remove(WorkingMemory workingMemory, + public final void remove(WorkingMemory workingMemory, MultiLinkedListNodeWrapper matches) { if ( this.childMemory != null ) { // removing from inner indexes @@ -194,26 +193,29 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#iterator(org.drools.WorkingMemory, org.drools.reteoo.ReteTuple) */ - public Iterator iterator(final WorkingMemory workingMemory, + public final Iterator iterator(final WorkingMemory workingMemory, final ReteTuple tuple) { this.selectPossibleMatches( workingMemory, tuple ); Iterator iterator = new Iterator() { - Iterator it = memoryMasterList.iterator(); - ObjectMatches current = null; - ObjectMatches next = null; + //Iterator it = memoryMasterList.iterator(); + ObjectMatches current = null; + ObjectMatches next = null; + ObjectMatches candidate = (ObjectMatches) memoryMasterList.getFirst(); - public boolean hasNext() { + public final boolean hasNext() { boolean hasnext = false; if ( next == null ) { - while ( it.hasNext() ) { - next = (ObjectMatches) it.next(); - if ( next.getChild().getLinkedList() != noMatchList ) { - if ( (childMemory == null) || (childMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) next.getChild().getChild() )) ) { + while ( candidate != null ) { + if ( candidate.getChild().getLinkedList() != noMatchList ) { + if ( (childMemory == null) || (childMemory.isPossibleMatch( (MultiLinkedListNodeWrapper) candidate.getChild().getChild() )) ) { hasnext = true; + next = candidate; + candidate = (ObjectMatches) candidate.getNext(); break; } } + candidate = (ObjectMatches) candidate.getNext(); } } else { hasnext = true; @@ -221,7 +223,7 @@ return hasnext; } - public Object next() { + public final Object next() { if ( this.next == null ) { this.hasNext(); } @@ -233,7 +235,7 @@ return this.current; } - public void remove() { + public final void remove() { throw new UnsupportedOperationException( "Iterator.remove() should not be used to remove right side objects from right memory." ); } @@ -246,7 +248,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#isEmpty() */ - public boolean isEmpty() { + public final boolean isEmpty() { return this.memoryMap.isEmpty(); } @@ -255,7 +257,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#selectPossibleMatches(org.drools.WorkingMemory, org.drools.reteoo.ReteTuple) */ - public void selectPossibleMatches(WorkingMemory workingMemory, + public final void selectPossibleMatches(WorkingMemory workingMemory, ReteTuple tuple) { Object select = declaration.getValue( tuple.get( this.column ).getObject() ); Integer hash = (select != null) ? new Integer( select.hashCode() ) : new Integer( 0 ); @@ -272,7 +274,7 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#isPossibleMatch(org.drools.reteoo.FactHandleImpl) */ - public boolean isPossibleMatch(MultiLinkedListNodeWrapper matches) { + public final boolean isPossibleMatch(MultiLinkedListNodeWrapper matches) { boolean ret = false; if ( (matches != null) && (matches.getChild() != null) && (matches.getChild().getLinkedList() != null) ) { ret = (matches.getChild().getLinkedList() != noMatchList); @@ -292,7 +294,7 @@ * @param handle * @return */ - private MultiLinkedList getFactList(WorkingMemory workingMemory, + private final MultiLinkedList getFactList(WorkingMemory workingMemory, InternalFactHandle handle) { Object select = this.extractor.getValue( handle.getObject() ); Integer hash = (select != null) ? new Integer( select.hashCode() ) : new Integer( 0 ); @@ -311,14 +313,14 @@ * * @see org.drools.reteoo.beta.BetaRightMemory#size() */ - public int size() { + public final int size() { return this.memoryMasterList.size(); } /** * @param matches */ - private void removeMemoryEntry(MultiLinkedList list) { + private final void removeMemoryEntry(MultiLinkedList list) { this.memoryMap.remove( ((KeyMultiLinkedList) list).getKey() ); } @@ -329,7 +331,7 @@ * * @return */ - public boolean isClean() { + public final boolean isClean() { boolean ret = true; for ( Iterator i = this.memoryMap.values().iterator(); i.hasNext(); ) { MultiLinkedList list = (MultiLinkedList) i.next(); @@ -341,7 +343,7 @@ return ret; } - public Iterator iterator() { + public final Iterator iterator() { return this.memoryMasterList.iterator(); } Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/LinkedList.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/LinkedList.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/LinkedList.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -104,7 +104,7 @@ * @return * The first <code>LinkedListNode</code>. */ - public LinkedListNode getFirst() { + public final LinkedListNode getFirst() { return this.firstNode; } @@ -113,7 +113,7 @@ * @return * The last <code>LinkedListNode</code>. */ - public LinkedListNode getLast() { + public final LinkedListNode getLast() { return this.lastNode; } @@ -167,7 +167,7 @@ * @return * boolean value indicating the empty status of the list */ - public boolean isEmpty() { + public final boolean isEmpty() { return (this.firstNode == null); } @@ -183,7 +183,7 @@ * @return * return size of the list as an int */ - public int size() { + public final int size() { return this.size; } Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Chosen.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Chosen.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Chosen.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -21,7 +21,7 @@ import java.io.Serializable; -public class Chosen +public final class Chosen implements Serializable { @@ -39,19 +39,19 @@ this.hobby = hobby; } - public int getId() { + public final int getId() { return this.id; } - public String getGuestName() { + public final String getGuestName() { return this.guestName; } - public Hobby getHobby() { + public final Hobby getHobby() { return this.hobby; } - public String toString() { + public final String toString() { return "{Chosen id=" + this.id + ", name=" + this.guestName + ", hobbies=" + this.hobby + "}"; } } \ No newline at end of file Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Context.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Context.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Context.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -21,7 +21,7 @@ import java.io.Serializable; -public class Context +public final class Context implements Serializable { @@ -30,6 +30,14 @@ public static final int MAKE_PATH = 2; public static final int CHECK_DONE = 3; public static final int PRINT_RESULTS = 4; + + public static final String[] stateStrings = { + "START_UP", + "ASSIGN_SEATS", + "MAKE_PATH", + "CHECK_DONE", + "PRINT_RESULTS" + }; private int state; @@ -45,35 +53,23 @@ this.state = state; } - public void setState(int state) { + public final void setState(int state) { this.state = state; } - public boolean isState(int state) { + public final boolean isState(int state) { return this.state == state; } - public int getState() { + public final int getState() { return this.state; } - public String getStringValue() { - switch ( this.state ) { - case 0 : - return "START_UP"; - case 1 : - return "ASSIGN_SEATS"; - case 2 : - return "MAKE_PATH"; - case 3 : - return "CHECK_DONE"; - case 4 : - return "PRINT_RESULTS"; - } - return ""; + public final String getStringValue() { + return stateStrings[this.state]; } - public String toString() { + public final String toString() { return "[Context state=" + getStringValue() + "]"; } } \ No newline at end of file Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Count.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Count.java 2006-04-26 13:42:09 UTC (rev 3973) +++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/Count.java 2006-04-26 14:56:28 UTC (rev 3974) @@ -17,7 +17,7 @@ -public class Count { +public final class Count { private int value; public Count(int value) { @@ -25,19 +25,19 @@ this.value = value; } - public int getValue() { + public final int getValue() { return this.value; } - public void setValue(int value) { + public final void setValue(int value) { this.value = value; ... [truncated message content] |
From: <jbo...@li...> - 2006-04-26 13:08:41
|
Author: kev...@jb... Date: 2006-04-26 09:08:34 -0400 (Wed, 26 Apr 2006) New Revision: 3972 Modified: labs/jbosstm/trunk/ArjunaJTS/INSTALL Log: Updated to include dependency on Corba ORB Modified: labs/jbosstm/trunk/ArjunaJTS/INSTALL =================================================================== --- labs/jbosstm/trunk/ArjunaJTS/INSTALL 2006-04-26 12:57:58 UTC (rev 3971) +++ labs/jbosstm/trunk/ArjunaJTS/INSTALL 2006-04-26 13:08:34 UTC (rev 3972) @@ -31,6 +31,7 @@ <mbean code="com.arjuna.ats.jbossatx.jts.TransactionManagerService" name="jboss:service=TransactionManager"> + <depends>jboss:service=CorbaORB</depends> <attribute name="TransactionTimeout">300</attribute> </mbean> |
From: <jbo...@li...> - 2006-04-26 12:58:11
|
Author: mic...@jb... Date: 2006-04-26 08:57:58 -0400 (Wed, 26 Apr 2006) New Revision: 3971 Modified: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EmptyColumn.drl Log: fixed rule name Modified: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EmptyColumn.drl =================================================================== --- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EmptyColumn.drl 2006-04-26 12:46:44 UTC (rev 3970) +++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EmptyColumn.drl 2006-04-26 12:57:58 UTC (rev 3971) @@ -4,7 +4,7 @@ global java.util.List list; -rule simple rule +rule "simple rule" when Cheese( ) then |
Author: mar...@jb... Date: 2006-04-26 08:46:44 -0400 (Wed, 26 Apr 2006) New Revision: 3970 Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EmptyColumn.drl labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/lang/test_EmptyColumn.drl Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/RuleParserTest.java Log: JBRULES-239 NullPointer for Empty Columns -Added parser and build tests for empty coloumns Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java =================================================================== --- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java 2006-04-26 06:45:18 UTC (rev 3969) +++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java 2006-04-26 12:46:44 UTC (rev 3970) @@ -88,7 +88,34 @@ assertEquals( new Integer( 5 ), list.get( 0 ) ); } + + public void testEmptyColumn() throws Exception { + //pre build the package + PackageBuilder builder = new PackageBuilder(); + builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_EmptyColumn.drl" ) ) ); + Package pkg = builder.getPackage(); + //add the package to a rulebase + RuleBase ruleBase = getRuleBase(); + ruleBase.addPackage( pkg ); + + WorkingMemory workingMemory = ruleBase.newWorkingMemory(); + + List list = new ArrayList(); + workingMemory.setGlobal( "list", + list ); + + Cheese stilton = new Cheese( "stilton", + 5 ); + workingMemory.assertObject( stilton ); + + workingMemory.fireAllRules(); + + assertEquals( new Integer( 5 ), + list.get( 0 ) ); + } + + public void testHelloWorld() throws Exception { //read in the source Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/RuleParserTest.java =================================================================== --- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/RuleParserTest.java 2006-04-26 06:45:18 UTC (rev 3969) +++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/RuleParserTest.java 2006-04-26 12:46:44 UTC (rev 3970) @@ -259,6 +259,20 @@ assertFalse( parser.hasErrors() ); } + + public void testEmptyColumn() throws Exception { + RuleParser ruleParser = parseResource( "test_EmptyColumn.drl" ); + ruleParser.compilation_unit(); + PackageDescr packageDescr = ruleParser.getPackageDescr(); + assertEquals( 1, packageDescr.getRules().size() ); + RuleDescr ruleDescr = (RuleDescr) packageDescr.getRules().get( 0 ); + assertNotNull( ruleDescr.getLhs() ); + assertEquals( 1, ruleDescr.getLhs().getDescrs().size() ); + ColumnDescr columnDescr = ( ColumnDescr ) ruleDescr.getLhs().getDescrs().get( 0 ); + assertEquals( 0, columnDescr.getDescrs().size() ); //this may be null, not sure as the test doesn't get this far... + assertEquals( "Cheese", columnDescr.getObjectType() ); + + } public void testSimpleRule() throws Exception { RuleDescr rule = parseResource( "simple_rule.drl" ).rule(); Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EmptyColumn.drl =================================================================== --- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EmptyColumn.drl 2006-04-26 06:45:18 UTC (rev 3969) +++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EmptyColumn.drl 2006-04-26 12:46:44 UTC (rev 3970) @@ -0,0 +1,12 @@ +package org.drools.test; + +import org.drools.Cheese; + +global java.util.List list; + +rule simple rule + when + Cheese( ) + then + list.add( cheese ); +end \ No newline at end of file Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/lang/test_EmptyColumn.drl =================================================================== --- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/lang/test_EmptyColumn.drl 2006-04-26 06:45:18 UTC (rev 3969) +++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/lang/test_EmptyColumn.drl 2006-04-26 12:46:44 UTC (rev 3970) @@ -0,0 +1,9 @@ +package org.drools.test; + +import org.drools.Cheese; + +rule simple rule + when + Cheese( ) + then +end \ No newline at end of file |
From: <jbo...@li...> - 2006-04-26 06:45:24
|
Author: mic...@jb... Date: 2006-04-26 02:45:18 -0400 (Wed, 26 Apr 2006) New Revision: 3969 Modified: labs/jbossrules/trunk/documentation/manual/en/master.xml Log: added leaps Modified: labs/jbossrules/trunk/documentation/manual/en/master.xml =================================================================== --- labs/jbossrules/trunk/documentation/manual/en/master.xml 2006-04-26 06:43:04 UTC (rev 3968) +++ labs/jbossrules/trunk/documentation/manual/en/master.xml 2006-04-26 06:45:18 UTC (rev 3969) @@ -74,7 +74,7 @@ <xi:include href="Chapter-Rule_Engine/Section-Rete_Algorithm.xml" /> - <!-- MISSING !! <xi:include href="Chapter-Rule_Engine/Section-Leaps_Algorithm.xml" /> --> + <xi:include href="Chapter-Rule_Engine/Section-Leaps_Algorithm.xml" /> <xi:include href="Chapter-Rule_Engine/Section-Rule_Base.xml" /> |
From: <jbo...@li...> - 2006-04-26 06:43:09
|
Author: mic...@jb... Date: 2006-04-26 02:43:04 -0400 (Wed, 26 Apr 2006) New Revision: 3968 Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Why_use_a_Rule_Engine.xml Log: Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Why_use_a_Rule_Engine.xml =================================================================== --- labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Why_use_a_Rule_Engine.xml 2006-04-26 03:29:03 UTC (rev 3967) +++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Why_use_a_Rule_Engine.xml 2006-04-26 06:43:04 UTC (rev 3968) @@ -2,10 +2,14 @@ <section> <title>Why use a Rule Engine</title> - <para>Two questions often asked are</para> + <para>Some questions often asked are</para> <orderedlist> <listitem> + <para>When should I use a rule engine ?</para> + </listitem> + + <listitem> <para>What advantage does this have over hand coded "if ..... then" approaches?</para> </listitem> @@ -18,49 +22,157 @@ </listitem> </orderedlist> - <para></para> + <para>We will attempt to adderess these below.</para> - <itemizedlist> - <listitem> - <para>Declarative Programming</para> + <section> + <title>Summary of advantages of a rule engine</title> - <para>Rule englines allow you to say "What to do" not "How to do - it".</para> - </listitem> + <itemizedlist> + <listitem> + <para>Declarative Programming</para> - <listitem> - <para>Logic and Data Separation</para> - </listitem> + <para>Rule englines allow you to say "What to do" not "How to do + it".</para> - <listitem> - <para>Speed and Scalability</para> + <para>They key advantage of this point is that it can make it easy to + express solutions to hard problems, and consequently have those + solutions verified (rules are much easier to read then code).</para> - <para>The Rete algorithm, and its descendents such as Drools' - Reteoo,</para> - </listitem> + <para>Rule systems are capable of solving very very hard problems, yet + providing a solution that is able to explain why a "decision" was made + (not so easy with other types of AI systems like neural networks, or + say, my brain - I have no idea why I scratched the side of the + car).</para> + </listitem> - <listitem> - <para>Centralisation Knowledge</para> - </listitem> + <listitem> + <para>Logic and Data Separation</para> - <listitem> - <para>Tool Integration</para> - </listitem> - </itemizedlist> + <para>Your data is in your domain objects, the logic is in the rules. + This is fundamentally breaking the OO coupling of data and logic (this + can be an advantage as well as a disadvantage depending on your point + of view). The upshot is that the logic can be much easier to maintain + as there are changes in the future, as the logic is all layed out in + rules.</para> + </listitem> + <listitem> + <para>Speed and Scalability</para> + + <para>The Rete algorithm, Leaps algorithm, and its descendents such as + Drools' Reteoo (and Leaps), provide very efficient ways of matching + rule patterns to your domain object data. These are especially + efficient when you have datasets that do not change entirely (as the + rule engine can remember past matches). These algorithms are battle + proven.</para> + </listitem> + + <listitem> + <para>Centralisation of Knowledge</para> + + <para>By using rules, you are creating a repository of knowlegde (a + knowledebase) which is executable. This means its a single point of + truth, for business policy (for instance) - ideally rules are so + readable, they also serve as the documentation.</para> + </listitem> + + <listitem> + <para>Tool Integration</para> + + <para>Tools such as eclipse (and in future, Web based UIs) provide + ways to edit and manage rules and get immediate feedback, validation + and content assistance. Auditing and debugging tools are also + available.</para> + </listitem> + + <listitem> + <para>Explanation facility</para> + + <para>Rule systems effectively provide an "explanation facility" by + being able to log the "decisions" made by the rule engine (and why the + decisions were made).</para> + </listitem> + + <listitem> + <para>Understandable rules (readable by domain experts)</para> + + <para>By creating object models (and optionally Domain Specific + Languages) that model your problem domain, rules can look very close + to natural language. They lend themselves to logic that is + understandable to domain experts who may be non technical (as all the + program plumbing is in the usual code, hidden away).</para> + </listitem> + </itemizedlist> + </section> + <section> - <title>When not to use a rule engine</title> - <para> - To quote a Drools mailing list regular (Dave Hamu): - "It seems to me that in the excitement of working -with rules engines, that people forget that a rules engine is only one -piece of a complex application or solution. Rules engines are not -really intended to handle workflow or process executions nor are -workflow engines or process management tools designed to do rules. Use -the right tool for the job. Sure, a pair of pliers can be used as a -hammering tool in a pinch, but that's not what it's designed for." + <title>When should you use a rule engine</title> - </para> + <para>The shortest answer to this is "when there is no satisfactory + traditional programming approach to solve the problem.". Given that short + answer, some more explanation is required. The reason why there is no + "traditional" approach is possibly one of the following: <itemizedlist> + <listitem> + <para>The problem is just too fiddly for traditional code. </para> + + <para>The problem may not be complex, but you can't see a non + fragile way of building it.</para> + + + </listitem> + + <listitem> + <para>The problem is beyond any obvious algorithm based solution.</para> + </listitem> + + <listitem> + <para>The logic changes often </para> + + <para>The logic itself may be simple (but doesn't have to be) but + the rules change just too often. In many organisations, software + releases are few and far between, and rules can help provide the + "agility" that is needed, and expected these days (in a reasonably + safe way).</para> + + + </listitem> + </itemizedlist> + </para> + + <para> + Of course if rules are a new technology in your project teams experience, the overhead in getting going must be factored in. Its not a trivial technology, but we try to make it easier. + </para> + + <para>Typically in a modern OO application you would use a rule engine to + contain key parts of your business logic (what that means of course + depends on the application) - ESPECIALLY the REALLY MESSY parts !. This is + an inversion of the OO concept of encapsulating all the logic inside your + objects. This is not to say that you throw out OO practices, on the + contrary in any real world application, business logic is just one part of + the application. If you ever notice lots of "if" "else" "switch" and other + messy logic in your code that just doesn't feel right (and you keep coming + back to fix it - either because you got it wrong, or the logic/your + understanding changes) - think about using rules. If you are faced with + tough problems of which there are no algorithms or patterns for, consider + rules.</para> + + <para>Rules could be used embedded in your application, or perhaps as a + service. Often rules work best as "stateful" component - hence they are + often an integral part of an application. However, there have been + successful cases of creating reusable rul eservices which are + stateless.</para> </section> + <section> + <title>When not to use a rule engine</title> + + <para>To quote a Drools mailing list regular (Dave Hamu): "It seems to me + that in the excitement of working with rules engines, that people forget + that a rules engine is only one piece of a complex application or + solution. Rules engines are not really intended to handle workflow or + process executions nor are workflow engines or process management tools + designed to do rules. Use the right tool for the job. Sure, a pair of + pliers can be used as a hammering tool in a pinch, but that's not what + it's designed for."</para> + </section> </section> \ No newline at end of file |
From: <jbo...@li...> - 2006-04-26 03:29:12
|
Author: mic...@jb... Date: 2006-04-25 23:29:03 -0400 (Tue, 25 Apr 2006) New Revision: 3967 Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-What_is_a_Rule_Engine.xml Log: Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-What_is_a_Rule_Engine.xml =================================================================== --- labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-What_is_a_Rule_Engine.xml 2006-04-26 03:23:59 UTC (rev 3966) +++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-What_is_a_Rule_Engine.xml 2006-04-26 03:29:03 UTC (rev 3967) @@ -4,47 +4,58 @@ <section> <title>Background</title> - <para> - A rule engine like Drools is centred around the concept of production rules (IF conditions THEN actions). Emil Leon Post (http://en.wikipedia.org/wiki/Emil_Leon_Post) was the first to use production systems in logic - as a consequence of this he was able to prove that any logical system (including mathematics) could be written with production rules. Quite an amazing proof, this essentially means that you can represent any system/problem with production rules (back in the real world there are constraints of processing power and efficiency of course !). - </para> - <para> - You may also have heard of "Expert Systems" in the context of rule engines. You can think of expert systems as a rule engine + the codification of knowledge for a specific problem domain (+ a user interface !). In that sense, Drools is a platform for expert systems. Historically, rule engines popularity grew out of expert systems success (for example, EMYCIN was one of the first "shells" for an expert system, which was created from the MYCIN medical diagnosis expert system). - </para> + <para>A rule engine like Drools is centred around the concept of + production rules (IF conditions THEN actions). Emil Leon Post + (http://en.wikipedia.org/wiki/Emil_Leon_Post) was the first to use + production systems in logic - as a consequence of this he was able to + prove that any logical system (including mathematics) could be written + with production rules. Quite an amazing proof, this essentially means that + you can represent any system/problem with production rules (back in the + real world there are constraints of processing power and efficiency of + course !).</para> + <para>You may also have heard of "Expert Systems" in the context of rule + engines. You can think of expert systems as a rule engine + the + codification of knowledge for a specific problem domain (+ a user + interface !). In that sense, Drools is a platform for expert systems. + Historically, rule engines popularity grew out of expert systems success + (for example, EMYCIN was one of the first "shells" for an expert system, + which was created from the MYCIN medical diagnosis expert system).</para> </section> <section> <title>Rules</title> - <para>A <indexterm> - <primary>Rule</primary> - </indexterm>Rule is the codification of business knowledge. A Rule has - attributes, a Left Hand Side (LHS) and a Right Hand Side (RHS). Drools - allows the following attributes:</para> - <itemizedlist> - <listitem> - <para>salience</para> - </listitem> + <para>A <indexterm> + <primary>Rule</primary> + </indexterm>Rule is the codification of business knowledge. A Rule has + attributes, a Left Hand Side (LHS) and a Right Hand Side (RHS). Drools + allows the following attributes:</para> - <listitem> - <para>agenda-group</para> - </listitem> + <itemizedlist> + <listitem> + <para>salience</para> + </listitem> - <listitem> - <para>no-loop</para> - </listitem> + <listitem> + <para>agenda-group</para> + </listitem> - <listitem> - <para>auto-focus</para> - </listitem> + <listitem> + <para>no-loop</para> + </listitem> - <listitem> - <para>duration</para> - </listitem> - </itemizedlist> + <listitem> + <para>auto-focus</para> + </listitem> - <programlisting>rule “<name>” + <listitem> + <para>duration</para> + </listitem> + </itemizedlist> + + <programlisting>rule “<name>” <attribute> <value> when <LHS> @@ -53,25 +64,25 @@ end </programlisting> - <para>The LHS of the Rule consists of one or more Conditions. As the Rule - Engine is made aware of new data or changes to existing data it matches the - data against the Conditions, when all the Conditions are met and true the - RHS, and its actions, are executed; the RHS, called the <indexterm> - <primary>Consequence</primary> - </indexterm>Consequence. The LHS and the RHS is analogous to:</para> + <para>The LHS of the Rule consists of one or more Conditions. As the Rule + Engine is made aware of new data or changes to existing data it matches + the data against the Conditions, when all the Conditions are met and true + the RHS, and its actions, are executed; the RHS, called the <indexterm> + <primary>Consequence</primary> + </indexterm>Consequence. The LHS and the RHS is analogous to:</para> - <programlisting>if ( <LHS> ) { + <programlisting>if ( <LHS> ) { <RHS> }</programlisting> - <para>Rules are associated with a namespace via the - <literal>package</literal> keyword; other Rule Engines may call this a - <indexterm> - <primary>Rule Set</primary> - </indexterm>Rule Set. A Package declares imports, global variables, - functions and rules.</para> + <para>Rules are associated with a namespace via the + <literal>package</literal> keyword; other Rule Engines may call this a + <indexterm> + <primary>Rule Set</primary> + </indexterm>Rule Set. A Package declares imports, global variables, + functions and rules.</para> - <programlisting>package com.sample + <programlisting>package com.sample import java.util.List import com.sample.Cheese @@ -90,174 +101,175 @@ cheeses.add( cheese ); end</programlisting> - <para>The process of matching the new or existing modified data against - rules is called <indexterm> - <primary>Pattern Matching</primary> - </indexterm> Pattern Matching, the engine which does this matching is the - <indexterm> - <primary>Inference Engine</primary> - </indexterm>Inference Engine. The Rule's are referred to as the <indexterm> - <primary>Production Memory</primary> - </indexterm>Production Memory and the data that the Inference Engine - matches against is the <indexterm> - <primary>WorkingMemory</primary> - </indexterm>Working Memory. the Agenda manages the execution of the - matched Rules. There are a number of algorithms used for Pattern Matching by - Inference Engines including:</para> + <para>The process of matching the new or existing modified data against + rules is called <indexterm> + <primary>Pattern Matching</primary> + </indexterm> Pattern Matching, the engine which does this matching is + the <indexterm> + <primary>Inference Engine</primary> + </indexterm>Inference Engine. The Rule's are referred to as the + <indexterm> + <primary>Production Memory</primary> + </indexterm>Production Memory and the data that the Inference Engine + matches against is the <indexterm> + <primary>WorkingMemory</primary> + </indexterm>Working Memory. the Agenda manages the execution of the + matched Rules. There are a number of algorithms used for Pattern Matching + by Inference Engines including:</para> - <itemizedlist> - <listitem> - <para>Linear</para> - </listitem> + <itemizedlist> + <listitem> + <para>Linear</para> + </listitem> - <listitem> - <para>Rete</para> - </listitem> + <listitem> + <para>Rete</para> + </listitem> - <listitem> - <para>Treat</para> - </listitem> + <listitem> + <para>Treat</para> + </listitem> - <listitem> - <para>Leaps</para> - </listitem> - </itemizedlist> + <listitem> + <para>Leaps</para> + </listitem> + </itemizedlist> - <para>Drools has implementations for both Rete and Leaps; Leaps is still - considered experiment. The Drools <indexterm> - <primary>Rete</primary> - </indexterm>Rete implementation is called ReteOO signifying that this - Drools has an enhanced and optimised implementation of the Rete algorithm. - Other Rete based engines also have marketting terms for their prioprietary - enhancements to Rete, like RetePlus and Rete III,</para> + <para>Drools has implementations for both Rete and Leaps; Leaps is still + considered experiment. The Drools <indexterm> + <primary>Rete</primary> + </indexterm>Rete implementation is called ReteOO signifying that this + Drools has an enhanced and optimised implementation of the Rete algorithm. + Other Rete based engines also have marketting terms for their prioprietary + enhancements to Rete, like RetePlus and Rete III,</para> - <figure> - <title>A Basic Rete network</title> + <figure> + <title>A Basic Rete network</title> - <mediaobject> - <imageobject> - <imagedata align="center" fileref="Rule_Engine.svg" format="SVG" /> - </imageobject> + <mediaobject> + <imageobject> + <imagedata align="center" fileref="Rule_Engine.svg" format="SVG" /> + </imageobject> - <imageobject> - <imagedata align="center" fileref="Rule_Engine.png" format="PNG" /> - </imageobject> - </mediaobject> - </figure> + <imageobject> + <imagedata align="center" fileref="Rule_Engine.png" format="PNG" /> + </imageobject> + </mediaobject> + </figure> - <para>The LHS of a rule is made up of <indexterm> - <primary>Conditional Element</primary> - </indexterm>iConditional Elements and <indexterm> - <primary>Field Constraint</primary> - </indexterm>iField Constraints. The following example shows a <indexterm> - <primary>Literal Field Constraint</primary> - </indexterm>iLiteral Field Constraint used with a Cheese Fact; the - combination of Field Constraints on a Fact is known as a <indexterm> - <primary>Column</primary> - </indexterm>Column.</para> + <para>The LHS of a rule is made up of <indexterm> + <primary>Conditional Element</primary> + </indexterm>iConditional Elements and <indexterm> + <primary>Field Constraint</primary> + </indexterm>iField Constraints. The following example shows a <indexterm> + <primary>Literal Field Constraint</primary> + </indexterm>iLiteral Field Constraint used with a Cheese Fact; the + combination of Field Constraints on a Fact is known as a <indexterm> + <primary>Column</primary> + </indexterm>Column.</para> - <programlisting>rule "Cheddar Cheese" + <programlisting>rule "Cheddar Cheese" when Cheese( type == "cheddar" ) then System.out.println( "cheddar" ); end</programlisting> - <para>The example above is similar to :</para> + <para>The example above is similar to :</para> - <programlisting>public void cheddarCheese(Cheese cheese) { + <programlisting>public void cheddarCheese(Cheese cheese) { if ( cheese.getType().equals("cheddar") { System.out.println( "cheddar" ); } }</programlisting> - <para>Rule engines are a complete de-coupling of data from the logic. Rules - cannot be called directly as they are not methods or functions instead Rules - fire in response to changes in Working Memory's data, It may help to think - of this de-coupling as a specialised event sytem. The Consequence is the - Listener to the full matching of the LHS events.</para> + <para>Rule engines are a complete de-coupling of data from the logic. + Rules cannot be called directly as they are not methods or functions + instead Rules fire in response to changes in Working Memory's data, It may + help to think of this de-coupling as a specialised event sytem. The + Consequence is the Listener to the full matching of the LHS events.</para> - <para>Rule Engines are much like a database where Rule's LHS define the - queries on the Working Memory. The previous rule can be expressed in - <indexterm> - <primary>SQL</primary> - </indexterm>SQL as:</para> + <para>Rule Engines are much like a database where Rule's LHS define the + queries on the Working Memory. The previous rule can be expressed in + <indexterm> + <primary>SQL</primary> + </indexterm>SQL as:</para> - <programlisting> select * from Cheese where type == "cheddar"</programlisting> + <programlisting> select * from Cheese where type == "cheddar"</programlisting> - <para>A <indexterm> - <primary>DataBase</primary> - </indexterm>Database executes SQL, on request, where as a Rule Engine will - process data against its rules, its Production Memory, as it's asserted; - this process is known as <indexterm> - <primary>Pattern Matching</primary> - </indexterm>Pattern Matching. When added to the Production Memory, Rule's - are decomposed into a graph using the <indexterm> - <primary>Rete</primary> - </indexterm>Rete algorithm. Rete is one of the standard Rule Engine - algorithms developed by <indexterm> - <primary>Charles Forgey</primary> - </indexterm>Charles Forgey in 1979 which is covered in greater detail in a - Rete Algorithm chapter.</para> + <para>A <indexterm> + <primary>DataBase</primary> + </indexterm>Database executes SQL, on request, where as a Rule Engine + will process data against its rules, its Production Memory, as it's + asserted; this process is known as <indexterm> + <primary>Pattern Matching</primary> + </indexterm>Pattern Matching. When added to the Production Memory, + Rule's are decomposed into a graph using the <indexterm> + <primary>Rete</primary> + </indexterm>Rete algorithm. Rete is one of the standard Rule Engine + algorithms developed by <indexterm> + <primary>Charles Forgey</primary> + </indexterm>Charles Forgey in 1979 which is covered in greater detail in + a Rete Algorithm chapter.</para> - <figure> - <title>A Basic Rete network</title> + <figure> + <title>A Basic Rete network</title> - <mediaobject> - <imageobject> - <imagedata align="center" fileref="A_Basic_Rete_Network.svg" - format="SVG" /> - </imageobject> + <mediaobject> + <imageobject> + <imagedata align="center" fileref="A_Basic_Rete_Network.svg" + format="SVG" /> + </imageobject> - <imageobject> - <imagedata align="center" fileref="A_Basic_Rete_Network.png" - format="PNG" /> - </imageobject> - </mediaobject> - </figure> + <imageobject> + <imagedata align="center" fileref="A_Basic_Rete_Network.png" + format="PNG" /> + </imageobject> + </mediaobject> + </figure> - <para>Each Fact type in our Working Memory, such as <code>Cheese</code>, is - represented by an <indexterm> - <primary>Object Type</primary> - </indexterm>Object Type class, shown as the root node in our graph. When - Facts are asserted into the Working Memory the Rule Engine finds the - matching Object Type node and propagates the asserted Fact onto the next - node. The Object Type node maintains a memory of all matched Facts. in our - example the next node in the graph is a <indexterm> - <primary>Field Constraint</primary> - </indexterm>Field Constraint, <code>type == "cheddar", </code>its job is - to filter Facts using the given constraint; if the type of - <code>Cheese</code> is not "cheddar" the Fact progresses no further in the - network, if it is "cheddar" it is rememebered in the <indexterm> - <primary>Alpha Node</primary> - </indexterm>Alpha Node's memory and propagated onto the next node in the - network.. Alpha Node is classic Rete terminology for single input/single - output nodes, in that it receives a single Fact of a specified Object Type - and propates a single Fact of specified Object Type.</para> + <para>Each Fact type in our Working Memory, such as <code>Cheese</code>, + is represented by an <indexterm> + <primary>Object Type</primary> + </indexterm>Object Type class, shown as the root node in our graph. When + Facts are asserted into the Working Memory the Rule Engine finds the + matching Object Type node and propagates the asserted Fact onto the next + node. The Object Type node maintains a memory of all matched Facts. in our + example the next node in the graph is a <indexterm> + <primary>Field Constraint</primary> + </indexterm>Field Constraint, <code>type == "cheddar", </code>its job is + to filter Facts using the given constraint; if the type of + <code>Cheese</code> is not "cheddar" the Fact progresses no further in the + network, if it is "cheddar" it is rememebered in the <indexterm> + <primary>Alpha Node</primary> + </indexterm>Alpha Node's memory and propagated onto the next node in the + network.. Alpha Node is classic Rete terminology for single input/single + output nodes, in that it receives a single Fact of a specified Object Type + and propates a single Fact of specified Object Type.</para> - <para>At this point we have what is known as a <indexterm> - <primary>Partial Match</primary> - </indexterm>Partial Match, in that we have matched facts against some, but - not all, of the Rule's nodes. <indexterm> - <primary>Left Input Adapter Node</primary> - </indexterm>s will be explained later, suffice to say it always propagetes - onto the next node, in this case a <indexterm> - <primary>Terminal Node</primary> - </indexterm>Terminal Node. The Terminal Node is our end node, now we say - the Rule is Fully Matched and ready to fire.</para> + <para>At this point we have what is known as a <indexterm> + <primary>Partial Match</primary> + </indexterm>Partial Match, in that we have matched facts against some, + but not all, of the Rule's nodes. <indexterm> + <primary>Left Input Adapter Node</primary> + </indexterm>s will be explained later, suffice to say it always + propagetes onto the next node, in this case a <indexterm> + <primary>Terminal Node</primary> + </indexterm>Terminal Node. The Terminal Node is our end node, now we say + the Rule is Fully Matched and ready to fire.</para> - <para>Earlier we mentioned that a Rule Engine is much like a Database, we - can prove this by using a <indexterm> - <primary>Query</primary> - </indexterm>Query construct. A Query is Rule with a special Terminal node; - instead of executing a Consequence the Terminal node stores matching Facts - in a list, which is returned as the result. Lets prove this</para> + <para>Earlier we mentioned that a Rule Engine is much like a Database, we + can prove this by using a <indexterm> + <primary>Query</primary> + </indexterm>Query construct. A Query is Rule with a special Terminal + node; instead of executing a Consequence the Terminal node stores matching + Facts in a list, which is returned as the result. Lets prove this</para> - <programlisting>query "Find cheeses with a cost of 5" + <programlisting>query "Find cheeses with a cost of 5" Cheese( price == 5 ) end</programlisting> - <programlisting>// First create the facts + <programlisting>// First create the facts Cheese stilton = new Cheese("stilton", 8); // type, price Cheese cheddar = new Cheese("cheddar", 5); // type, price Cheese mozarella = new Cheese("mozarella", 5); // type, price @@ -269,21 +281,21 @@ List results = workingMemory.getQueryResults( "Find cheeses with a cost of 5" );</programlisting> - <para>When we get the Query Results the List has a size of two and - references "cheddar" and "mozarella", as expected. If we had used a Rule - construct instead of a Query the Terminal Node's Consequence would have - attempted to fire twice, once for "cheddar" and once for "mozarella".</para> + <para>When we get the Query Results the List has a size of two and + references "cheddar" and "mozarella", as expected. If we had used a Rule + construct instead of a Query the Terminal Node's Consequence would have + attempted to fire twice, once for "cheddar" and once for + "mozarella".</para> - <para>When a Rule is Fully Matched it does not fire immediately (in Rete, - but in Leaps it does !). Instead the Rule plus the matched Facts are - <indexterm> - <primary>Activated</primary> - </indexterm>Activated placed onto the <indexterm> - <primary>Agenda</primary> - </indexterm>Agenda; which is responsible for the scheduling and firing - <indexterm> - <primary>Activation</primary> - </indexterm>Activations.</para> - - </section> + <para>When a Rule is Fully Matched it does not fire immediately (in Rete, + but in Leaps it does !). Instead the Rule plus the matched Facts are + <indexterm> + <primary>Activated</primary> + </indexterm>Activated placed onto the <indexterm> + <primary>Agenda</primary> + </indexterm>Agenda; which is responsible for the scheduling and firing + <indexterm> + <primary>Activation</primary> + </indexterm>Activations.</para> + </section> </section> \ No newline at end of file |