[jboss-svn-commits] JBL Code SVN: r6559 - in labs/jbossrules/trunk/drools-repository/src: main/java/org/drools/repository test/java/org/drools/repository

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Oct 3 17:15:14 EDT 2006


Author: michael.neale at jboss.com
Date: 2006-10-03 17:15:04 -0400 (Tue, 03 Oct 2006)
New Revision: 6559

Modified:
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/MyAccessManager.java
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RuleItem.java
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulePackageItem.java
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulesRepository.java
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/StateItem.java
   labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RulePackageItemTestCase.java
Log:
JBRULES-509 - rule parallel version extractor

Modified: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/MyAccessManager.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/MyAccessManager.java	2006-10-03 16:45:27 UTC (rev 6558)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/MyAccessManager.java	2006-10-03 21:15:04 UTC (rev 6559)
@@ -11,6 +11,10 @@
 import org.apache.jackrabbit.core.security.AMContext;
 import org.apache.jackrabbit.core.security.AccessManager;
 
+/**
+ * This is just an experimental access manager for proof of concept. Don't
+ * actually use it or you are insane !
+ */
 public class MyAccessManager
     implements
     AccessManager {

Modified: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RuleItem.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RuleItem.java	2006-10-03 16:45:27 UTC (rev 6558)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RuleItem.java	2006-10-03 21:15:04 UTC (rev 6559)
@@ -284,8 +284,6 @@
             //make sure this object's node is the head version
             checkIsUpdateable();                                       
             
-            
-            
             CategoryItem tagItem = this.rulesRepository.loadCategory(tag);
                                     
             //now set the tag property of the rule
@@ -438,6 +436,16 @@
      */
     public void setState(String stateName) throws RulesRepositoryException {
         try {
+            //make sure this node is a rule node
+            if(this.node.getPrimaryNodeType().getName().equals("nt:version")) {
+                String message = "Error. States can only be set for the head version of a rule node";
+                log.error(message);
+                throw new RulesRepositoryException(message);
+            } 
+            
+            //now set the state property of the rule                              
+            checkout();
+            
             StateItem stateItem = this.rulesRepository.getState(stateName);
             this.setState(stateItem);
         }
@@ -482,8 +490,9 @@
      */
     public StateItem getState() throws RulesRepositoryException {
         try {
-            Property stateProperty = this.node.getProperty(STATE_PROPERTY_NAME);
-            Node stateNode = this.node.getSession().getNodeByUUID(stateProperty.getString());
+            Node content = getVersionContentNode();
+            Property stateProperty = content.getProperty(STATE_PROPERTY_NAME);
+            Node stateNode = this.rulesRepository.getSession().getNodeByUUID(stateProperty.getString());
             return new StateItem(this.rulesRepository, stateNode);
         }
         catch(PathNotFoundException e) {
@@ -495,6 +504,18 @@
             throw new RulesRepositoryException(e);
         }
     }
+    
+    /** Compare this rules state with some other state */
+    public boolean sameState(StateItem other) {
+        StateItem thisState = getState();
+        if (thisState == other) {
+            return true;
+        } else if (thisState != null){
+            return thisState.equals( other );
+        } else {
+            return false;
+        }
+    }
 
     /**
      * Gets a DslItem object corresponding to the DSL reference from the node that this object
@@ -506,7 +527,7 @@
      */
     public DslItem getDsl() throws RulesRepositoryException {
         try {
-            Property dslProperty = this.node.getProperty(DSL_PROPERTY_NAME);
+            Property dslProperty = getVersionContentNode().getProperty(DSL_PROPERTY_NAME);
             Node dslNode = this.node.getSession().getNodeByUUID(dslProperty.getString());
             return new DslItem(this.rulesRepository, dslNode);
         }

Modified: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulePackageItem.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulePackageItem.java	2006-10-03 16:45:27 UTC (rev 6558)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulePackageItem.java	2006-10-03 21:15:04 UTC (rev 6559)
@@ -9,24 +9,13 @@
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
 import javax.jcr.PathNotFoundException;
-import javax.jcr.Property;
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.Value;
 import javax.jcr.ValueFactory;
-import javax.jcr.lock.LockException;
-import javax.jcr.nodetype.ConstraintViolationException;
-import javax.jcr.nodetype.NoSuchNodeTypeException;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionException;
-import javax.jcr.version.VersionIterator;
 
 import org.apache.log4j.Logger;
 
-//TODO: consider allowing ruleSets to aggregate other ruleSets in addition to rules
-//TODO: exclude duplicate references
-//TODO: add remove function   
-
 /**
  * A ruleSet object aggregates a set of rules. This is advantageous for systems using the JBoss Rules
  * engine where the application might make use of many related rules.  
@@ -37,168 +26,191 @@
  * 
  * @author btruitt
  */
-public class RulePackageItem extends VersionableItem {       
-    private static Logger log = Logger.getLogger(RulePackageItem.class);
-    
+public class RulePackageItem extends VersionableItem {
+    private static Logger      log                              = Logger.getLogger( RulePackageItem.class );
+
     /**
+     * This is the name of the rules "subfolder" where rules are kept
+     * for this package.
+     */
+    public static final String RULES_FOLDER_NAME                = "rules";
+
+    /**
      * The name of the reference property on the rulepackage_node_type type node that objects of
      * this type hold a reference to
      */
-    public static final String RULE_REFERENCE_PROPERTY_NAME = "drools:ruleReference";
-    
+    public static final String RULE_REFERENCE_PROPERTY_NAME     = "drools:ruleReference";
+
     /**
      * The name of the reference property on the rulepackage_node_type type node that objects of
      * this type hold a reference to
      */
-    public static final String FUNCTION_REFERENCE_PROPERTY_NAME = "drools:functionReference";    
-    
+    public static final String FUNCTION_REFERENCE_PROPERTY_NAME = "drools:functionReference";
+
     /**
      * The name of the rule package node type
      */
-    public static final String RULE_PACKAGE_TYPE_NAME = "drools:rulepackageNodeType";   
-    
+    public static final String RULE_PACKAGE_TYPE_NAME           = "drools:rulepackageNodeType";
+
     /**
+     * The folder where functions are kept
+     */
+    public static final String FUNCTION_FOLDER_NAME             = "functions";
+
+    /**
      * Constructs an object of type RulePackageItem corresponding the specified node
      * @param rulesRepository the rulesRepository that instantiated this object
      * @param node the node to which this object corresponds
      * @throws RulesRepositoryException 
      */
-    public RulePackageItem(RulesRepository rulesRepository, Node node) throws RulesRepositoryException {
-        super(rulesRepository, node);
-        
+    public RulePackageItem(RulesRepository rulesRepository,
+                           Node node) throws RulesRepositoryException {
+        super( rulesRepository,
+               node );
+
         try {
             //make sure this node is a rule package node       
-            if(!(this.node.getPrimaryNodeType().getName().equals(RULE_PACKAGE_TYPE_NAME))) {
+            if ( !(this.node.getPrimaryNodeType().getName().equals( RULE_PACKAGE_TYPE_NAME )) ) {
                 String message = this.node.getName() + " is not a node of type " + RULE_PACKAGE_TYPE_NAME + ". It is a node of type: " + this.node.getPrimaryNodeType().getName();
-                log.error(message);
-                throw new RulesRepositoryException(message);
-            }    
+                log.error( message );
+                throw new RulesRepositoryException( message );
+            }
+        } catch ( Exception e ) {
+            log.error( "Caught exception: " + e );
+            throw new RulesRepositoryException( e );
         }
-        catch(Exception e) {
-            log.error("Caught exception: " + e);
-            throw new RulesRepositoryException(e);
-        }
-    }    
-    
+    }
+
     /**
      * This adds a rule to the current physical package (you can move it later).
      */
-    public RuleItem addRule(String ruleName, String description) {
+    public RuleItem addRule(String ruleName,
+                            String description) {
         Node ruleNode;
         try {
+
+            Node rulesFolder = this.node.getNode( RULES_FOLDER_NAME );
+            ruleNode = rulesFolder.addNode( ruleName,
+                                            RuleItem.RULE_NODE_TYPE_NAME );
+            ruleNode.setProperty( RuleItem.TITLE_PROPERTY_NAME,
+                                  ruleName );
+
+            ruleNode.setProperty( RuleItem.DESCRIPTION_PROPERTY_NAME,
+                                  description );
+            ruleNode.setProperty( RuleItem.FORMAT_PROPERTY_NAME,
+                                  RuleItem.RULE_FORMAT );
+            //ruleNode.setProperty(RuleItem.RULE_CONTENT_PROPERTY_NAME, "");
+
+            ruleNode.setProperty( VersionableItem.CHECKIN_COMMENT,
+                                  "Initial" );
+
+            Calendar lastModified = Calendar.getInstance();
+            ruleNode.setProperty( RuleItem.LAST_MODIFIED_PROPERTY_NAME,
+                                  lastModified );
             
-            Node rulesFolder = this.node.getNode( "rules" );
-            ruleNode = rulesFolder.addNode( ruleName, RuleItem.RULE_NODE_TYPE_NAME);
-            ruleNode.setProperty(RuleItem.TITLE_PROPERTY_NAME, ruleName);
             
             
-            ruleNode.setProperty(RuleItem.DESCRIPTION_PROPERTY_NAME, description);
-            ruleNode.setProperty(RuleItem.FORMAT_PROPERTY_NAME, RuleItem.RULE_FORMAT);
-            //ruleNode.setProperty(RuleItem.RULE_CONTENT_PROPERTY_NAME, "");
-                                    
-            ruleNode.setProperty( VersionableItem.CHECKIN_COMMENT, "Initial" );
-            
-            Calendar lastModified = Calendar.getInstance();
-            ruleNode.setProperty(RuleItem.LAST_MODIFIED_PROPERTY_NAME, lastModified);
-            
+
+            RuleItem rule = new RuleItem( this.rulesRepository,
+                                          ruleNode );
+            //rule.setState( "Draft" );
             this.rulesRepository.save();
             
-            RuleItem rule = new RuleItem(this.rulesRepository, ruleNode);
             rule.checkin( "Initial" );
             return rule;
-            
+
         } catch ( Exception e ) {
-            if (e instanceof RuntimeException) {
+            if ( e instanceof RuntimeException ) {
                 throw (RuntimeException) e;
-            } else if (e instanceof ItemExistsException ) {
-                throw new RulesRepositoryException("A rule of that name already exists in that package.", e);
+            } else if ( e instanceof ItemExistsException ) {
+                throw new RulesRepositoryException( "A rule of that name already exists in that package.",
+                                                    e );
             } else {
-                throw new RulesRepositoryException(e);
+                throw new RulesRepositoryException( e );
             }
-        } 
-        
-        
+        }
+
     }
-    
+
     /** Remove a rule by name */
     public void removeRule(String name) {
         try {
-            this.node.getNode( "rules/" + name ).remove();
-        } catch ( RepositoryException e) {
-            throw new RulesRepositoryException(e);
+            this.node.getNode( RULES_FOLDER_NAME + "/" + name ).remove();
+        } catch ( RepositoryException e ) {
+            throw new RulesRepositoryException( e );
         }
     }
-    
-//The following should be kept for reference on how to add a reference that 
-//is either locked to a version or follows head
-//    /**
-//     * Adds a rule to the rule package node this object represents.  The reference to the rule
-//     * will optionally follow the head version of the specified rule's node or the specific 
-//     * current version.
-//     * 
-//     * @param ruleItem the ruleItem corresponding to the node to add to the rule package this 
-//     *                 object represents
-//     * @param followRuleHead if true, the reference to the rule node will follow the head version 
-//     *                       of the node, even if new versions are added. If false, will refer 
-//     *                       specifically to the current version.
-//     * @throws RulesRepositoryException
-//     */
-//    public void addRuleReference(RuleItem ruleItem, boolean followRuleHead) throws RulesRepositoryException {        
-//        try {
-//            ValueFactory factory = this.node.getSession().getValueFactory();
-//            int i = 0;
-//            Value[] newValueArray = null;
-//            
-//            try {
-//                Value[] oldValueArray = this.node.getProperty(RULE_REFERENCE_PROPERTY_NAME).getValues();
-//                newValueArray = new Value[oldValueArray.length + 1];                
-//                
-//                for(i=0; i<oldValueArray.length; i++) {
-//                    newValueArray[i] = oldValueArray[i];
-//                }
-//            }
-//            catch(PathNotFoundException e) {
-//                //the property has not been created yet. do so now
-//                newValueArray = new Value[1];
-//            }
-//            finally {
-//                if(newValueArray != null) { //just here to make the compiler happy
-//                    if(followRuleHead) {                    
-//                        newValueArray[i] = factory.createValue(ruleItem.getNode());
-//                    }
-//                    else {
-//                        //this is the magic that ties it to a specific version
-//                        newValueArray[i] = factory.createValue(ruleItem.getNode().getBaseVersion());
-//                    }
-//                    this.node.checkout();
-//                    this.node.setProperty(RULE_REFERENCE_PROPERTY_NAME, newValueArray);                
-//                    this.node.getSession().save();
-//                    this.node.checkin();
-//                }
-//                else {
-//                    throw new RulesRepositoryException("Unexpected null pointer for newValueArray");
-//                }
-//            }                    
-//        }
-//        catch(UnsupportedRepositoryOperationException e) {
-//            String message = "";
-//            try {
-//                message = "Error: Caught UnsupportedRepositoryOperationException when attempting to get base version for rule: " + ruleItem.getNode().getName() + ". Are you sure your JCR repository supports versioning? ";
-//                log.error(message + e);
-//            }
-//            catch (RepositoryException e1) {
-//                log.error("Caught exception: " + e1);
-//                throw new RulesRepositoryException(message, e1);
-//            }
-//            log.error("Caught exception: " + e);
-//            throw new RulesRepositoryException(e);
-//        }
-//        catch(Exception e) {
-//            log.error("Caught exception: " + e);
-//            throw new RulesRepositoryException(e);
-//        }
-//    }
 
+    // The following should be kept for reference on how to add a reference that 
+    //is either locked to a version or follows head - FOR SHARING RULES
+    //    /**
+    //     * Adds a rule to the rule package node this object represents.  The reference to the rule
+    //     * will optionally follow the head version of the specified rule's node or the specific 
+    //     * current version.
+    //     * 
+    //     * @param ruleItem the ruleItem corresponding to the node to add to the rule package this 
+    //     *                 object represents
+    //     * @param followRuleHead if true, the reference to the rule node will follow the head version 
+    //     *                       of the node, even if new versions are added. If false, will refer 
+    //     *                       specifically to the current version.
+    //     * @throws RulesRepositoryException
+    //     */
+    //    public void addRuleReference(RuleItem ruleItem, boolean followRuleHead) throws RulesRepositoryException {        
+    //        try {
+    //            ValueFactory factory = this.node.getSession().getValueFactory();
+    //            int i = 0;
+    //            Value[] newValueArray = null;
+    //            
+    //            try {
+    //                Value[] oldValueArray = this.node.getProperty(RULE_REFERENCE_PROPERTY_NAME).getValues();
+    //                newValueArray = new Value[oldValueArray.length + 1];                
+    //                
+    //                for(i=0; i<oldValueArray.length; i++) {
+    //                    newValueArray[i] = oldValueArray[i];
+    //                }
+    //            }
+    //            catch(PathNotFoundException e) {
+    //                //the property has not been created yet. do so now
+    //                newValueArray = new Value[1];
+    //            }
+    //            finally {
+    //                if(newValueArray != null) { //just here to make the compiler happy
+    //                    if(followRuleHead) {                    
+    //                        newValueArray[i] = factory.createValue(ruleItem.getNode());
+    //                    }
+    //                    else {
+    //                        //this is the magic that ties it to a specific version
+    //                        newValueArray[i] = factory.createValue(ruleItem.getNode().getBaseVersion());
+    //                    }
+    //                    this.node.checkout();
+    //                    this.node.setProperty(RULE_REFERENCE_PROPERTY_NAME, newValueArray);                
+    //                    this.node.getSession().save();
+    //                    this.node.checkin();
+    //                }
+    //                else {
+    //                    throw new RulesRepositoryException("Unexpected null pointer for newValueArray");
+    //                }
+    //            }                    
+    //        }
+    //        catch(UnsupportedRepositoryOperationException e) {
+    //            String message = "";
+    //            try {
+    //                message = "Error: Caught UnsupportedRepositoryOperationException when attempting to get base version for rule: " + ruleItem.getNode().getName() + ". Are you sure your JCR repository supports versioning? ";
+    //                log.error(message + e);
+    //            }
+    //            catch (RepositoryException e1) {
+    //                log.error("Caught exception: " + e1);
+    //                throw new RulesRepositoryException(message, e1);
+    //            }
+    //            log.error("Caught exception: " + e);
+    //            throw new RulesRepositoryException(e);
+    //        }
+    //        catch(Exception e) {
+    //            log.error("Caught exception: " + e);
+    //            throw new RulesRepositoryException(e);
+    //        }
+    //    }
+
     /**
      * Adds a function to the rule package node this object represents.  The reference to the 
      * function node will follow the head version of the specified node.
@@ -208,9 +220,10 @@
      * @throws RulesRepositoryException
      */
     public void addFunction(FunctionItem functionItem) throws RulesRepositoryException {
-        this.addFunction(functionItem, true);        
+        this.addFunction( functionItem,
+                          true );
     }
-    
+
     /**
      * Adds a function to the rule package node this object represents.  The reference to the function
      * will optionally follow the head version of the specified node or the specific current version.
@@ -222,61 +235,57 @@
      *                       specifically to the current version.
      * @throws RulesRepositoryException
      */
-    public void addFunction(FunctionItem functionItem, boolean followFunctionHead) throws RulesRepositoryException {        
+    public void addFunction(FunctionItem functionItem,
+                            boolean followFunctionHead) throws RulesRepositoryException {
         try {
             ValueFactory factory = this.node.getSession().getValueFactory();
             int i = 0;
             Value[] newValueArray = null;
-            
+
             try {
-                Value[] oldValueArray = this.node.getProperty(FUNCTION_REFERENCE_PROPERTY_NAME).getValues();
-                newValueArray = new Value[oldValueArray.length + 1];                
-                
-                for(i=0; i<oldValueArray.length; i++) {
+                Value[] oldValueArray = this.node.getProperty( FUNCTION_REFERENCE_PROPERTY_NAME ).getValues();
+                newValueArray = new Value[oldValueArray.length + 1];
+
+                for ( i = 0; i < oldValueArray.length; i++ ) {
                     newValueArray[i] = oldValueArray[i];
                 }
-            }
-            catch(PathNotFoundException e) {
+            } catch ( PathNotFoundException e ) {
                 //the property has not been created yet. do so now
                 newValueArray = new Value[1];
-            }
-            finally {
-                if(newValueArray != null) { //just here to make the compiler happy
-                    if(followFunctionHead) {                    
-                        newValueArray[i] = factory.createValue(functionItem.getNode());
+            } finally {
+                if ( newValueArray != null ) { //just here to make the compiler happy
+                    if ( followFunctionHead ) {
+                        newValueArray[i] = factory.createValue( functionItem.getNode() );
+                    } else {
+                        newValueArray[i] = factory.createValue( functionItem.getNode().getBaseVersion() );
                     }
-                    else {
-                        newValueArray[i] = factory.createValue(functionItem.getNode().getBaseVersion());
-                    }
                     this.node.checkout();
-                    this.node.setProperty(FUNCTION_REFERENCE_PROPERTY_NAME, newValueArray);                
+                    this.node.setProperty( FUNCTION_REFERENCE_PROPERTY_NAME,
+                                           newValueArray );
                     this.node.getSession().save();
                     this.node.checkin();
+                } else {
+                    throw new RulesRepositoryException( "Unexpected null pointer for newValueArray" );
                 }
-                else {
-                    throw new RulesRepositoryException("Unexpected null pointer for newValueArray");
-                }
-            }                    
-        }
-        catch(UnsupportedRepositoryOperationException e) {
+            }
+        } catch ( UnsupportedRepositoryOperationException e ) {
             String message = "";
             try {
                 message = "Error: Caught UnsupportedRepositoryOperationException when attempting to get base version for function: " + functionItem.getNode().getName() + ". Are you sure your JCR repository supports versioning? ";
-                log.error(message + e);
+                log.error( message + e );
+            } catch ( RepositoryException e1 ) {
+                log.error( "Caught exception: " + e1 );
+                throw new RulesRepositoryException( message,
+                                                    e1 );
             }
-            catch (RepositoryException e1) {
-                log.error("Caught exception: " + e1);
-                throw new RulesRepositoryException(message, e1);
-            }
-            log.error("Caught exception: " + e);
-            throw new RulesRepositoryException(e);
+            log.error( "Caught exception: " + e );
+            throw new RulesRepositoryException( e );
+        } catch ( Exception e ) {
+            log.error( "Caught exception: " + e );
+            throw new RulesRepositoryException( e );
         }
-        catch(Exception e) {
-            log.error("Caught exception: " + e);
-            throw new RulesRepositoryException(e);
-        }
     }
-    
+
     /**
      * Removes the specified rule from the rule package node this object represents.  
      * 
@@ -284,43 +293,42 @@
      *                 this object represents
      * @throws RulesRepositoryException
      */
-    public void removeRuleReference(RuleItem ruleItem) throws RulesRepositoryException {                
+    public void removeRuleReference(RuleItem ruleItem) throws RulesRepositoryException {
         try {
-            Value[] oldValueArray = this.node.getProperty(RULE_REFERENCE_PROPERTY_NAME).getValues();
+            Value[] oldValueArray = this.node.getProperty( RULE_REFERENCE_PROPERTY_NAME ).getValues();
             Value[] newValueArray = new Value[oldValueArray.length - 1];
-            
+
             boolean wasThere = false;
-            
-            int j=0;
-            for(int i=0; i<oldValueArray.length; i++) {
-                Node ruleNode = this.node.getSession().getNodeByUUID(oldValueArray[i].getString());
-                RuleItem currentRuleItem = new RuleItem(this.rulesRepository, ruleNode);
-                if(currentRuleItem.equals(ruleItem)) {
+
+            int j = 0;
+            for ( int i = 0; i < oldValueArray.length; i++ ) {
+                Node ruleNode = this.node.getSession().getNodeByUUID( oldValueArray[i].getString() );
+                RuleItem currentRuleItem = new RuleItem( this.rulesRepository,
+                                                         ruleNode );
+                if ( currentRuleItem.equals( ruleItem ) ) {
                     wasThere = true;
-                }
-                else {
+                } else {
                     newValueArray[j] = oldValueArray[i];
                     j++;
                 }
             }
-                            
-            if(!wasThere) {
+
+            if ( !wasThere ) {
                 return;
-            }
-            else {
+            } else {
                 this.node.checkout();
-                this.node.setProperty(RULE_REFERENCE_PROPERTY_NAME, newValueArray);                
+                this.node.setProperty( RULE_REFERENCE_PROPERTY_NAME,
+                                       newValueArray );
                 this.node.getSession().save();
                 this.node.checkin();
             }
-        }
-        catch(PathNotFoundException e) {
+        } catch ( PathNotFoundException e ) {
             //the property has not been created yet. 
             return;
-        }  
-        catch(Exception e) {
-            log.error("Caught exception", e);
-            throw new RulesRepositoryException(e);
+        } catch ( Exception e ) {
+            log.error( "Caught exception",
+                       e );
+            throw new RulesRepositoryException( e );
         }
     }
 
@@ -331,43 +339,42 @@
      *                 this object represents
      * @throws RulesRepositoryException
      */
-    public void removeFunction(FunctionItem functionItem) throws RulesRepositoryException {                
+    public void removeFunction(FunctionItem functionItem) throws RulesRepositoryException {
         try {
-            Value[] oldValueArray = this.node.getProperty(FUNCTION_REFERENCE_PROPERTY_NAME).getValues();
+            Value[] oldValueArray = this.node.getProperty( FUNCTION_REFERENCE_PROPERTY_NAME ).getValues();
             Value[] newValueArray = new Value[oldValueArray.length - 1];
-            
+
             boolean wasThere = false;
-            
-            int j=0;
-            for(int i=0; i<oldValueArray.length; i++) {
-                Node functionNode = this.node.getSession().getNodeByUUID(oldValueArray[i].getString());
-                FunctionItem currentFunctionItem = new FunctionItem(this.rulesRepository, functionNode);
-                if(currentFunctionItem.equals(functionItem)) {
+
+            int j = 0;
+            for ( int i = 0; i < oldValueArray.length; i++ ) {
+                Node functionNode = this.node.getSession().getNodeByUUID( oldValueArray[i].getString() );
+                FunctionItem currentFunctionItem = new FunctionItem( this.rulesRepository,
+                                                                     functionNode );
+                if ( currentFunctionItem.equals( functionItem ) ) {
                     wasThere = true;
-                }
-                else {
+                } else {
                     newValueArray[j] = oldValueArray[i];
                     j++;
                 }
             }
-                            
-            if(!wasThere) {
+
+            if ( !wasThere ) {
                 return;
-            }
-            else {
+            } else {
                 this.node.checkout();
-                this.node.setProperty(FUNCTION_REFERENCE_PROPERTY_NAME, newValueArray);                
+                this.node.setProperty( FUNCTION_REFERENCE_PROPERTY_NAME,
+                                       newValueArray );
                 this.node.getSession().save();
                 this.node.checkin();
             }
-        }
-        catch(PathNotFoundException e) {
+        } catch ( PathNotFoundException e ) {
             //the property has not been created yet. 
             return;
-        }  
-        catch(Exception e) {
-            log.error("Caught exception", e);
-            throw new RulesRepositoryException(e);
+        } catch ( Exception e ) {
+            log.error( "Caught exception",
+                       e );
+            throw new RulesRepositoryException( e );
         }
     }
 
@@ -376,135 +383,192 @@
      * 
      * @return the List object holding the FunctionItem objects in this rule package
      * @throws RulesRepositoryException 
-     */   
+     */
     public List getFunctions() throws RulesRepositoryException {
-        try {                       
-            Value[] valueArray = this.node.getProperty(FUNCTION_REFERENCE_PROPERTY_NAME).getValues();
+        try {
+            Value[] valueArray = this.node.getProperty( FUNCTION_REFERENCE_PROPERTY_NAME ).getValues();
             List returnList = new ArrayList();
-           
-            for(int i=0; i<valueArray.length; i++) {
-                Node functionNode = this.node.getSession().getNodeByUUID(valueArray[i].getString());
-                returnList.add(new FunctionItem(this.rulesRepository, functionNode));
+
+            for ( int i = 0; i < valueArray.length; i++ ) {
+                Node functionNode = this.node.getSession().getNodeByUUID( valueArray[i].getString() );
+                returnList.add( new FunctionItem( this.rulesRepository,
+                                                  functionNode ) );
             }
             return returnList;
-        }
-        catch(PathNotFoundException e) {
+        } catch ( PathNotFoundException e ) {
             //the property has not been created yet. 
             return new ArrayList();
-        }                                       
-        catch(Exception e) {
-            log.error("Caught exception: " + e);
-            throw new RulesRepositoryException(e);
+        } catch ( Exception e ) {
+            log.error( "Caught exception: " + e );
+            throw new RulesRepositoryException( e );
         }
     }
-    
-//    /**
-//     * Gets a list of RuleItem objects for each rule node in this rule package
-//     * 
-//     * @return the List object holding the RuleItem objects in this rule package
-//     * @throws RulesRepositoryException 
-//     */
-//    public List getRules() throws RulesRepositoryException {
-//        try {                       
-//            Value[] valueArray = this.node.getProperty(RULE_REFERENCE_PROPERTY_NAME).getValues();
-//            List returnList = new ArrayList();
-//           
-//            for(int i=0; i<valueArray.length; i++) {
-//                Node ruleNode = this.node.getSession().getNodeByUUID(valueArray[i].getString());
-//                returnList.add(new RuleItem(this.rulesRepository, ruleNode));
-//            }
-//            return returnList;
-//        }
-//        catch(PathNotFoundException e) {
-//            //the property has not been created yet. 
-//            return new ArrayList();
-//        }                                       
-//        catch(Exception e) {
-//            log.error("Caught exception: " + e);
-//            throw new RulesRepositoryException(e);
-//        }
-//    }   
-    
-    
+
+    //    /**
+    //     * Gets a list of RuleItem objects for each rule node in this rule package
+    //     * 
+    //     * @return the List object holding the RuleItem objects in this rule package
+    //     * @throws RulesRepositoryException 
+    //     */
+    //    public List getRules() throws RulesRepositoryException {
+    //        try {                       
+    //            Value[] valueArray = this.node.getProperty(RULE_REFERENCE_PROPERTY_NAME).getValues();
+    //            List returnList = new ArrayList();
+    //           
+    //            for(int i=0; i<valueArray.length; i++) {
+    //                Node ruleNode = this.node.getSession().getNodeByUUID(valueArray[i].getString());
+    //                returnList.add(new RuleItem(this.rulesRepository, ruleNode));
+    //            }
+    //            return returnList;
+    //        }
+    //        catch(PathNotFoundException e) {
+    //            //the property has not been created yet. 
+    //            return new ArrayList();
+    //        }                                       
+    //        catch(Exception e) {
+    //            log.error("Caught exception: " + e);
+    //            throw new RulesRepositoryException(e);
+    //        }
+    //    }   
+
     /** Return an iterator for the rules in this package */
     public Iterator getRules() {
-        
         try {
-            final NodeIterator it = this.node.getNode( "rules" ).getNodes();
-            return new Iterator() {
-                public boolean hasNext() {
-                    return it.hasNext();
-                }
-                public Object next() {               
-                    return new RuleItem(rulesRepository, (Node) it.next());
-                }
-                public void remove() {
-                    throw new UnsupportedOperationException("You can't remove a rule this way.");                
-                }
-            };
-            
+            RuleItemIterator it = new RuleItemIterator( this.node.getNode( RULES_FOLDER_NAME ).getNodes(),
+                                                        this.rulesRepository );
+            return it;
         } catch ( PathNotFoundException e ) {
-            throw new RulesRepositoryException(e);
+            throw new RulesRepositoryException( e );
         } catch ( RepositoryException e ) {
-            throw new RulesRepositoryException(e);
+            throw new RulesRepositoryException( e );
         }
-        
+
     }
-    
 
-    
     /**
      * Nicely formats the information contained by the node that this object encapsulates    
      */
     public String toString() {
-        try {            
+        try {
             StringBuffer returnString = new StringBuffer();
-            returnString.append("Content of the rule package named " + this.node.getName() + ":");
-            returnString.append("Description: " + this.getDescription() + "\n");
-            returnString.append("Format: " + this.getFormat() + "\n");
-            returnString.append("Last modified: " + this.getLastModified() + "\n");
-            returnString.append("Title: " + this.getTitle() + "\n");
-            returnString.append("Version Name: " + this.getVersionName() + "\n");
-            returnString.append("----\n");
-            
-            
+            returnString.append( "Content of the rule package named " + this.node.getName() + ":" );
+            returnString.append( "Description: " + this.getDescription() + "\n" );
+            returnString.append( "Format: " + this.getFormat() + "\n" );
+            returnString.append( "Last modified: " + this.getLastModified() + "\n" );
+            returnString.append( "Title: " + this.getTitle() + "\n" );
+            returnString.append( "Version Name: " + this.getVersionName() + "\n" );
+            returnString.append( "----\n" );
+
             return returnString.toString();
-        }
-        catch(Exception e) {
-            log.error("Caught Exception", e);
+        } catch ( Exception e ) {
+            log.error( "Caught Exception",
+                       e );
             return null;
         }
-    }    
-    
+    }
+
     public VersionableItem getPrecedingVersion() throws RulesRepositoryException {
         try {
             Node precedingVersionNode = this.getPrecedingVersionNode();
-            if(precedingVersionNode != null) {
-                return new RulePackageItem(this.rulesRepository, precedingVersionNode);
-            }
-            else {
+            if ( precedingVersionNode != null ) {
+                return new RulePackageItem( this.rulesRepository,
+                                            precedingVersionNode );
+            } else {
                 return null;
             }
-        }        
-        catch(Exception e) {
-            log.error("Caught exception", e);
-            throw new RulesRepositoryException(e);
-        }               
+        } catch ( Exception e ) {
+            log.error( "Caught exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
     }
 
     public VersionableItem getSucceedingVersion() throws RulesRepositoryException {
         try {
             Node succeedingVersionNode = this.getSucceedingVersionNode();
-            if(succeedingVersionNode != null) {
-                return new RulePackageItem(this.rulesRepository, succeedingVersionNode);
-            }
-            else {
+            if ( succeedingVersionNode != null ) {
+                return new RulePackageItem( this.rulesRepository,
+                                            succeedingVersionNode );
+            } else {
                 return null;
             }
-        }        
-        catch(Exception e) {
-            log.error("Caught exception", e);
-            throw new RulesRepositoryException(e);
+        } catch ( Exception e ) {
+            log.error( "Caught exception",
+                       e );
+            throw new RulesRepositoryException( e );
         }
-    }          
+    }
+
+    /**
+     * This iterates over nodes and produces RuleItem's.
+     * Also allows "skipping" of results to jump to certain items,
+     * as per JCRs "skip".
+     */
+    static class RuleItemIterator
+        implements
+        Iterator {
+
+        private NodeIterator    it;
+        private RulesRepository rulesRepository;
+
+        public RuleItemIterator(NodeIterator nodes,
+                                RulesRepository repo) {
+            this.it = nodes;
+            this.rulesRepository = repo;
+        }
+
+        public boolean hasNext() {
+            return it.hasNext();
+        }
+
+        public Object next() {
+            return new RuleItem( rulesRepository,
+                                 (Node) it.next() );
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException( "You can't remove a rule this way." );
+        }
+
+        /**
+         * @param i The number of rules to skip.
+         */
+        public void skip(int i) {
+            it.skip( i );
+        }
+
+    }
+
+    
+    /**
+     * This will return a list of rules for a given state.
+     * It works through the rules that belong to this package, and 
+     * if they are not in the correct state, walks backwards until it finds one
+     * in the correct state. 
+     * 
+     * If it walks all the way back up the versions looking for the "latest" 
+     * version with the appropriate state, and can't find one, 
+     * that asset is not included in the result.
+     */
+    public Iterator getRules(final StateItem state) {
+        final Iterator rules = getRules();
+        
+        List result = new ArrayList();
+        while(rules.hasNext()) {
+            RuleItem head = (RuleItem) rules.next();
+            if (head.sameState( state )) {
+                result.add( head );
+            } else {
+                Iterator prev = head.getPredecessorVersionsIterator();
+                while (prev.hasNext()) {
+                    RuleItem prevRule = (RuleItem) prev.next();
+                    if (prevRule.sameState( state )) {
+                        result.add( prevRule );
+                        break;
+                    }
+                }
+            }
+        }
+        return result.iterator();
+    }
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulesRepository.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulesRepository.java	2006-10-03 16:45:27 UTC (rev 6558)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulesRepository.java	2006-10-03 21:15:04 UTC (rev 6559)
@@ -572,8 +572,8 @@
             //create the node - see section 6.7.22.6 of the spec
             Node rulePackageNode = folderNode.addNode(name, RulePackageItem.RULE_PACKAGE_TYPE_NAME);
             
-            rulePackageNode.addNode( "rules", "nt:folder" );
-            rulePackageNode.addNode( "functions", "nt:folder" );
+            rulePackageNode.addNode( RulePackageItem.RULES_FOLDER_NAME, "nt:folder" );
+            rulePackageNode.addNode( RulePackageItem.FUNCTION_FOLDER_NAME, "nt:folder" );
             
             
             rulePackageNode.setProperty(RulePackageItem.TITLE_PROPERTY_NAME, name);
@@ -588,11 +588,13 @@
             this.session.save();
 
             return new RulePackageItem(this, rulePackageNode);
-        }
-        catch(Exception e) {
-            log.error("Caught Exception", e);
+        } catch (ItemExistsException e) {
+            throw new RulesRepositoryException("A package name must be unique.", e);
+        } catch (RepositoryException e) {
+            log.error( "Error when creating a new rule package", e );
             throw new RulesRepositoryException(e);
         }
+        
     }                                       
     
     /**

Modified: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/StateItem.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/StateItem.java	2006-10-03 16:45:27 UTC (rev 6558)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/StateItem.java	2006-10-03 21:15:04 UTC (rev 6559)
@@ -40,4 +40,21 @@
             throw new RulesRepositoryException(e);
         }
     }
+    
+    public boolean equals(Object in) {
+        if (!(in instanceof StateItem)) {
+            return false;
+        } else if (in == this) {
+            return true;
+        } else if (in == null) {
+            return false;
+        } else {
+            StateItem other = (StateItem) in;
+            return this.getName().equals( other.getName() );
+        }
+    }
+    
+    public int hashCode() {
+        return 42;
+    }
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RulePackageItemTestCase.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RulePackageItemTestCase.java	2006-10-03 16:45:27 UTC (rev 6558)
+++ labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RulePackageItemTestCase.java	2006-10-03 21:15:04 UTC (rev 6559)
@@ -1,18 +1,26 @@
 package org.drools.repository;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
-import javax.jcr.UnsupportedRepositoryOperationException;
-
-import org.drools.repository.*;
-
 import junit.framework.TestCase;
 
 public class RulePackageItemTestCase extends TestCase {
 
+    public void testListPackages() throws Exception {
+        RulesRepository repo = getRepo();
+        repo.createRulePackage( "testListPackages1", "lalalala" );
+        
+        List list = iteratorToList( repo.listPackages() );
+        int prevSize = list.size();
+        repo.createRulePackage( "testListPackages2", "abc" );
+        
+        list = iteratorToList( repo.listPackages() );
+        
+        assertEquals(prevSize + 1, list.size());
+    }
+    
     public void testRulePackageItem() throws Exception {
         RulesRepository repo = getRepo();
         try {
@@ -79,6 +87,76 @@
         }
     }    
     
+    /**
+     * This will test getting rules of specific versions out of a package.
+     */
+    public void testPackageRuleVersionExtraction() throws Exception {
+        RulePackageItem pack = getRepo().createRulePackage( "package extractor", "foo" );
+        
+        
+        RuleItem rule1 = pack.addRule( "rule number 1", "yeah man" );
+        RuleItem rule2 = pack.addRule( "rule number 2", "no way" );
+        RuleItem rule3 = pack.addRule( "rule number 3", "yes way" );
+        
+        getRepo().save();
+        
+        pack = getRepo().loadRulePackage( "package extractor" );
+        List rules = iteratorToList( pack.getRules() );
+        assertEquals(3, rules.size());
+        
+        StateItem state = getRepo().getState( "foobar" );
+        
+        rule1.setState( "foobar" );
+        rule1.checkin( "yeah" );
+        
+        pack = getRepo().loadRulePackage( "package extractor" );
+        
+        rules = iteratorToList( pack.getRules(state) );
+        
+        assertEquals(1, rules.size());
+        
+        //now lets try an invalid state tag
+        rules = iteratorToList( pack.getRules( getRepo().getState( "whee" ) ) );
+        assertEquals(0, rules.size());
+        
+        //and null, as we start with null, should be able to get all three back
+        //although an older version of one of them
+        rules = iteratorToList( pack.getRules(null) );
+        assertEquals(3, rules.size());
+        
+        //now do an update, and pull it out via state
+        rule1.updateRuleContent( "new content" );
+        rule1.setState( "draft" );
+        rule1.checkin( "latest" );
+        
+        rules = iteratorToList( pack.getRules(getRepo().getState( "draft" )) );
+        assertEquals(1, rules.size());
+        RuleItem rule = (RuleItem) rules.get( 0 );
+        assertEquals("new content", rule.getRuleContent());
+        
+        //get the previous one via state
+        
+        rules = iteratorToList( pack.getRules(getRepo().getState( "foobar" )) );
+        assertEquals(1, rules.size());
+        RuleItem prior = (RuleItem) rules.get( 0 );
+        
+        assertFalse("new content".equals( prior.getRuleContent() ));
+        
+    }
+    
+    public void testDuplicatePackageName() throws Exception {
+        RulePackageItem pack = getRepo().createRulePackage( "dupePackageTest", "testing for dupe" );        
+        assertNotNull(pack.getName());
+        
+        try {
+            getRepo().createRulePackage( "dupePackageTest", "this should fail" );
+            fail("Should not be able to add a package of the same name.");
+        } catch (RulesRepositoryException e) {
+            assertNotNull(e.getMessage());
+        }
+        
+    }
+    
     public void testLoadRulePackageItemByUUID() throws Exception {
 
         RulePackageItem rulePackageItem = getRepo().createRulePackage("testLoadRuleRuleItemByUUID", "desc");




More information about the jboss-svn-commits mailing list