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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Sep 7 05:37:53 EDT 2006


Author: michael.neale at jboss.com
Date: 2006-09-07 05:37:31 -0400 (Thu, 07 Sep 2006)
New Revision: 6100

Added:
   labs/jbossrules/trunk/drools-repository/pom.xml
   labs/jbossrules/trunk/drools-repository/src/main/
   labs/jbossrules/trunk/drools-repository/src/main/java/
   labs/jbossrules/trunk/drools-repository/src/main/java/org/
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/CategoryItem.java
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/DslItem.java
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/FunctionItem.java
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/Item.java
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/ItemVersionIterator.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/RulePackageIterator.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/RulesRepositoryException.java
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/StateItem.java
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/VersionableItem.java
   labs/jbossrules/trunk/drools-repository/src/main/resources/
   labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/
   labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/dsl_node_type.cnd
   labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/function_node_type.cnd
   labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/rule_node_type.cnd
   labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/rulepackage_node_type.cnd
   labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/state_node_type.cnd
   labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/tag_node_type.cnd
   labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/versionable_node_type.cnd
   labs/jbossrules/trunk/drools-repository/src/test/
   labs/jbossrules/trunk/drools-repository/src/test/java/
   labs/jbossrules/trunk/drools-repository/src/test/java/org/
   labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/
   labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/
   labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/CategoryItemTestCase.java
   labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/DslItemTestCase.java
   labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/FunctionItemTestCase.java
   labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RepositorySession.java
   labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RuleItemTestCase.java
   labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RulePackageItemTestCase.java
   labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RulesRepositoryTestCase.java
   labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/ScalabilityTest.java
   labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/StackUtil.java
Removed:
   labs/jbossrules/trunk/drools-repository/build.internal-targets.xml
   labs/jbossrules/trunk/drools-repository/build.properties
   labs/jbossrules/trunk/drools-repository/build.xml
   labs/jbossrules/trunk/drools-repository/classes/
   labs/jbossrules/trunk/drools-repository/dist/
   labs/jbossrules/trunk/drools-repository/lib/
   labs/jbossrules/trunk/drools-repository/log4j.xml
   labs/jbossrules/trunk/drools-repository/resources/
   labs/jbossrules/trunk/drools-repository/src/java/
   labs/jbossrules/trunk/drools-repository/src/node_type_definitions/
Modified:
   labs/jbossrules/trunk/drools-repository/.classpath
   labs/jbossrules/trunk/drools-repository/.project
Log:


Modified: labs/jbossrules/trunk/drools-repository/.classpath
===================================================================
--- labs/jbossrules/trunk/drools-repository/.classpath	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/.classpath	2006-09-07 09:37:31 UTC (rev 6100)
@@ -1,20 +1,20 @@
-<?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="src" path="src/java"/>
-	<classpathentry kind="lib" path="lib/commons-collections-3.1.jar"/>
-	<classpathentry kind="lib" path="lib/concurrent-1.3.4.jar"/>
-	<classpathentry kind="lib" path="lib/derby-10.1.1.0.jar"/>
-	<classpathentry kind="lib" path="lib/jackrabbit-core-1.0-SNAPSHOT.jar"/>
-	<classpathentry kind="lib" path="lib/jcr-1.0.jar"/>
-	<classpathentry kind="lib" path="lib/junit-3.8.1.jar"/>
-	<classpathentry kind="lib" path="lib/log4j-1.2.8.jar"/>
-	<classpathentry kind="lib" path="lib/lucene-1.4.3.jar"/>
-	<classpathentry kind="lib" path="lib/slf4j-log4j12-1.0.jar"/>
-	<classpathentry kind="lib" path="lib/svnant.jar"/>
-	<classpathentry kind="lib" path="lib/svnClientAdapter.jar"/>
-	<classpathentry kind="lib" path="lib/svnjavahl.jar"/>
-	<classpathentry kind="lib" path="lib/xercesImpl-2.6.2.jar"/>
-	<classpathentry kind="lib" path="lib/xmlParserAPIs-2.0.2.jar"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
+  <classpathentry kind="src" path="src/main/java"/>
+  <classpathentry kind="src" path="src/main/resources"/>
+  <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
+  <classpathentry kind="src" path="src/test/resources" output="target/test-classes"/>
+  <classpathentry kind="output" path="target/classes"/>
+  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+  <classpathentry kind="var" path="M2_REPO/xerces/xercesImpl/2.6.2/xercesImpl-2.6.2.jar"/>
+  <classpathentry kind="var" path="M2_REPO/lucene/lucene/1.4.3/lucene-1.4.3.jar"/>
+  <classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.8/log4j-1.2.8.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/apache/jackrabbit/jackrabbit-core/1.0.1/jackrabbit-core-1.0.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/xerces/xmlParserAPIs/2.0.2/xmlParserAPIs-2.0.2.jar"/>
+  <classpathentry kind="var" path="M2_REPO/commons-collections/commons-collections/3.1/commons-collections-3.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/concurrent/concurrent/1.3.4/concurrent-1.3.4.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-log4j12/1.0/slf4j-log4j12-1.0.jar"/>
+  <classpathentry kind="var" path="M2_REPO/jsr170/jcr/1.0/jcr-1.0.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/apache/derby/derby/10.1.1.0/derby-10.1.1.0.jar"/>
+  <classpathentry kind="var" path="M2_REPO/geronimo-spec/geronimo-spec-jta/1.0-M1/geronimo-spec-jta-1.0-M1.jar"/>
+</classpath>
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-repository/.project
===================================================================
--- labs/jbossrules/trunk/drools-repository/.project	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/.project	2006-09-07 09:37:31 UTC (rev 6100)
@@ -1,17 +1,14 @@
-<?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-	<name>drools-repository</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
+  <name>drools</name>
+  <comment/>
+  <projects/>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+      <arguments/>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+  </natures>
+</projectDescription>
\ No newline at end of file

Deleted: labs/jbossrules/trunk/drools-repository/build.internal-targets.xml
===================================================================
--- labs/jbossrules/trunk/drools-repository/build.internal-targets.xml	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/build.internal-targets.xml	2006-09-07 09:37:31 UTC (rev 6100)
@@ -1,27 +0,0 @@
-<project name="crm-internal-targets">    
-    
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-<!-- these are the internal targets                                                                            -->
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-              
-    <target name="compile">
-        <javac srcdir="${src.dir}" 
-               destdir="${classes.dir}" 
-               debug="on" 
-               optimize="off" 
-               memoryMaximumSize="384m" 
-               fork="true">
-            <classpath refid="base.libraries"/>
-            <compilerarg value="-Xlint:unchecked"/>
-        </javac>
-    </target>
-
-    <target name="jar" depends="compile">
-        <jar jarfile="${dist.dir}/repository.jar" update="false">
-            <fileset dir="${classes.dir}">
-                <include name="org/drools/repository/**/*"/>
-            </fileset>
-        </jar>        
-    </target>
-    
-</project>

Deleted: labs/jbossrules/trunk/drools-repository/build.properties
===================================================================
--- labs/jbossrules/trunk/drools-repository/build.properties	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/build.properties	2006-09-07 09:37:31 UTC (rev 6100)
@@ -1,3 +0,0 @@
-junit.home=/usr/java/junit3.8.1
-jboss.home=/usr/java/jboss-4.0.3SP1
-axis.home=/usr/java/axis-1_3
\ No newline at end of file

Deleted: labs/jbossrules/trunk/drools-repository/build.xml
===================================================================
--- labs/jbossrules/trunk/drools-repository/build.xml	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/build.xml	2006-09-07 09:37:31 UTC (rev 6100)
@@ -1,125 +0,0 @@
-<project name="drools-repository" default="main" basedir=".">        
-    <property file="build.properties"/>        
-    
-    <!-- default jdk location -->
-    <condition property="java.home.path" value="/usr/java/jdk1.5.0_05">
-        <not><isset property="${java.home.path}"/></not>
-    </condition>
-        
-    <property environment="env"/>
-	        
-    <property name="deploy.home" value="${jboss.home}/server/all/deploy"/>            
-    <property name="conf.home" value="${jboss.home}/server/all/conf"/>
-    <property name="build.dir" value="${basedir}/build"/>
-    <property name="lib.dir" value="${basedir}/lib"/>
-    <property name="reports.dir" value="${basedir}/reports"/>
-    <property name="classes.dir" value="${basedir}/classes"/>
-    <property name="src.dir" value="${basedir}/src/java"/>
-    <property name="dist.dir" value="${basedir}/dist"/>
-    <property name="resources.dir" value="${basedir}/resources"/>
-    <property name="doc.dir" value="${basedir}/doc"/>
-    <property name="java.home" value="${java.home.path}"/>
-    
-    <path id="axis.path">
-        <fileset dir="${axis.home}/lib" includes="*.jar"/>
-        <fileset dir="${jboss.home}/client" includes="activation.jar,mail.jar"/>
-    </path>
-
-    <path id="project.classpath">
-        <fileset dir="${lib.dir}">
-            <include name="**/*.jar"/>
-        </fileset>
-    </path>    
-    
-    <taskdef name="svn" classname="org.tigris.subversion.svnant.SvnTask" classpathref="project.classpath"/>    
-
-    <path id="base.libraries">
-        <pathelement location="${classes.dir}"/>
-        <fileset dir="${axis.home}/lib" includes="*.jar"/>
-        <fileset dir="${jboss.home}/lib" includes="*.jar"/>
-        <fileset dir="${jboss.home}/client" includes="*.jar"/>
-        <fileset dir="${jboss.home}/server/all/lib" includes="*.jar"/>
-        <fileset dir="${junit.home}" includes="junit.jar"/>
-        <fileset dir="${lib.dir}" includes="*.jar"/>
-    </path>
-    
-    <import file="./build.internal-targets.xml"/>
-    
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-<!-- these are the external targets. they are the ones that will be used typically by users. all internal      -->
-<!-- targets, which are not intended to be used by users normally, are in build.internal-targets.xml.          -->
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-    
-    <!-- Note: in the future if we decide to use hot-deploys with exploded jars, the build-incremental, build-full
-               and deploy targets will need to work differently. -->
-    <target name="build-incremental" depends="jar" description="do an incremental build of jar"/>    
-    
-    <target name="build-full" depends="clean, jar" description="do a clean build of jar "/>   
-    
-    <target name="build-cc" depends="clean, fetch, build-full, deploy, test" description="The build that is run by the continuous integration tool (CruiseControl). Run clean, fetch, build-full, test"/>
-    
-    <target name="test" description="run the junit tests. generate a report.">
-        <junit printsummary="yes" showoutput="yes" dir="${basedir}" haltonerror="false" haltonfailure="false" failureproperty="junitFailure">
-            <classpath>
-                <pathelement path="${classes.dir}"/>
-                <pathelement path="${src.dir}"/>
-                <pathelement path="./${resources.dir}"/>
-                <path refid="project.classpath"/>
-                <path refid="base.libraries"/>
-            </classpath>
-            <formatter type="plain"/>
-            <formatter type="xml"/>
-            <sysproperty key="java.endorsed.dirs" value="${jboss.home}/lib/endorsed"/>
-            <batchtest fork="yes" todir="${reports.dir}">
-                <fileset dir="${src.dir}">
-                    <include name="org/drools/repository/test/**/*Test.java"/>
-                    <include name="org/drools/repository/test/**/*TestCase.java"/>
-                </fileset>
-            </batchtest>
-        </junit>
-        <junitreport todir="${reports.dir}">
-            <fileset dir="${reports.dir}">
-                <include name="TEST-*.xml"/>
-            </fileset>
-            <report format="frames" 
-                    styledir="${resources.dir}/styles"
-                    todir="${reports.dir}/html"/>
-        </junitreport>
-        <fail if="junitFailure"/>
-    </target>
-    
-    <target name="clean" description="clean out the output directories">
-        <delete>
-            <fileset dir="${dist.dir}" includes="*.jar"/>
-        </delete>
-        <delete dir="${classes.dir}/com"/>        
-        <delete>
-            <fileset dir="${reports.dir}" includes="**/*"/>        
-        </delete>        
-    </target>
-        
-    <target name="deploy" description="ship the jars, wars, whatever to the execution system (this system)">
-        <fail message="not yet implemented" />    
-    </target>    
-        
-    <target name="fetch" description="get the latest source from the subversion repository">
-        <fail message="not yet implemented" />
-    </target>
-    
-    <target name="javadoc" description="do the documentation">
-        <javadoc destdir="${doc.dir}/javadoc" author="true" version="true" maxmemory="256M" use="true" packagenames="org.drools.repository.*" sourcepath="${src.dir}" windowtitle="rules repository API">
-            <classpath>
-                <path refid="base.libraries"/>
-                <path location="${junit.home}/junit.jar"/>
-            </classpath>    
-            <doctitle><![CDATA[<h1>rules repository API</h1>]]></doctitle>
-            <bottom><![CDATA[<i>Copyright &#169; 2006 Rackspace Corp. All Rights Reserved.</i>]]></bottom>
-            <tag name="todo" scope="all" description="To do:"/>
-        </javadoc>
-    </target>    
-    
-    <target name="all" depends="clean, fetch, build-full, test, javadoc, deploy" description="clean, fetch, build, javadoc, deploy, test"/>
-
-    <target name="main" depends="build-incremental, test" description="the default target. build-incremental, test"/>       
-
-</project>

Deleted: labs/jbossrules/trunk/drools-repository/log4j.xml
===================================================================
--- labs/jbossrules/trunk/drools-repository/log4j.xml	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/log4j.xml	2006-09-07 09:37:31 UTC (rev 6100)
@@ -1,152 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
-
-<!-- ===================================================================== -->
-<!--                                                                       -->
-<!--  Log4j Configuration                                                  -->
-<!--                                                                       -->
-<!-- ===================================================================== -->
-
-<!--
-   | For more configuration infromation and examples see the Jakarta Log4j
-   | owebsite: http://jakarta.apache.org/log4j
- -->
-
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
-
-   <!-- ================================= -->
-   <!-- Preserve messages in a local file -->
-   <!-- ================================= -->
-
-   <!-- ============================== -->
-   <!-- Append messages to the console -->
-   <!-- ============================== -->
-
-   <appender name="REPOSITORY_CONSOLE" class="org.apache.log4j.ConsoleAppender">
-      <param name="Target" value="System.out"/>
-      <param name="Threshold" value="DEBUG"/>
-
-      <layout class="org.apache.log4j.PatternLayout">
-         <!-- The default pattern: Date Priority [Category] Message\n -->
-         <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
-      </layout>
-   </appender>
-
-   <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
-      <param name="Target" value="System.out"/>
-      <param name="Threshold" value="INFO"/>
-
-      <layout class="org.apache.log4j.PatternLayout">
-         <!-- The default pattern: Date Priority [Category] Message\n -->
-         <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
-      </layout>
-   </appender>
-
-   <!-- ====================== -->
-   <!-- More Appender examples -->
-   <!-- ====================== -->
-
-   <!-- Buffer events and log them asynchronously
-   <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
-     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
-     <appender-ref ref="FILE"/>
-     <appender-ref ref="CONSOLE"/>
-     <appender-ref ref="SMTP"/>
-   </appender>
-   -->
-
-   <!-- EMail events to an administrator
-   <appender name="SMTP" class="org.apache.log4j.net.SMTPAppender">
-     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
-     <param name="Threshold" value="ERROR"/>
-     <param name="To" value="admin at myhost.domain.com"/>
-     <param name="From" value="nobody at myhost.domain.com"/>
-     <param name="Subject" value="JBoss Sever Errors"/>
-     <param name="SMTPHost" value="localhost"/>
-     <param name="BufferSize" value="10"/>
-     <layout class="org.apache.log4j.PatternLayout">
-       <param name="ConversionPattern" value="[%d{ABSOLUTE},%c{1}] %m%n"/>
-     </layout>
-   </appender>
-   -->
-
-   <!-- Syslog events
-   <appender name="SYSLOG" class="org.apache.log4j.net.SyslogAppender">
-     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
-     <param name="Facility" value="LOCAL7"/>
-     <param name="FacilityPrinting" value="true"/>
-     <param name="SyslogHost" value="localhost"/>
-     <layout class="org.apache.log4j.PatternLayout">
-       <param name="ConversionPattern" value="[%d{ABSOLUTE},%c{1}] %m%n"/>
-     </layout>
-   </appender>
-   -->
-
-   <!-- Log events to JMS (requires a topic to be created)
-   <appender name="JMS" class="org.apache.log4j.net.JMSAppender">
-     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
-     <param name="Threshold" value="ERROR"/>
-     <param name="TopicConnectionFactoryBindingName" value="java:/ConnectionFactory"/>
-     <param name="TopicBindingName" value="topic/MyErrorsTopic"/>
-   </appender>
-   -->
-
-   <!-- Log events through SNMP
-   <appender name="TRAP_LOG" class="org.apache.log4j.ext.SNMPTrapAppender">
-     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
-     <param name="ImplementationClassName" value="org.apache.log4j.ext.JoeSNMPTrapSender"/>
-     <param name="ManagementHost" value="127.0.0.1"/>
-     <param name="ManagementHostTrapListenPort" value="162"/>
-     <param name="EnterpriseOID" value="1.3.6.1.4.1.24.0"/>
-     <param name="LocalIPAddress" value="127.0.0.1"/>
-     <param name="LocalTrapSendPort" value="161"/>
-     <param name="GenericTrapType" value="6"/>
-     <param name="SpecificTrapType" value="12345678"/>
-     <param name="CommunityString" value="public"/>
-     <param name="ForwardStackTraceWithTrap" value="true"/>
-     <param name="Threshold" value="DEBUG"/>
-     <param name="ApplicationTrapOID" value="1.3.6.1.4.1.24.12.10.22.64"/>
-     <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="%d,%p,[%t],[%c],%m%n"/>
-     </layout>
-   </appender>
-   -->
-
-   <!--  Emit events as JMX notifications
-   <appender name="JMX" class="org.jboss.monitor.services.JMXNotificationAppender">
-      <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
-      
-      <param name="Threshold" value="WARN"/>
-      <param name="ObjectName" value="jboss.system:service=Logging,type=JMXNotificationAppender"/>
-      
-      <layout class="org.apache.log4j.PatternLayout">
-         <param name="ConversionPattern" value="%d %-5p [%c] %m"/>
-      </layout>
-   </appender>
-   -->
-   
-   <!-- ================ -->
-   <!-- Limit categories -->
-   <!-- ================ -->
-
-   <!-- Limit the org.apache category to INFO as its DEBUG is verbose -->
-   <category name="org.apache">
-      <priority value="INFO"/>
-   </category>
-
-   <!-- ======================= -->
-   <!-- Drools Repository       -->
-   <!-- ======================= -->
-   <category name="org.drools.repository">
-     <priority value="DEBUG" />
-     <appender-ref ref="REPOSITORY_CONSOLE"/>
-   </category>
-
-   <!-- ======================= -->
-   <!-- Setup the Root category -->
-   <!-- ======================= -->
-
-   <root>
-      <appender-ref ref="CONSOLE"/>
-   </root>
-</log4j:configuration>

Added: labs/jbossrules/trunk/drools-repository/pom.xml
===================================================================
--- labs/jbossrules/trunk/drools-repository/pom.xml	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/pom.xml	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,34 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+    <artifactId>drools</artifactId>
+    <groupId>org.drools</groupId>
+    <version>3.0.2</version>
+
+  <repositories>
+    <repository>
+      <id>basedir</id>
+      <url>file://${basedir}/../repository</url>
+    </repository>
+  </repositories> 
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+
+    <!-- first the deps for the repo API itself (Jackrabbit based) -->
+    <dependency>
+           <groupId>org.apache.jackrabbit</groupId>
+           <artifactId>jackrabbit-core</artifactId>
+           <version>1.0.1</version>
+    </dependency>
+  </dependencies>
+  
+  <build>
+    <finalName>drools-repository</finalName>
+  </build>
+</project>

Added: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/CategoryItem.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/CategoryItem.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/CategoryItem.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,112 @@
+package org.drools.repository;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionIterator;
+
+import org.apache.log4j.Logger;
+
+/**
+ * The TagItem class abstracts away details of the underlying JCR repository.
+ * 
+ * @author btruitt
+ */
+public class CategoryItem extends Item {
+    private Logger log = Logger.getLogger(CategoryItem.class);
+    
+    /**
+     * The name of the tag node type
+     */
+    public static final String TAG_NODE_TYPE_NAME = "drools:categoryNodeType";
+    
+    /**
+     * Constructs an object of type TagItem corresponding the specified node
+     * @param rulesRepository the rulesRepository that instantiated this object
+     * @param node the node to which this object corresponds
+     * @throws RulesRepositoryException 
+     */
+    public CategoryItem(RulesRepository rulesRepository, Node node) throws RulesRepositoryException {
+        super(rulesRepository, node);
+        
+        try {
+            //make sure this node is a tag node       
+            if(!(this.node.getPrimaryNodeType().getName().equals(TAG_NODE_TYPE_NAME))) {
+                String message = this.node.getName() + " is not a node of type " + TAG_NODE_TYPE_NAME + ". It is a node of type: " + this.node.getPrimaryNodeType().getName();
+                log.error(message);
+                throw new RulesRepositoryException(message);
+            }    
+        }
+        catch(Exception e) {
+            log.error("Caught exception: " + e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+
+    /**
+     * @return the full path of this tag, rooted at the tag area of the repository. 
+     * @throws RulesRepositoryException 
+     */
+    public String getFullPath() throws RulesRepositoryException {        
+        try {
+            log.debug("getting full path for node named: " + this.node.getName());
+            
+            StringBuffer returnString = new StringBuffer();
+            returnString.append(this.node.getName());
+            Node parentNode = this.node.getParent();
+            while(!parentNode.getName().equals(RulesRepository.TAG_AREA)) {
+                returnString.insert(0, parentNode.getName() + "/");
+                parentNode = parentNode.getParent();
+            }
+            return returnString.toString();                           
+        }
+        catch(Exception e) {            
+            log.error("Caught Exception: " + e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * @return a List of the immediate children of this tag
+     * @throws RulesRepositoryException 
+     */
+    public List getChildTags() throws RulesRepositoryException {
+        List children = new ArrayList();
+        
+        try {
+            NodeIterator it = this.node.getNodes();
+            while(it.hasNext()) {
+                Node currentNode = it.nextNode();
+                children.add(new CategoryItem(this.rulesRepository, currentNode));
+            }
+        }
+        catch(Exception e) {
+            log.error("Caught Exception: " + e);
+            throw new RulesRepositoryException(e);
+        }        
+        
+        return children;
+    }
+
+    /**
+     * Gets a TagItem object encapsulating the specified child tag. If the child tag 
+     * doesn't exist, it is created.
+     * 
+     * @param tagName the name of the child tag to get or add
+     * @return a TagItem encapsulating the specified child tag
+     * @throws RulesRepositoryException
+     */
+    public CategoryItem getChildTag(String tagName) throws RulesRepositoryException {
+        try {
+            return this.rulesRepository.getOrCreateCategory(this.getFullPath() + "/" + tagName);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception: " + e);
+            throw new RulesRepositoryException(e);
+        }
+    }        
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/CategoryItem.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/DslItem.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/DslItem.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/DslItem.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,183 @@
+package org.drools.repository;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionIterator;
+
+import org.apache.log4j.Logger;
+
+/**
+ * The DslItem is used to abstract away details of the JCR repository 
+ * 
+ * @author btruitt
+ */
+public class DslItem extends VersionableItem {
+    private Logger log = Logger.getLogger(DslItem.class);
+    
+    /**
+     * The name of the DSL node type
+     */
+    public static final String DSL_NODE_TYPE_NAME = "drools:dslNodeType";
+
+    public static final String DSL_CONTENT = "drools:dslContent";
+    
+    /**
+     * Constructs a DslItem object with the specified node as its node attribute
+     * 
+     * @param rulesRepository the rulesRepository that instantiated this object
+     * @param node
+     * @throws RulesRepositoryException 
+     */
+    public DslItem(RulesRepository rulesRepository, Node node) throws RulesRepositoryException {
+        super(rulesRepository, node);
+        
+        try {
+            //make sure this node is a dsl node       
+            if(!(this.node.getPrimaryNodeType().getName().equals(DSL_NODE_TYPE_NAME) ||
+                 this.node.getPrimaryNodeType().getName().equals("nt:version"))) {
+                String message = this.node.getName() + " is not a node of type " + DSL_NODE_TYPE_NAME + " nor nt:version. It is a node of type: " + this.node.getPrimaryNodeType().getName();
+                log.error(message);
+                throw new RulesRepositoryException(message);
+            }    
+        }
+        catch(Exception e) {
+            log.error("Caught exception: " + e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * returns the content of this object's dsl node
+     * 
+     * @return the content of this object's dsl node
+     * @throws RulesRepositoryException
+     */
+    public String getContent() throws RulesRepositoryException {
+        try {            
+            Node dslNode;
+            if(this.node.getPrimaryNodeType().getName().equals("nt:version")) {
+                dslNode = this.node.getNode("jcr:frozenNode");
+            }
+            else {
+                dslNode = this.node;
+            }
+            
+            Property data = dslNode.getProperty( DSL_CONTENT );
+            return data.getValue().getString();
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Creates a new version of this object's dsl node, using the content and attributes of the
+     * specified file.
+     * 
+     * @param file the file from which to get the content and attributes for the new version of the
+     *             dsl node
+     * @throws RulesRepositoryException
+     */
+    public void updateContent(String content) throws RulesRepositoryException {
+        try {
+            this.node.checkout();
+        }
+        catch(UnsupportedRepositoryOperationException e) {
+            String message = "";
+            try {
+                message = "Error: Caught UnsupportedRepositoryOperationException when attempting to checkout node: " + this.node.getName() + ". Are you sure your JCR repository supports versioning? ";
+                log.error(message + e);
+            }
+            catch (RepositoryException e1) {
+                log.error("Caught Exception", e);
+                throw new RulesRepositoryException(e1);
+            }
+            throw new RulesRepositoryException(message, e);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+        
+        try {
+            
+            Calendar lastModified = Calendar.getInstance();
+            this.node.setProperty(LAST_MODIFIED_PROPERTY_NAME, lastModified);
+            this.node.setProperty( DSL_CONTENT, content );
+            
+            this.node.getSession().save();                      
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+        finally {
+            try {
+                this.node.checkin();
+            }
+            catch(Exception e) {
+                log.error("Caught Exception: " + e);
+                throw new RulesRepositoryException(e);
+            }
+        }
+    }
+    
+    /**
+     * Nicely formats the information contained by the node that this object encapsulates
+     */
+    public String toString() {                
+        try {
+            StringBuffer returnString = new StringBuffer();
+            returnString.append("Content of DSL node named " + this.node.getName() + ":\n");
+            returnString.append(this.getContent() + "\n");
+            returnString.append("--------------\n");
+            return returnString.toString();
+        }
+        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 DslItem(this.rulesRepository, precedingVersionNode);
+            }
+            else {
+                return null;
+            }
+        }        
+        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 DslItem(this.rulesRepository, succeedingVersionNode);
+            }
+            else {
+                return null;
+            }
+        }        
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }          
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/DslItem.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/FunctionItem.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/FunctionItem.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/FunctionItem.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,475 @@
+package org.drools.repository;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
+
+import org.apache.log4j.Logger;
+
+/**
+ * The FunctionItem class is used to abstract away the details of the underlying JCR repository.
+ * It is used to pass information about functions stored in the repository.
+ * 
+ * @author btruitt
+ */
+public class FunctionItem extends VersionableItem {
+    private Logger log = Logger.getLogger(FunctionItem.class);    
+    
+    /**
+     * The name of the tag property on the function node type
+     */
+    public static final String TAG_PROPERTY_NAME = "drools:categoryReference";
+    
+    /**
+     * The name of the function node type
+     */
+    public static final String FUNCTION_NODE_TYPE_NAME = "drools:functionNodeType";
+    
+    /**
+     * The name of the state property on the function node type
+     */
+    public static final String STATE_PROPERTY_NAME = "drools:stateReference";                 
+    
+    /**
+     * The name of the content property on the function node type
+     */
+    public static final String CONTENT_PROPERTY_NAME = "drools:content";            
+    
+    /**
+     * The name of the function language property on the function node type
+     */
+    public static final String FUNCTION_LANGUAGE_PROPERTY_NAME = "drools:functionLanguage";
+    
+    /**
+     * Constructs a FunctionItem object, setting its node attribute to the specified node.
+     * 
+     * @param rulesRepository the rulesRepository that instantiated this object
+     * @param node the node in the repository that this FunctionItem corresponds to
+     * @throws RulesRepositoryException 
+     */
+    public FunctionItem(RulesRepository rulesRepository, Node node) throws RulesRepositoryException {
+        super(rulesRepository, node);
+        
+        try {
+            //make sure this node is a function node       
+            if(!(this.node.getPrimaryNodeType().getName().equals(FUNCTION_NODE_TYPE_NAME) ||
+                 this.node.getPrimaryNodeType().getName().equals("nt:version"))) {
+                String message = this.node.getName() + " is not a node of type " + FUNCTION_NODE_TYPE_NAME + " nor nt:version. It is a node of type: " + this.node.getPrimaryNodeType().getName();
+                log.error(message);
+                throw new RulesRepositoryException(message);
+            }    
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * returns the content of this object's function node
+     * 
+     * @return the content of this object's function node
+     * @throws RulesRepositoryException
+     */
+    public String getContent() throws RulesRepositoryException {
+        try {                        
+            Node functionNode;
+            if(this.node.getPrimaryNodeType().getName().equals("nt:version")) {
+                functionNode = this.node.getNode("jcr:frozenNode");
+            }
+            else {
+                functionNode = this.node;
+            }
+                        
+            Property data = functionNode.getProperty(CONTENT_PROPERTY_NAME);
+            return data.getValue().getString();
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }                
+    
+    /**
+     * @return the function language of this object's function node
+     * @throws RulesRepositoryException
+     */
+    public String getFunctionLanguage() throws RulesRepositoryException {
+        try {                        
+            Node functionNode;
+            if(this.node.getPrimaryNodeType().getName().equals("nt:version")) {
+                functionNode = this.node.getNode("jcr:frozenNode");
+            }
+            else {
+                functionNode = this.node;
+            }
+                        
+            Property languageProperty = functionNode.getProperty(FUNCTION_LANGUAGE_PROPERTY_NAME);
+            return languageProperty.getValue().getString();
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Creates a new version of this object's function node, updating th content for the
+     * function node. 
+     * 
+     * @param newContent the new content for the function
+     * @throws RulesRepositoryException
+     */
+    public void updateContent(String newContent) throws RulesRepositoryException {
+        try {
+            this.node.checkout();
+        }
+        catch(UnsupportedRepositoryOperationException e) {
+            String message = "";
+            try {
+                message = "Error: Caught UnsupportedRepositoryOperationException when attempting to checkout rule: " + this.node.getName() + ". Are you sure your JCR repository supports versioning? ";
+                log.error(message, e);
+            }
+            catch (RepositoryException e1) {
+                log.error("Caught Exception", e);
+                throw new RulesRepositoryException(e1);
+            }
+            throw new RulesRepositoryException(message, e);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+        
+        try {                                    
+            this.node.setProperty(CONTENT_PROPERTY_NAME, newContent);
+            
+            Calendar lastModified = Calendar.getInstance();
+            this.node.setProperty(LAST_MODIFIED_PROPERTY_NAME, lastModified);
+            
+            this.node.getSession().save();
+            
+            this.node.checkin();
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }            
+    
+    /**
+     * Adds the specified tag to this object's function node. Tags are stored as nodes in a tag area of
+     * the repository. If the specified tag does not already have a corresponding node, a node is 
+     * created for it.
+     *  
+     * @param tag the tag to add to the function. functions can have multiple tags
+     * @throws RulesRepositoryException 
+     */
+    public void addTag(String tag) throws RulesRepositoryException {
+        try {
+            //make sure this object's node is the head version
+            if(this.node.getPrimaryNodeType().getName().equals("nt:version")) {
+                String message = "Error. Tags can only be added to the head version of a function node";
+                log.error(message);
+                throw new RulesRepositoryException(message);
+            }                                       
+            
+            CategoryItem tagItem = this.rulesRepository.getOrCreateCategory(tag);
+                                    
+            //now set the tag property of the node
+            Property tagReferenceProperty;
+            int i = 0;
+            Value[] newTagValues = null;
+            try {
+                tagReferenceProperty = this.node.getProperty(TAG_PROPERTY_NAME);
+                Value[] oldTagValues = tagReferenceProperty.getValues();
+                
+                //first, make sure this tag wasn't already there. while we're at it, lets copy the array
+                newTagValues = new Value[oldTagValues.length + 1];                
+                for(i=0; i<oldTagValues.length; i++) {
+                    if(oldTagValues[i].getString().equals(tag)) {
+                        log.info("tag '" + tag + "' already existed for function node: " + this.node.getName());
+                        return;
+                    }
+                    newTagValues[i] = oldTagValues[i];
+                }
+            }
+            catch(PathNotFoundException e) {
+                //the property doesn't exist yet, so create it in the finally block
+                newTagValues = new Value[1];                 
+            }
+            finally {   
+                if(newTagValues != null) {
+                    newTagValues[i] = this.node.getSession().getValueFactory().createValue(tagItem.getNode());
+                    this.node.checkout();
+                    this.node.setProperty(TAG_PROPERTY_NAME, newTagValues);
+                    this.node.getSession().save();
+                    this.node.checkin();
+                }
+                else {
+                    log.error("reached expected path of execution when adding tag '" + tag + "' to functionNode: " + this.node.getName());
+                }
+            }
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+
+    /**
+     * Removes the specified tag from this object's function node.
+     * 
+     * @param tag the tag to remove from the node
+     * @throws RulesRepositoryException 
+     */
+    public void removeTag(String tag) throws RulesRepositoryException {
+        //TODO: implement if the removed tag no longer has anyone referencing it, remove the tag (are we sure we want to do this, for versioning's sake?)
+        try {
+            //make sure this object's node is the head version
+            if(this.node.getPrimaryNodeType().getName().equals("nt:version")) {
+                String message = "Error. Tags can only be removed from the head version of a function node";
+                log.error(message);
+                throw new RulesRepositoryException(message);
+            }                                                   
+                                    
+            //now set the tag property of the rule
+            Property tagReferenceProperty;
+            int i = 0;
+            int j = 0;
+            Value[] newTagValues = null;
+            try {
+                tagReferenceProperty = this.node.getProperty(TAG_PROPERTY_NAME);
+                Value[] oldTagValues = tagReferenceProperty.getValues();
+                
+                //see if the tag was even there
+                boolean wasThere = false;
+                for(i=0; i<oldTagValues.length; i++) {
+                    Node tagNode = this.node.getSession().getNodeByUUID(oldTagValues[i].getString());
+                    if(tagNode.getName().equals(tag)) {                                                
+                        wasThere = true;
+                    }
+                }
+                
+                if(wasThere) {
+                    //copy the array, minus the specified tag
+                    newTagValues = new Value[oldTagValues.length + 1];                
+                    for(i=0; i<oldTagValues.length; i++) {
+                        Node tagNode = this.node.getSession().getNodeByUUID(oldTagValues[i].getString());
+                        if(!tagNode.getName().equals(tag)) {                                                         
+                            newTagValues[j] = oldTagValues[i];
+                            j++;
+                        }
+                    }
+                }
+                else {
+                    //TODO: remove the tag if it isn't used by anyone else
+                    return;
+                }
+            }
+            catch(PathNotFoundException e) {
+                //the property doesn't exist yet
+                //TODO: first remove the tag if it isn't used by anyone else
+                return;             
+            }
+            finally {   
+                if(newTagValues != null) {
+                    this.node.checkout();
+                    this.node.setProperty(TAG_PROPERTY_NAME, newTagValues);
+                    this.node.getSession().save();
+                    this.node.checkin();
+                }
+                else {
+                    log.error("reached expected path of execution when removing tag '" + tag + "' from functionNode: " + this.node.getName());
+                }
+            }
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Gets a list of TagItem objects for this object's function node.
+     * 
+     * @return a list of TagItem objects for each tag on the node. If there are no tags, an empty list. 
+     * @throws RulesRepositoryException
+     */
+    public List getTags() throws RulesRepositoryException {
+        try {                            
+            Node functionNode;
+            if(this.node.getPrimaryNodeType().getName().equals("nt:version")) {
+                functionNode = this.node.getNode("jcr:frozenNode");
+            }
+            else {
+                functionNode = this.node;
+            }
+            
+            List returnList = new ArrayList();
+            try {
+                Property tagReferenceProperty = functionNode.getProperty(TAG_PROPERTY_NAME);
+                Value[] tagValues = tagReferenceProperty.getValues();                
+                for(int i=0; i<tagValues.length; i++) {
+                    Node tagNode = this.node.getSession().getNodeByUUID(tagValues[i].getString());
+                    CategoryItem tagItem = new CategoryItem(this.rulesRepository, tagNode);
+                    returnList.add(tagItem);
+                }
+            }
+            catch(PathNotFoundException e) {
+                //the property doesn't even exist yet, so just return nothing
+            }
+            return returnList;
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Sets this object's function node's state property to refer to the specified state node
+     * 
+     * @param stateName the name of the state to set the function node to
+     * @throws RulesRepositoryException 
+     */
+    public void setState(String stateName) throws RulesRepositoryException {
+        try {
+            StateItem stateItem = this.rulesRepository.getState(stateName);
+            this.setState(stateItem);
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Sets this object's function node's state property to refer to the specified StateItem's node
+     * 
+     * @param stateItem the StateItem encapsulating the node to refer to from this object's node's state 
+     *                  property
+     * @throws RulesRepositoryException 
+     */
+    public void setState(StateItem stateItem) throws RulesRepositoryException {
+        try {
+            //make sure this node is a function node
+            if(this.node.getPrimaryNodeType().getName().equals("nt:version")) {
+                String message = "Error. States can only be set for the head version of a function node";
+                log.error(message);
+                throw new RulesRepositoryException(message);
+            } 
+            
+            //now set the state property of the rule                              
+            this.node.checkout();
+            this.node.setProperty(STATE_PROPERTY_NAME, stateItem.getNode());
+            this.node.getSession().save();
+            this.node.checkin();        
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Gets StateItem object corresponding to the state property of this object's node
+     * 
+     * @return a StateItem object corresponding to the state property of this object's node, or null
+     *         if the state property is not set
+     * @throws RulesRepositoryException
+     */
+    public StateItem getState() throws RulesRepositoryException {
+        try {
+            Property stateProperty = this.node.getProperty(STATE_PROPERTY_NAME);
+            Node stateNode = this.node.getSession().getNodeByUUID(stateProperty.getString());
+            return new StateItem(this.rulesRepository, stateNode);
+        }
+        catch(PathNotFoundException e) {
+            //not set
+            return null;
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+
+    /**
+     * Nicely formats the information contained by the node that this object encapsulates
+     */
+    public String toString() {                
+        try {
+            StringBuffer returnString = new StringBuffer();
+            returnString.append("Content of function item named '" + this.getName() + "':\n");
+            returnString.append(this.getContent() + "\n");
+            returnString.append("------\n");
+                        
+            returnString.append("Function Language: " + this.getFunctionLanguage() + "\n");
+            returnString.append("Version Name: " + this.getVersionName() + "\n");
+            returnString.append("------\n");
+            
+            returnString.append("Function state: ");
+            StateItem stateItem = this.getState();
+            if(stateItem != null) {
+                returnString.append(this.getState().getName() + "\n");
+            }
+            else {
+                returnString.append("NO STATE SET FOR THIS NODE\n");
+            }            
+            returnString.append("------\n");
+            
+            returnString.append("Categories:\n");
+            for(Iterator it=this.getTags().iterator(); it.hasNext();) {
+                CategoryItem currentTag = (CategoryItem)it.next();
+                returnString.append(currentTag.getName() + "\n");
+            }
+            returnString.append("--------------\n");
+            return returnString.toString();
+        }
+        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 FunctionItem(this.rulesRepository, precedingVersionNode);
+            }
+            else {
+                return null;
+            }
+        }        
+        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 FunctionItem(this.rulesRepository, succeedingVersionNode);
+            }
+            else {
+                return null;
+            }
+        }        
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }           
+}
\ No newline at end of file


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/FunctionItem.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/Item.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/Item.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/Item.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,106 @@
+package org.drools.repository;
+
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionIterator;
+
+import org.apache.log4j.Logger;
+
+
+/**
+ * The item class is used to abstract away the underlying details of the JCR repository.
+ * 
+ * @author btruitt
+ */
+public abstract class Item {
+    Logger log = Logger.getLogger(Item.class);
+
+    /**
+     * The node within the repository that this item corresponds to
+     */
+    protected Node node;
+    
+    /**
+     * The RulesRepository object that this object was created from
+     */
+    protected RulesRepository rulesRepository;
+
+    /**
+     * Sets the item object's node attribute to the specified node
+     * 
+     * @param rulesRepository the RulesRepository object that this object is being created from
+     * @param node the node in the repository that this item corresponds to
+     */
+    public Item(RulesRepository rulesRepository, Node node) {
+        this.rulesRepository = rulesRepository;
+        this.node = node;
+    }
+
+    /**
+     * gets the node in the repository that this item is associated with
+     * 
+     * @return the node in the repository that this item is associated with
+     */
+    public Node getNode() {
+        return node;
+    }    
+    
+    /**
+     * gets the name of this item (unless overridden in a subclass, this just returns the
+     * name of the node that this Item encapsulates.
+     * 
+     * @return the name of the node that this item encapsultes
+     * @throws RulesRepositoryException 
+     */
+    public String getName() throws RulesRepositoryException {
+        try {
+            return this.node.getName();
+        }
+        catch(Exception e) {
+            log.error("Caught exception: " + e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+
+    /**
+     * @return the RulesRepository object that this object was instantiated from
+     */
+    public RulesRepository getRulesRepository() {
+        return rulesRepository;
+    }
+    
+    public boolean equals(Object obj) {
+        if(!(obj instanceof Item)) {
+            return false;
+        }
+        else {
+            Item rhs = (Item)obj;
+            return this.node.equals(rhs.getNode());
+        }
+    }
+
+    public int hashCode() {
+        return this.node.hashCode();
+    }        
+    
+    /**
+     * @return the name of the version for this node in the version history
+     * @throws RulesRepositoryException
+     */
+    public String getVersionName() throws RulesRepositoryException {
+        try {
+            if(this.node.getPrimaryNodeType().getName().equals("nt:version")) {
+                return this.node.getName();
+            }
+            else {
+                return this.node.getBaseVersion().getName();
+            }            
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/Item.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/ItemVersionIterator.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/ItemVersionIterator.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/ItemVersionIterator.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,68 @@
+package org.drools.repository;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Implements the Iterator interface, allowing iteration over the version history of versionableItem 
+ * nodes
+ * 
+ * @author btruitt
+ */
+public class ItemVersionIterator implements Iterator {
+    private static final Logger log = Logger.getLogger(ItemVersionIterator.class);
+    
+    private VersionableItem currentVersionableItem;
+    private int iterationType;
+    
+    public static final int ITERATION_TYPE_SUCCESSOR = 1;
+    public static final int ITERATION_TYPE_PREDECESSOR = 2;
+
+    public ItemVersionIterator(VersionableItem versionableItem, int iterationType) {
+        this.currentVersionableItem = versionableItem;
+        this.iterationType = iterationType;
+    }
+    
+    public boolean hasNext() {
+        if(this.currentVersionableItem == null) {
+            return false;
+        }
+        
+        if(this.iterationType == ITERATION_TYPE_SUCCESSOR) {
+            return (this.currentVersionableItem.getSucceedingVersion() != null);
+        }
+        else if(this.iterationType == ITERATION_TYPE_PREDECESSOR) {
+            return (this.currentVersionableItem.getPrecedingVersion() != null);
+        }
+        else {
+            //shouldn't reach this block
+            log.error("Reached unexpected path of execution because iterationType is set to: " + this.iterationType);
+            return false;
+        }
+    }
+
+    public Object next() {
+        if(this.iterationType == ITERATION_TYPE_SUCCESSOR) {
+            this.currentVersionableItem = this.currentVersionableItem.getSucceedingVersion();            
+        }
+        else if(this.iterationType == ITERATION_TYPE_PREDECESSOR) {
+            this.currentVersionableItem = this.currentVersionableItem.getPrecedingVersion();
+        }
+        else {
+            //shouldn't reach this block
+            log.error("Reached unexpected path of execution because iterationType is set to: " + this.iterationType);
+            return null;
+        }
+        
+        if(this.currentVersionableItem == null) {
+            throw new NoSuchElementException();
+        }
+        return this.currentVersionableItem;
+    }
+
+    public void remove() {
+        throw new UnsupportedOperationException();
+    }
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/ItemVersionIterator.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: 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-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RuleItem.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,616 @@
+package org.drools.repository;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
+
+import org.apache.log4j.Logger;
+
+/**
+ * The RuleItem class is used to abstract away the details of the underlying JCR repository.
+ * It is used to pass information about rules stored in the repository.
+ * 
+ * @author btruitt
+ */
+public class RuleItem extends VersionableItem {
+    private Logger log = Logger.getLogger(RuleItem.class);
+    
+    /**
+     * The name of the DSL property on the rule node type
+     */
+    public static final String DSL_PROPERTY_NAME = "drools:dslReference";
+    
+    /**
+     * The name of the tag property on the rule node type
+     */
+    public static final String TAG_PROPERTY_NAME = "drools:categoryReference";
+    
+    /**
+     * The name of the rule node type
+     */
+    public static final String RULE_NODE_TYPE_NAME = "drools:ruleNodeType";
+    
+    /**
+     * The name of the state property on the rule node type
+     */
+    public static final String STATE_PROPERTY_NAME = "drools:stateReference";                 
+    
+    /**
+     * The name of the lhs property on the rule node type
+     */
+    public static final String LHS_PROPERTY_NAME = "drools:lhs";
+    
+    /**
+     * The name of the rhs property on the rule node type
+     */
+    public static final String RHS_PROPERTY_NAME = "drools:rhs";
+    
+    /**
+     * The name of the date effective property on the rule node type
+     */
+    public static final String DATE_EFFECTIVE_PROPERTY_NAME = "drools:dateEffective";
+    
+    /**
+     * The name of the date expired property on the rule node type
+     */
+    public static final String DATE_EXPIRED_PROPERTY_NAME = "drools:dateExpired";                        
+    
+    /**
+     * The name of the rule language property on the rule node type
+     */
+    public static final String RULE_LANGUAGE_PROPERTY_NAME = "drools:ruleLanguage";    
+    
+    /**
+     * Constructs a RuleItem object, setting its node attribute to the specified node.
+     * 
+     * @param rulesRepository the rulesRepository that instantiated this object
+     * @param node the node in the repository that this RuleItem corresponds to
+     * @throws RulesRepositoryException 
+     */
+    public RuleItem(RulesRepository rulesRepository, Node node) throws RulesRepositoryException {
+        super(rulesRepository, node);
+        
+        try {
+            //make sure this node is a rule node       
+            if(!(this.node.getPrimaryNodeType().getName().equals(RULE_NODE_TYPE_NAME) ||
+                 this.node.getPrimaryNodeType().getName().equals("nt:version"))) {
+                String message = this.node.getName() + " is not a node of type " + RULE_NODE_TYPE_NAME + " nor nt:version. It is a node of type: " + this.node.getPrimaryNodeType().getName();
+                log.error(message);
+                throw new RulesRepositoryException(message);
+            }    
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * returns the lhs of this object's rule node
+     * 
+     * @return the lhs of this object's rule node
+     * @throws RulesRepositoryException
+     */
+    public String getLhs() throws RulesRepositoryException {
+        try {                        
+            Node ruleNode = getVersionContentNode();
+            
+            //grab the lhs of the node and dump it into a string            
+            Property data = ruleNode.getProperty(LHS_PROPERTY_NAME);
+            return data.getValue().getString();
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * returns the rhs of this object's rule node
+     * 
+     * @return the rhs of this object's rule node
+     * @throws RulesRepositoryException
+     */
+    public String getRhs() throws RulesRepositoryException {
+        try {                        
+            Node ruleNode = getVersionContentNode();
+            
+            //grab the lhs of the node and dump it into a string            
+            Property data = ruleNode.getProperty(RHS_PROPERTY_NAME);
+            return data.getValue().getString();
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+        
+    /**
+     * @return the date the rule becomes effective
+     * @throws RulesRepositoryException
+     */
+    public Calendar getDateEffective() throws RulesRepositoryException {
+        try {                        
+            Node ruleNode = getVersionContentNode();
+                        
+            Property dateEffectiveProperty = ruleNode.getProperty(DATE_EFFECTIVE_PROPERTY_NAME);
+            return dateEffectiveProperty.getDate();
+        }
+        catch(PathNotFoundException e) {
+            // doesn't have this property
+            return null;
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Creates a new version of this object's rule node, updating the effective date for the
+     * rule node. 
+     *  
+     * @param newDateEffective the new effective date for the rule 
+     * @throws RulesRepositoryException
+     */
+    public void updateDateEffective(Calendar newDateEffective) throws RulesRepositoryException {
+        checkout();
+        
+        try {                                    
+            this.node.setProperty(DATE_EFFECTIVE_PROPERTY_NAME, newDateEffective);
+            
+            Calendar lastModified = Calendar.getInstance();
+            this.node.setProperty(LAST_MODIFIED_PROPERTY_NAME, lastModified);
+
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+
+
+    
+    /**
+     * @return the date the rule becomes expired
+     * @throws RulesRepositoryException
+     */
+    public Calendar getDateExpired() throws RulesRepositoryException {
+        try {                        
+            Node ruleNode = getVersionContentNode();
+                        
+            Property dateExpiredProperty = ruleNode.getProperty(DATE_EXPIRED_PROPERTY_NAME);
+            return dateExpiredProperty.getDate();
+        }
+        catch(PathNotFoundException e) {
+            // doesn't have this property
+            return null;
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+
+
+    
+    /**
+     * Creates a new version of this object's rule node, updating the expired date for the
+     * rule node. 
+     *  
+     * @param newDateExpired the new expired date for the rule 
+     * @throws RulesRepositoryException
+     */
+    public void updateDateExpired(Calendar newDateExpired) throws RulesRepositoryException {
+        checkout();
+        
+        try {                                    
+            this.node.setProperty(DATE_EXPIRED_PROPERTY_NAME, newDateExpired);
+            
+            Calendar lastModified = Calendar.getInstance();
+            this.node.setProperty(LAST_MODIFIED_PROPERTY_NAME, lastModified);
+;
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * @return the rule language of this object's rune node
+     * @throws RulesRepositoryException
+     */
+    public String getRuleLanguage() throws RulesRepositoryException {
+        try {                        
+            Node ruleNode = getVersionContentNode();
+                        
+            Property ruleLanguageProperty = ruleNode.getProperty(RULE_LANGUAGE_PROPERTY_NAME);
+            return ruleLanguageProperty.getValue().getString();
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Creates a new version of this object's rule node, updating the lhs content for the
+     * rule node. 
+     * 
+     * @param lhs the new lhs content for the rule
+     * @throws RulesRepositoryException
+     */
+    public RuleItem updateLhs(String newLhsContent) throws RulesRepositoryException {
+        checkout();
+        
+        try {                                    
+            this.node.setProperty(LHS_PROPERTY_NAME, newLhsContent);
+            
+            Calendar lastModified = Calendar.getInstance();
+            this.node.setProperty(LAST_MODIFIED_PROPERTY_NAME, lastModified);
+            return this;
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Creates a new version of this object's rule node, updating the rhs content for the
+     * rule node. 
+     * 
+     * @param lhs the new rhs content for the rule
+     * @throws RulesRepositoryException
+     */
+    public void updateRhs(String newRhsContent) throws RulesRepositoryException {
+        checkout();
+        
+        try {                                    
+            this.node.setProperty(RHS_PROPERTY_NAME, newRhsContent);
+            
+            Calendar lastModified = Calendar.getInstance();
+            this.node.setProperty(LAST_MODIFIED_PROPERTY_NAME, lastModified);
+
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }        
+    
+    /**
+     * Adds the specified tag to this object's rule node. Tags are stored as nodes in a tag area of
+     * the repository. If the specified tag does not already have a corresponding node, a node is 
+     * created for it.
+     *  
+     * @param tag the tag to add to the rule. rules can have multiple tags
+     * @throws RulesRepositoryException 
+     */
+    public void addCategory(String tag) throws RulesRepositoryException {
+        try {
+            //make sure this object's node is the head version
+            checkIsUpdateable();                                       
+            
+            CategoryItem tagItem = this.rulesRepository.getOrCreateCategory(tag);
+                                    
+            //now set the tag property of the rule
+            Property tagReferenceProperty;
+            int i = 0;
+            Value[] newTagValues = null;
+            try {
+                tagReferenceProperty = this.node.getProperty(TAG_PROPERTY_NAME);
+                Value[] oldTagValues = tagReferenceProperty.getValues();
+                
+                //first, make sure this tag wasn't already there. while we're at it, lets copy the array
+                newTagValues = new Value[oldTagValues.length + 1];                
+                for(i=0; i<oldTagValues.length; i++) {
+                    if(oldTagValues[i].getString().equals(tag)) {
+                        log.info("tag '" + tag + "' already existed for rule node: " + this.node.getName());
+                        return;
+                    }
+                    newTagValues[i] = oldTagValues[i];
+                }
+            }
+            catch(PathNotFoundException e) {
+                //the property doesn't exist yet, so create it in the finally block
+                newTagValues = new Value[1];                 
+            }
+            finally {   
+                if(newTagValues != null) {
+                    newTagValues[i] = this.node.getSession().getValueFactory().createValue(tagItem.getNode());
+                    this.node.checkout();
+                    this.node.setProperty(TAG_PROPERTY_NAME, newTagValues);
+                }
+                else {
+                    log.error("reached expected path of execution when adding tag '" + tag + "' to ruleNode: " + this.node.getName());
+                }
+            }
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+
+
+
+    /**
+     * Removes the specified tag from this object's rule node.
+     * 
+     * @param tag the tag to remove from the rule
+     * @throws RulesRepositoryException 
+     */
+    public void removeCategory(String tag) throws RulesRepositoryException {
+        try {
+            //make sure this object's node is the head version
+            if(this.node.getPrimaryNodeType().getName().equals("nt:version")) {
+                String message = "Error. Tags can only be removed from the head version of a rule node";
+                log.error(message);
+                throw new RulesRepositoryException(message);
+            }                                                   
+                                    
+            //now set the tag property of the rule
+            Property tagReferenceProperty;
+            int i = 0;
+            int j = 0;
+            Value[] newTagValues = null;
+            try {
+                tagReferenceProperty = this.node.getProperty(TAG_PROPERTY_NAME);
+                Value[] oldTagValues = tagReferenceProperty.getValues();
+                
+                //see if the tag was even there
+                boolean wasThere = false;
+                for(i=0; i<oldTagValues.length; i++) {
+                    Node tagNode = this.node.getSession().getNodeByUUID(oldTagValues[i].getString());
+                    if(tagNode.getName().equals(tag)) {                                                
+                        wasThere = true;
+                    }
+                }
+                
+                if(wasThere) {
+                    //copy the array, minus the specified tag
+                    newTagValues = new Value[oldTagValues.length + 1];                
+                    for(i=0; i<oldTagValues.length; i++) {
+                        Node tagNode = this.node.getSession().getNodeByUUID(oldTagValues[i].getString());
+                        if(!tagNode.getName().equals(tag)) {                                                         
+                            newTagValues[j] = oldTagValues[i];
+                            j++;
+                        }
+                    }
+                }
+                else {
+                    //TODO: remove the tag if it isn't used by anyone else
+                    return;
+                }
+            }
+            catch(PathNotFoundException e) {
+                //the property doesn't exist yet
+                //TODO: first remove the tag if it isn't used by anyone else
+                return;             
+            }
+            finally {   
+                if(newTagValues != null) {
+                    checkout();
+                    this.node.setProperty(TAG_PROPERTY_NAME, newTagValues);
+                }
+                else {
+                    log.error("reached expected path of execution when removing tag '" + tag + "' from ruleNode: " + this.node.getName());
+                }
+            }
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Gets a list of TagItem objects for this object's rule node.
+     * 
+     * @return a list of TagItem objects for each tag on the rule. If there are no tags, an empty list. 
+     * @throws RulesRepositoryException
+     */
+    public List getCategories() throws RulesRepositoryException {
+        try {                            
+            Node ruleNode;
+            if(this.node.getPrimaryNodeType().getName().equals("nt:version")) {
+                ruleNode = this.node.getNode("jcr:frozenNode");
+            }
+            else {
+                ruleNode = this.node;
+            }
+            
+            List returnList = new ArrayList();
+            try {
+                Property tagReferenceProperty = ruleNode.getProperty(TAG_PROPERTY_NAME);
+                Value[] tagValues = tagReferenceProperty.getValues();                
+                for(int i=0; i<tagValues.length; i++) {
+                    Node tagNode = this.node.getSession().getNodeByUUID(tagValues[i].getString());
+                    CategoryItem tagItem = new CategoryItem(this.rulesRepository, tagNode);
+                    returnList.add(tagItem);
+                }
+            }
+            catch(PathNotFoundException e) {
+                //the property doesn't even exist yet, so just return nothing
+            }
+            return returnList;
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Sets this object's rule node's state property to refer to the specified state node
+     * 
+     * @param stateName the name of the state to set the rule node to
+     * @throws RulesRepositoryException 
+     */
+    public void setState(String stateName) throws RulesRepositoryException {
+        try {
+            StateItem stateItem = this.rulesRepository.getState(stateName);
+            this.setState(stateItem);
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Sets this object's rule node's state property to refer to the specified StateItem's node
+     * 
+     * @param stateItem the StateItem encapsulating the node to refer to from this object's node's state 
+     *                  property
+     * @throws RulesRepositoryException 
+     */
+    public void setState(StateItem stateItem) 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();
+            this.node.setProperty(STATE_PROPERTY_NAME, stateItem.getNode());
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Gets StateItem object corresponding to the state property of this object's node
+     * 
+     * @return a StateItem object corresponding to the state property of this object's node, or null
+     *         if the state property is not set
+     * @throws RulesRepositoryException
+     */
+    public StateItem getState() throws RulesRepositoryException {
+        try {
+            Property stateProperty = this.node.getProperty(STATE_PROPERTY_NAME);
+            Node stateNode = this.node.getSession().getNodeByUUID(stateProperty.getString());
+            return new StateItem(this.rulesRepository, stateNode);
+        }
+        catch(PathNotFoundException e) {
+            //not set
+            return null;
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+
+    /**
+     * Gets a DslItem object corresponding to the DSL reference from the node that this object
+     * encapsulates.
+     * 
+     * @return a DslItem object corresponding to the DSL reference for this rule node. If there is
+     *         no DSL node referenced from this object's node, then null.
+     * @throws RulesRepositoryException 
+     */
+    public DslItem getDsl() throws RulesRepositoryException {
+        try {
+            Property dslProperty = this.node.getProperty(DSL_PROPERTY_NAME);
+            Node dslNode = this.node.getSession().getNodeByUUID(dslProperty.getString());
+            return new DslItem(this.rulesRepository, dslNode);
+        }
+        catch(PathNotFoundException e) {
+            //not set
+            return null;
+        }
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Nicely formats the information contained by the node that this object encapsulates
+     */
+    public String toString() {                
+        try {
+            StringBuffer returnString = new StringBuffer();
+            returnString.append("Content of rule item named '" + this.getName() + "':\n");
+            returnString.append("LHS: " + this.getLhs() + "\n");
+            returnString.append("RHS: " + this.getRhs() + "\n");
+            returnString.append("------\n");
+            
+            returnString.append("Date Effective: " + this.getDateEffective() + "\n");
+            returnString.append("Date Expired: " + this.getDateExpired() + "\n");
+            returnString.append("Rule Language: " + this.getRuleLanguage() + "\n");
+            returnString.append("Version Name: " + this.getVersionName() + "\n");
+            returnString.append("------\n");
+            
+            returnString.append("Rule state: ");
+            StateItem stateItem = this.getState();
+            if(stateItem != null) {
+                returnString.append(this.getState().getName() + "\n");
+            }
+            else {
+                returnString.append("NO STATE SET FOR THIS NODE\n");
+            }            
+            returnString.append("------\n");
+            
+            returnString.append("Rule tags:\n");
+            for(Iterator it=this.getCategories().iterator(); it.hasNext();) {
+                CategoryItem currentTag = (CategoryItem)it.next();
+                returnString.append(currentTag.getName() + "\n");
+            }
+            returnString.append("--------------\n");
+            return returnString.toString();
+        }
+        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 RuleItem(this.rulesRepository, precedingVersionNode);
+            }
+            else {
+                return null;
+            }
+        }        
+        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 RuleItem(this.rulesRepository, succeedingVersionNode);
+            }
+            else {
+                return null;
+            }
+        }        
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }           
+}
\ No newline at end of file


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RuleItem.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: 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-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulePackageItem.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,501 @@
+package org.drools.repository;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.Node;
+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.version.Version;
+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.  
+ * <p>
+ * A rule set refers to rule nodes within the RulesRepository.  It can either have the reference to a 
+ * specific rule follow the head version of that rule, or have this reference continue to refer to 
+ * a specific version of that rule even when a new version of the rule is checked into the repository
+ * 
+ * @author btruitt
+ */
+public class RulePackageItem extends VersionableItem {       
+    private static Logger log = Logger.getLogger(RulePackageItem.class);
+    
+    /**
+     * 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";
+    
+    /**
+     * 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";    
+    
+    /**
+     * The name of the rule package node type
+     */
+    public static final String RULE_PACKAGE_TYPE_NAME = "drools:rulepackageNodeType";   
+    
+    /**
+     * 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);
+        
+        try {
+            //make sure this node is a rule package node       
+            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);
+            }    
+        }
+        catch(Exception e) {
+            log.error("Caught exception: " + e);
+            throw new RulesRepositoryException(e);
+        }
+    }    
+    
+    /**
+     * Adds a rule to the rule package node this object represents.  The reference to the rule 
+     * will follow the head version of the specified rule's node.
+     * 
+     * @param ruleItem the ruleItem corresponding to the node to add to the rule package this
+     *                 object represents
+     * @throws RulesRepositoryException
+     */
+    public void addRule(RuleItem ruleItem) throws RulesRepositoryException {
+        this.addRule(ruleItem, true);        
+    }
+    
+    /**
+     * 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 addRule(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 {
+                        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.
+     * 
+     * @param functionItem the functionItem corresponding to the node to add to the rule package this
+     *                 object represents
+     * @throws RulesRepositoryException
+     */
+    public void addFunction(FunctionItem functionItem) throws RulesRepositoryException {
+        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.
+     * 
+     * @param functionItem the functionItem corresponding to the node to add to the rule package this 
+     *                 object represents
+     * @param followRuleHead if true, the reference to the function 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 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++) {
+                    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(followFunctionHead) {                    
+                        newValueArray[i] = factory.createValue(functionItem.getNode());
+                    }
+                    else {
+                        newValueArray[i] = factory.createValue(functionItem.getNode().getBaseVersion());
+                    }
+                    this.node.checkout();
+                    this.node.setProperty(FUNCTION_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 function: " + functionItem.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);
+        }
+    }
+    
+    /**
+     * Removes the specified rule from the rule package node this object represents.  
+     * 
+     * @param ruleItem the ruleItem corresponding to the node to remove from the rule package 
+     *                 this object represents
+     * @throws RulesRepositoryException
+     */
+    public void removeRule(RuleItem ruleItem) throws RulesRepositoryException {                
+        try {
+            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)) {
+                    wasThere = true;
+                }
+                else {
+                    newValueArray[j] = oldValueArray[i];
+                    j++;
+                }
+            }
+                            
+            if(!wasThere) {
+                return;
+            }
+            else {
+                this.node.checkout();
+                this.node.setProperty(RULE_REFERENCE_PROPERTY_NAME, newValueArray);                
+                this.node.getSession().save();
+                this.node.checkin();
+            }
+        }
+        catch(PathNotFoundException e) {
+            //the property has not been created yet. 
+            return;
+        }  
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+
+    /**
+     * Removes the specified function from the rule package node this object represents.  
+     * 
+     * @param functionItem the functionItem corresponding to the node to remove from the rule package 
+     *                 this object represents
+     * @throws RulesRepositoryException
+     */
+    public void removeFunction(FunctionItem functionItem) throws RulesRepositoryException {                
+        try {
+            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)) {
+                    wasThere = true;
+                }
+                else {
+                    newValueArray[j] = oldValueArray[i];
+                    j++;
+                }
+            }
+                            
+            if(!wasThere) {
+                return;
+            }
+            else {
+                this.node.checkout();
+                this.node.setProperty(FUNCTION_REFERENCE_PROPERTY_NAME, newValueArray);                
+                this.node.getSession().save();
+                this.node.checkin();
+            }
+        }
+        catch(PathNotFoundException e) {
+            //the property has not been created yet. 
+            return;
+        }  
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+
+    /**
+     * Gets a list of FunctionItem objects for each function node in this rule package
+     * 
+     * @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();
+            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));
+            }
+            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);
+        }
+    }    
+    
+    /**
+     * Removes all functions from the rule package
+     * 
+     * @throws RulesRepositoryException
+     */
+    public void removeAllFunctions() throws RulesRepositoryException {
+        try {
+            Property functionsProperty = this.node.getProperty(FUNCTION_REFERENCE_PROPERTY_NAME);
+            this.node.checkout();
+            functionsProperty.remove();
+            this.node.save();
+            this.node.checkin();
+        }
+        catch(PathNotFoundException e) {
+            //the property has not been created yet. 
+            return;
+        }                                       
+        catch(Exception e) {
+            log.error("Caught exception: " + e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Removes all rules from the rule package
+     * 
+     * @throws RulesRepositoryException
+     */
+    public void removeAllRules() throws RulesRepositoryException {
+        try {
+            Property rulesProperty = this.node.getProperty(RULE_REFERENCE_PROPERTY_NAME);
+            this.node.checkout();
+            rulesProperty.remove();
+            this.node.save();
+            this.node.checkin();
+        }
+        catch(PathNotFoundException e) {
+            //the property has not been created yet. 
+            return;
+        }                                       
+        catch(Exception e) {
+            log.error("Caught exception: " + e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Nicely formats the information contained by the node that this object encapsulates    
+     */
+    public String toString() {
+        try {            
+            StringBuffer returnString = new StringBuffer();
+            returnString.append("Content of the rule package named " + this.node.getName() + ":");
+            returnString.append("Contributor: " + this.getContributor() + "\n");
+            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");
+            
+            //iterate over the rules in this rule package and dump them
+            returnString.append("Rules in rule package: \n");
+            List ruleItems = this.getRules();
+            Iterator it = ruleItems.iterator();
+            while(it.hasNext()) {
+                RuleItem currentRuleItem = (RuleItem)it.next();
+                returnString.append(currentRuleItem.toString() + "\n");
+            }
+            returnString.append("----\n");
+            
+            //iterate over the functions in this rule package and dump them
+            returnString.append("Functions in rule package: \n");
+            List functionItems = this.getFunctions();
+            it = functionItems.iterator();
+            while(it.hasNext()) {
+                FunctionItem currentFunctionItem = (FunctionItem)it.next();
+                returnString.append(currentFunctionItem.toString() + "\n");
+            }
+            returnString.append("--------\n");
+            
+            return returnString.toString();
+        }
+        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 {
+                return null;
+            }
+        }        
+        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 {
+                return null;
+            }
+        }        
+        catch(Exception e) {
+            log.error("Caught exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }          
+}
\ No newline at end of file


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulePackageItem.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulePackageIterator.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulePackageIterator.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulePackageIterator.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,37 @@
+package org.drools.repository;
+
+import java.util.Iterator;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+
+/**
+ * This wraps a node iterator, and provides RulePackageItems when requested.
+ * This supports lazy loading if needed.
+ */
+public class RulePackageIterator
+    implements
+    Iterator {
+    
+    
+    
+    private NodeIterator packageNodeIterator;
+    private RulesRepository repository;
+
+    public RulePackageIterator(RulesRepository repository, NodeIterator packageNodes) {
+        this.packageNodeIterator = packageNodes;
+    }
+
+    public boolean hasNext() {
+        return this.packageNodeIterator.hasNext();
+    }
+
+    public Object next() {        
+        return new RulePackageItem(this.repository, (Node) this.packageNodeIterator.next());
+    }
+
+    public void remove() {
+        this.packageNodeIterator.remove();
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulePackageIterator.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: 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-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulesRepository.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,986 @@
+package org.drools.repository;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.jcr.NamespaceException;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
+import javax.jcr.Workspace;
+
+import org.apache.jackrabbit.core.TransientRepository;
+import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
+import org.apache.jackrabbit.core.nodetype.NodeTypeDef;
+import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
+import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+import org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader;
+import org.apache.log4j.Logger;
+
+
+/**
+ * RulesRepository is the class that defines the bahavior for the JBoss Rules (drools) rule repository
+ * based upon the JCR specification (JSR-170).  
+ * <p>
+ * An instance of this class is capable of storing rules used by the JBoss Rule engine.  It also 
+ * provides a versioning capability for rules.  Rules can be imported from specified files.  The 
+ * RulesRepository is also capable of storing DSL content.  Rules can be explicitly tied to a 
+ * particular DSL node within the repository, and this reference can either follow the head version,
+ * or a specific version of the DSL node.  
+ * <p>
+ * The RulesRepository also is capable of storing RulePackages, which aggregate one or more Rules into 
+ * a set.  RulePackages hold references to the nodes storing the content of the rules in the set within 
+ * the repository.  Each entry in a rulepackage can either refer to the head version of the given rule
+ * node, or a specific version.   
+ * <p>
+ * Rules can be tagged. Tags are stored in a separate area of the repository, and can be added on
+ * demand.  Rules can have 0 or more tags. Tags are intended to help provide a means for searching
+ * for specific types of rules quickly, even when they aren't all part of the same rulepackage.
+ * <p>
+ * Rules can be associated with 0 or 1 states.  States are created in a seperate area of the 
+ * repository. States are intended to help track the progress of a rule as it traverses its life-
+ * cycle. (e.g. draft, approved, deprecated, etc.)
+ * <p>
+ * The RulesRepository provides versioning of rules, rule packages, and DSLs.  This versioning works
+ * in a strictly linear fashion, with one version having at most 1 predecessor version (or none, if
+ * it is the first version), and at most 1 successor version (or none, if it is the most recently
+ * checked-in version).  The JCR specification supports a more complicated versioning system, and 
+ * if there is sufficient demand, we can modify our versioning scheme to be better aligned with JCR's
+ * versioning abilities.
+ * 
+ * @author btruitt
+ */
+public class RulesRepository {
+    private static final String DROOLS_URI = "http://www.jboss.org/drools-repository/1.0";
+
+    private static final Logger log = Logger.getLogger(RulesRepository.class);
+    
+    /**
+     * The name of the rulepackage area of the repository
+     */
+    public final static String RULE_PACKAGE_AREA = "drools:rulepackage_area";
+    
+    /**
+     * The name of the rule area of the repository
+     */
+    public final static String RULE_AREA = "drools:rule_area";
+    
+    /**
+     * The name of the rule area of the repository
+     */
+    public final static String FUNCTION_AREA = "drools:function_area";
+    
+    /**
+     * The name of the DSL area of the repository
+     */
+    public final static String DSL_AREA = "drools:dsl_area";
+    
+    /**
+     * The name of the tag area of the repository
+     */
+    public final static String TAG_AREA = "drools:tag_area";
+    
+    /**
+     * The name of the state area of the repository
+     */
+    public final static String STATE_AREA = "drools:state_area";
+    
+    /**
+     * The name of the rules repository within the JCR repository
+     */
+    public final static String RULES_REPOSITORY_NAME = "drools:repository";
+    
+    private Repository repository;
+    private Session session;
+
+    /**
+     * This will create the JCR repository automatically if it does not already exist.  
+     * It will call setupRepository() to attempt to setup the repository, in case
+     * it has not already been setup.  
+     */
+    public RulesRepository() {
+        this(false);
+    }
+    
+    /**
+     * This will create the JCR repository automatically if it does not already exist.  
+     * It will call setupRepository() to attempt to setup the repository, in case
+     * it has not already been setup.
+     *   
+     * @param clearRepository whether or not to erase the contents of the rules repository
+     *                        portion of the JCR repository 
+     */
+    public RulesRepository(boolean clearRepository) {       
+        try {
+            //TODO: probably want to do something more serious than automatic creation of a 
+            //      transientRepository here.  (e.g. manual creation of the repository to be 
+            //      JCR implementation neutral). be sure to update the javadoc
+            repository = new TransientRepository();
+            session = repository.login(
+                                       new SimpleCredentials("username", "password".toCharArray()));
+
+            if(this.session == null) {
+                log.error("LOGIN FAILED! SESSION IS NULL!");
+            }                  
+            
+            if(clearRepository) {
+                this.clearRepository();
+            }
+            
+            setupRepository();            
+        }
+        catch (Exception e) {
+            log.error("Caught Exception", e);
+        }    
+    }
+    
+    /**
+     * Clears out the entire tree below the rules repository node of the JCR repository.
+     */
+    public void clearRepository() {
+        try {
+            log.info("Clearing rules repository");
+            Node node = session.getRootNode().getNode(RULES_REPOSITORY_NAME);
+            node.remove();
+        }
+        catch(PathNotFoundException e) {                
+            //doesn't exist yet. no biggie.
+        }          
+        catch(RepositoryException e) {
+            //this will happen on the first setup. no biggie.
+        }
+    }
+    
+    private void registerNodeTypesFromCndFile(String cndFileName, Workspace ws) throws RulesRepositoryException, InvalidNodeTypeDefException {
+        try {
+            //Read in the CND file
+            Reader in = new InputStreamReader(this.getClass().getResourceAsStream( cndFileName ));
+            
+            // Create a CompactNodeTypeDefReader
+            CompactNodeTypeDefReader cndReader = new CompactNodeTypeDefReader(in, cndFileName);
+            
+            // Get the List of NodeTypeDef objects
+            List ntdList = cndReader.getNodeTypeDefs();
+            
+            // Get the NodeTypeManager from the Workspace.
+            // Note that it must be cast from the generic JCR NodeTypeManager to the
+            // Jackrabbit-specific implementation.
+            NodeTypeManagerImpl ntmgr = (NodeTypeManagerImpl)ws.getNodeTypeManager();
+            
+            // Acquire the NodeTypeRegistry
+            NodeTypeRegistry ntreg = ntmgr.getNodeTypeRegistry();
+            
+            // Loop through the prepared NodeTypeDefs
+            for(Iterator i = ntdList.iterator(); i.hasNext();) {                               
+                // Get the NodeTypeDef...
+                NodeTypeDef ntd = (NodeTypeDef)i.next();                                        
+                
+                log.debug("Attempting to regsiter node type named: " + ntd.getName());
+                
+                // ...and register it            
+                ntreg.registerNodeType(ntd);
+            }
+        }
+        catch(InvalidNodeTypeDefException e) {
+            log.warn("InvalidNodeTypeDefinitionException caught when trying to add node from CND file: " + cndFileName + ". This will happen if the node type was already registered. " + e);
+            throw e;
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Attempts to setup the repository.  If the work that it tries to do has already been done, it 
+     * will return with modifying the repository.
+     * 
+     * @throws RulesRepositoryException     
+     */
+    protected void setupRepository() throws RulesRepositoryException {
+        try {
+            Node root = session.getRootNode();
+            Workspace ws = session.getWorkspace();
+
+            //no need to set it up again, skip it if it has.
+            boolean registered = false;
+            String uris[] = ws.getNamespaceRegistry().getURIs();            
+            for ( int i = 0; i < uris.length; i++ ) {
+                if (DROOLS_URI.equals( uris[i]) ) {
+                    registered = true;
+                }
+            }
+
+            if (!registered) {
+                ws.getNamespaceRegistry().registerNamespace("drools", DROOLS_URI);
+                
+                this.registerNodeTypesFromCndFile("/node_type_definitions/versionable_node_type.cnd", ws);
+                this.registerNodeTypesFromCndFile("/node_type_definitions/dsl_node_type.cnd", ws);            
+                this.registerNodeTypesFromCndFile("/node_type_definitions/tag_node_type.cnd", ws);
+                this.registerNodeTypesFromCndFile("/node_type_definitions/state_node_type.cnd", ws);
+                this.registerNodeTypesFromCndFile("/node_type_definitions/rule_node_type.cnd", ws);
+                this.registerNodeTypesFromCndFile("/node_type_definitions/function_node_type.cnd", ws);
+                this.registerNodeTypesFromCndFile("/node_type_definitions/rulepackage_node_type.cnd", ws);
+            }
+            
+            // Setup the rule repository node
+            Node repositoryNode = addNodeIfNew(root, RULES_REPOSITORY_NAME, "nt:folder");
+                    
+            // Setup the Rule area
+            addNodeIfNew(repositoryNode, RULE_AREA, "nt:folder");
+            
+            //Setup the Rule area
+            addNodeIfNew(repositoryNode, FUNCTION_AREA, "nt:folder");
+            
+            // Setup the RulePackageItem area        
+            addNodeIfNew(repositoryNode, RULE_PACKAGE_AREA, "nt:folder");
+            
+            // Setup the DSL area                
+            addNodeIfNew(repositoryNode, DSL_AREA, "nt:folder");
+            
+            //Setup the DSL area                
+            addNodeIfNew(repositoryNode, TAG_AREA, "nt:folder");
+            
+            //Setup the State area                
+            addNodeIfNew(repositoryNode, STATE_AREA, "nt:folder");
+            
+            session.save();                        
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            System.err.println(e.getMessage());
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Will add a node named 'nodeName' of type 'type' to 'parent' if such a node does not already
+     * exist.
+     * 
+     * @param parent the parent node to add the new node to
+     * @param nodeName the name of the new node
+     * @param type the type of the new node
+     * @return a reference to the Node object that is created by the addition, or, if the node already
+     *         existed, a reference to the pre-existant node.
+     * @throws RulesRepositoryException
+     */
+    protected Node addNodeIfNew(Node parent, String nodeName, String type) throws RulesRepositoryException {              
+        Node node;
+        try {
+            node = parent.getNode(nodeName);                
+        }
+        catch(PathNotFoundException e) {
+            //it doesn't exist yet, so create it                       
+            try {
+                log.debug("Adding new node of type: " + type + " named: " + nodeName + " to parent node named " + parent.getName());
+                
+                node = parent.addNode(nodeName, type);
+            }
+            catch (Exception e1) {                
+                log.error("Caught Exception", e);
+                throw new RulesRepositoryException(e1);
+            }
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+        return node;
+    }
+    
+    /**
+     * Explicitly logout of the underlying JCR repository.  If this is the last session to that
+     * repository, the repository will automatically be shutdown.
+     */
+    public void logout() {
+        this.session.logout();
+    }
+    
+    /**
+     * Recursively outputs the contents of the workspace starting from root. The large subtree
+     * called jcr:system is skipped.  This method is just here for programmatic debugging 
+     * purposes, and should be removed.
+     * 
+     * @throws RulesRepositoryException
+     */
+    public void dumpRepository() throws RulesRepositoryException {
+        try {
+            this.dump(this.session.getRootNode());
+        }
+        catch(Exception e) {
+            log.error("Caught exception: " + e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /** 
+     * Recursively outputs the contents of the given node. Used for debugging purposes. 
+     */
+    private void dump(final Node node) throws RulesRepositoryException {
+        try {
+            // First output the node path
+            System.out.println(node.getPath());
+            // Skip the virtual (and large!) jcr:system subtree
+            /*if (node.getName().equals("jcr:system")) {
+                return;
+            }*/
+    
+            // Then output the properties
+            PropertyIterator properties = node.getProperties();
+            while (properties.hasNext()) {
+                Property property = properties.nextProperty();
+                if (property.getDefinition().isMultiple()) {
+                    // A multi-valued property, print all values
+                    Value[] values = property.getValues();
+                    for (int i = 0; i < values.length; i++) {
+                        System.out.println(
+                            property.getPath() + " = " + values[i].getString());
+                    }
+                } else {
+                    // A single-valued property
+                    System.out.println(
+                        property.getPath() + " = " + property.getString());
+                }
+            }
+    
+            // Finally output all the child nodes recursively
+            NodeIterator nodes = node.getNodes();
+            while (nodes.hasNext()) {
+                dump(nodes.nextNode());
+            }
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }                
+    
+    private Map areaNodeCache = new HashMap();
+    
+    private Node getAreaNode(String areaName) throws RulesRepositoryException {
+        if (areaNodeCache.containsKey( areaName )) {
+            return (Node) areaNodeCache.get( areaName );
+        } else {
+            Node folderNode = null;
+            int tries = 0;
+            while(folderNode == null && tries < 2) {
+                try {
+                    tries++;                                                
+                    folderNode = this.session.getRootNode().getNode(RULES_REPOSITORY_NAME + "/" + areaName);
+                }
+                catch(PathNotFoundException e) {
+                    if(tries == 1) {
+                        //hmm..repository must have gotten screwed up.  set it up again                
+                        log.warn("The repository appears to have become corrupted. It will be re-setup now.");
+                        this.setupRepository();
+                    }
+                    else {
+                        log.error("Unable to correct repository corruption");
+                    }
+                }
+                catch(Exception e) {
+                    log.error("Caught Exception", e);
+                    throw new RulesRepositoryException("Caught exception " + e.getClass().getName(), e);
+                }
+            }
+            if(folderNode == null) {
+                String message = "Could not get a reference to a node for " + RULES_REPOSITORY_NAME + "/" + areaName;
+                log.error(message);
+                throw new RulesRepositoryException(message);
+            }
+            areaNodeCache.put( areaName, folderNode );
+            return folderNode;
+        }
+    }
+    
+    /**
+     * Adds a DSL node in the repository using the content and attributes of the specified file
+     * 
+     * @param file the file to use to import the DSL content and attributes
+     * @return a DslItem object encapsulating the node that gets added
+     * @throws RulesRepositoryException 
+     */
+    public DslItem addDsl(String name, String content) throws RulesRepositoryException { 
+        Node folderNode = this.getAreaNode(DSL_AREA);            
+        
+        try {
+            //create the node - see section 6.7.22.6 of the spec
+            Node dslNode = folderNode.addNode(name, DslItem.DSL_NODE_TYPE_NAME);
+            
+            dslNode.setProperty(DslItem.TITLE_PROPERTY_NAME, name);
+            
+            //TODO: set this property correctly once we've figured out logging in / JAAS
+            dslNode.setProperty(DslItem.CONTRIBUTOR_PROPERTY_NAME, "not yet implemented");
+                        
+            dslNode.setProperty(DslItem.DESCRIPTION_PROPERTY_NAME, "");
+            dslNode.setProperty(DslItem.FORMAT_PROPERTY_NAME, DslItem.DSL_FORMAT);
+            
+            dslNode.setProperty( DslItem.DSL_CONTENT, content );
+            dslNode.setProperty(DslItem.LAST_MODIFIED_PROPERTY_NAME, Calendar.getInstance());
+            
+            this.session.save();
+            
+            try {
+                dslNode.checkin();
+            }
+            catch(UnsupportedRepositoryOperationException e) {
+                String message = "Error: Caught UnsupportedRepositoryOperationException when attempting to checkin dsl: " + dslNode.getName() + ". Are you sure your JCR repository supports versioning? ";
+                log.error(message + e);
+                throw new RulesRepositoryException(message, e);
+            }
+            
+            return new DslItem(this, dslNode);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }                
+    }    
+    
+    /**
+     * Adds a Function node in the repository using the content specified.
+     * 
+     * @param functionName the name of the function
+     * @param content the content of the function
+     * @return a FunctionItem object encapsulating the node that gets added
+     * @throws RulesRepositoryException
+     */
+    public FunctionItem addFunction(String functionName, String content) throws RulesRepositoryException {
+        Node folderNode = this.getAreaNode(FUNCTION_AREA);        
+        
+        try {        
+            //create the node - see section 6.7.22.6 of the spec
+            Node functionNode = folderNode.addNode(functionName, FunctionItem.FUNCTION_NODE_TYPE_NAME);
+                        
+            functionNode.setProperty(FunctionItem.TITLE_PROPERTY_NAME, functionName);
+            functionNode.setProperty(FunctionItem.CONTENT_PROPERTY_NAME, content);
+            functionNode.setProperty(FunctionItem.DESCRIPTION_PROPERTY_NAME, "");
+            
+            //TODO: set contributor correctly
+            functionNode.setProperty(FunctionItem.CONTRIBUTOR_PROPERTY_NAME, "");
+            
+            functionNode.setProperty(FunctionItem.FORMAT_PROPERTY_NAME, FunctionItem.FUNCTION_FORMAT);
+            
+            Calendar lastModified = Calendar.getInstance();
+            functionNode.setProperty(FunctionItem.LAST_MODIFIED_PROPERTY_NAME, lastModified);
+            
+            session.save();
+            
+            try {
+                functionNode.checkin();
+            }
+            catch(UnsupportedRepositoryOperationException e) {
+                String message = "Error: Caught UnsupportedRepositoryOperationException when attempting to checkin node: " + functionNode.getName() + ". Are you sure your JCR repository supports versioning? ";
+                log.error(message + e);
+                throw new RulesRepositoryException(message, e);
+            }
+            
+            return new FunctionItem(this, functionNode);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Adds a Function node in the repository using the content specified.
+     * 
+     * @param functionName the name of the function
+     * @param content the content of the function
+     * @param description the description of the function
+     * @return a FunctionItem object encapsulating the node that gets added
+     * @throws RulesRepositoryException
+     */
+    public FunctionItem addFunction(String functionName, String content, String description) throws RulesRepositoryException {
+        Node folderNode = this.getAreaNode(FUNCTION_AREA);        
+        
+        try {        
+            //create the node - see section 6.7.22.6 of the spec
+            Node functionNode = folderNode.addNode(functionName, FunctionItem.FUNCTION_NODE_TYPE_NAME);
+                        
+            functionNode.setProperty(FunctionItem.TITLE_PROPERTY_NAME, functionName);
+            functionNode.setProperty(FunctionItem.CONTENT_PROPERTY_NAME, content);
+            functionNode.setProperty(FunctionItem.DESCRIPTION_PROPERTY_NAME, description);
+            functionNode.setProperty(FunctionItem.FORMAT_PROPERTY_NAME, FunctionItem.FUNCTION_FORMAT);
+            
+            //TODO: set contributor correctly
+            functionNode.setProperty(FunctionItem.CONTRIBUTOR_PROPERTY_NAME, "");
+            
+            Calendar lastModified = Calendar.getInstance();
+            functionNode.setProperty(FunctionItem.LAST_MODIFIED_PROPERTY_NAME, lastModified);
+            
+            session.save();
+            
+            try {
+                functionNode.checkin();
+            }
+            catch(UnsupportedRepositoryOperationException e) {
+                String message = "Error: Caught UnsupportedRepositoryOperationException when attempting to checkin node: " + functionNode.getName() + ". Are you sure your JCR repository supports versioning? ";
+                log.error(message + e);
+                throw new RulesRepositoryException(message, e);
+            }
+            
+            return new FunctionItem(this, functionNode);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Adds a Rule node in the repository using the content specified, associating it with
+     * the specified DSL node
+     * 
+     * @param ruleName the name of the rule
+     * @param lhsContent the lhs of the rule
+     * @param rhsContent the rhs of the rule
+     * @param dslItem the dslItem encapsulting the dsl node to associate this rule node with
+     * @paaram followDslHead whether or not to follow the head revision of the dsl node
+     * @return a RuleItem object encapsulating the node that gets added
+     * @throws RulesRepositoryException
+     */
+    public RuleItem addRule(String ruleName, String lhsContent, String rhsContent, DslItem dslItem, boolean followDslHead) throws RulesRepositoryException {
+        Node folderNode = this.getAreaNode(RULE_AREA);        
+        
+        try {        
+            //create the node - see section 6.7.22.6 of the spec
+            Node ruleNode = folderNode.addNode(ruleName, RuleItem.RULE_NODE_TYPE_NAME);
+                        
+            ruleNode.setProperty(RuleItem.TITLE_PROPERTY_NAME, ruleName);
+            ruleNode.setProperty(RuleItem.LHS_PROPERTY_NAME, lhsContent);
+            ruleNode.setProperty(RuleItem.RHS_PROPERTY_NAME, rhsContent);
+            ruleNode.setProperty(RuleItem.DESCRIPTION_PROPERTY_NAME, "");
+            ruleNode.setProperty(RuleItem.FORMAT_PROPERTY_NAME, RuleItem.RULE_FORMAT);
+            
+            //TODO: set this correctly
+            ruleNode.setProperty(RuleItem.CONTRIBUTOR_PROPERTY_NAME, "");
+            
+            if(followDslHead) {
+                ruleNode.setProperty(RuleItem.DSL_PROPERTY_NAME, dslItem.getNode());
+            }
+            else {
+                //tie the ruleNode to specifically the current version of the dslNode
+                ruleNode.setProperty(RuleItem.DSL_PROPERTY_NAME, dslItem.getNode().getBaseVersion());
+            }
+            
+            Calendar lastModified = Calendar.getInstance();
+            ruleNode.setProperty(RuleItem.LAST_MODIFIED_PROPERTY_NAME, lastModified);
+            
+            session.save();
+            
+            try {
+                ruleNode.checkin();
+            }
+            catch(UnsupportedRepositoryOperationException e) {
+                String message = "Error: Caught UnsupportedRepositoryOperationException when attempting to checkin rule: " + ruleNode.getName() + ". Are you sure your JCR repository supports versioning? ";
+                log.error(message + e);
+                throw new RulesRepositoryException(message, e);
+            }
+            
+            return new RuleItem(this, ruleNode);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Adds a Rule node in the repository using the content specified, with the specified
+     * effective and expiration dates, and referencing the specified dsl node
+     * 
+     * @param ruleName the name of the rule
+     * @param lhsContent the lhs of the rule
+     * @param rhsContent the rhs of the rule
+     * @param dslItem the DslItem object encapsuling the dsl node to assocaite this node with
+     * @param followDslHead whether or not to follow the head revision of the DSL node
+     * @param effectiveDate the date the rule becomes effective
+     * @param expiredDate the date teh rule expires
+     * @param description the description of the rule
+     * @return a RuleItem object encapsulating the node that gets added
+     * @throws RulesRepositoryException
+     */
+    public RuleItem addRule(String ruleName, String lhsContent, String rhsContent, DslItem dslItem, boolean followDslHead, Calendar effectiveDate, Calendar expiredDate, String description) throws RulesRepositoryException {
+        Node folderNode = this.getAreaNode(RULE_AREA);        
+        
+        try {        
+            //create the node - see section 6.7.22.6 of the spec
+            Node ruleNode = folderNode.addNode(ruleName, RuleItem.RULE_NODE_TYPE_NAME);
+                        
+            ruleNode.setProperty(RuleItem.TITLE_PROPERTY_NAME, ruleName);
+            
+            //TODO: set this property correctly once we've figured out logging in / JAAS
+            ruleNode.setProperty(RuleItem.CONTRIBUTOR_PROPERTY_NAME, "not yet implemented");
+                        
+            ruleNode.setProperty(RuleItem.DESCRIPTION_PROPERTY_NAME, description);
+            ruleNode.setProperty(RuleItem.FORMAT_PROPERTY_NAME, RuleItem.RULE_FORMAT);
+            ruleNode.setProperty(RuleItem.LHS_PROPERTY_NAME, lhsContent);
+            ruleNode.setProperty(RuleItem.RHS_PROPERTY_NAME, rhsContent);            
+            ruleNode.setProperty(RuleItem.DSL_PROPERTY_NAME, dslItem.getNode());
+            ruleNode.setProperty(RuleItem.DATE_EFFECTIVE_PROPERTY_NAME, effectiveDate);
+            ruleNode.setProperty(RuleItem.DATE_EXPIRED_PROPERTY_NAME, expiredDate);
+            
+            Calendar lastModified = Calendar.getInstance();
+            ruleNode.setProperty(RuleItem.LAST_MODIFIED_PROPERTY_NAME, lastModified);
+            
+            session.save();
+            
+            try {
+                ruleNode.checkin();
+            }
+            catch(UnsupportedRepositoryOperationException e) {
+                String message = "Error: Caught UnsupportedRepositoryOperationException when attempting to checkin rule: " + ruleNode.getName() + ". Are you sure your JCR repository supports versioning? ";
+                log.error(message + e);
+                throw new RulesRepositoryException(message, e);
+            }
+            
+            return new RuleItem(this, ruleNode);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Adds a Rule node in the repository using the content specified
+     * 
+     * @param ruleName the name of the rule
+     * @param lhsContent the lhs of the rule
+     * @param rhsContent the rhs of the rule
+     * @return a RuleItem object encapsulating the node that gets added
+     * @throws RulesRepositoryException
+     */
+    public RuleItem addRule(String ruleName, String lhsContent, String rhsContent) throws RulesRepositoryException {
+        Node folderNode = this.getAreaNode(RULE_AREA);        
+        
+        try {        
+            //create the node - see section 6.7.22.6 of the spec
+            Node ruleNode = folderNode.addNode(ruleName, RuleItem.RULE_NODE_TYPE_NAME);
+                        
+            ruleNode.setProperty(RuleItem.TITLE_PROPERTY_NAME, ruleName);
+            
+            //TODO: set this property correctly once we've figured out logging in / JAAS
+            ruleNode.setProperty(RuleItem.CONTRIBUTOR_PROPERTY_NAME, "not yet implemented");
+                        
+            ruleNode.setProperty(RuleItem.DESCRIPTION_PROPERTY_NAME, "");
+            ruleNode.setProperty(RuleItem.FORMAT_PROPERTY_NAME, RuleItem.RULE_FORMAT);
+            ruleNode.setProperty(RuleItem.LHS_PROPERTY_NAME, lhsContent);
+            ruleNode.setProperty(RuleItem.RHS_PROPERTY_NAME, rhsContent);                        
+            ruleNode.setProperty( VersionableItem.CHECKIN_COMMENT, "Initial" );
+            
+            
+            Calendar lastModified = Calendar.getInstance();
+            ruleNode.setProperty(RuleItem.LAST_MODIFIED_PROPERTY_NAME, lastModified);
+            
+            session.save();
+            
+            try {
+                ruleNode.checkin();
+            }
+            catch(UnsupportedRepositoryOperationException e) {
+                String message = "Error: Caught UnsupportedRepositoryOperationException when attempting to checkin rule: " + ruleNode.getName() + ". Are you sure your JCR repository supports versioning? ";
+                log.error(message + e);
+                throw new RulesRepositoryException(message, e);
+            }
+            
+            return new RuleItem(this, ruleNode);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * Adds a Rule node in the repository using the content specified, with the specified
+     * effective and expiration dates
+     * 
+     * @param ruleName the name of the rule
+     * @param lhsContent the lhs of the rule
+     * @param rhsContent the rhs of the rule
+     * @param effectiveDate the date the rule becomes effective
+     * @param expiredDate the date teh rule expires
+     * @return a RuleItem object encapsulating the node that gets added
+     * @throws RulesRepositoryException
+     */
+    public RuleItem addRule(String ruleName, String lhsContent, String rhsContent, Calendar effectiveDate, Calendar expiredDate) throws RulesRepositoryException {
+        Node folderNode = this.getAreaNode(RULE_AREA);        
+        
+        try {        
+            //create the node - see section 6.7.22.6 of the spec
+            Node ruleNode = folderNode.addNode(ruleName, RuleItem.RULE_NODE_TYPE_NAME);
+                        
+            ruleNode.setProperty(RuleItem.TITLE_PROPERTY_NAME, ruleName);
+
+            //TODO: set this property correctly once we've figured out logging in / JAAS
+            ruleNode.setProperty(RuleItem.CONTRIBUTOR_PROPERTY_NAME, "not yet implemented");
+                        
+            ruleNode.setProperty(RuleItem.DESCRIPTION_PROPERTY_NAME, "");
+            ruleNode.setProperty(RuleItem.FORMAT_PROPERTY_NAME, RuleItem.RULE_FORMAT);
+            
+            ruleNode.setProperty(RuleItem.LHS_PROPERTY_NAME, lhsContent);
+            ruleNode.setProperty(RuleItem.RHS_PROPERTY_NAME, rhsContent);            
+            ruleNode.setProperty(RuleItem.DATE_EFFECTIVE_PROPERTY_NAME, effectiveDate);
+            ruleNode.setProperty(RuleItem.DATE_EXPIRED_PROPERTY_NAME, expiredDate);
+            
+            Calendar lastModified = Calendar.getInstance();
+            ruleNode.setProperty(RuleItem.LAST_MODIFIED_PROPERTY_NAME, lastModified);
+            
+            session.save();
+            ruleNode.checkin();
+
+            
+            return new RuleItem(this, ruleNode);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }    
+    
+    /**
+     * Adds a rule package node in the repository. This node has a property called 
+     * drools:rule_reference that is a multi-value reference property.  It will hold an array of 
+     * references to rule nodes that are subsequently added.
+     *   
+     * @param name what to name the node added
+     * @return a RulePackageItem, encapsulating the created node
+     * @throws RulesRepositoryException
+     */
+    public RulePackageItem createRulePackage(String name) throws RulesRepositoryException {
+        Node folderNode = this.getAreaNode(RULE_PACKAGE_AREA);
+                 
+        try {
+            //create the node - see section 6.7.22.6 of the spec
+            Node rulePackageNode = folderNode.addNode(name, RulePackageItem.RULE_PACKAGE_TYPE_NAME);
+            
+            rulePackageNode.setProperty(RulePackageItem.TITLE_PROPERTY_NAME, name);
+            
+            //TODO: set this property correctly once we've figured out logging in / JAAS
+            rulePackageNode.setProperty(RulePackageItem.CONTRIBUTOR_PROPERTY_NAME, "not yet implemented");
+                        
+            rulePackageNode.setProperty(RulePackageItem.DESCRIPTION_PROPERTY_NAME, "");
+            rulePackageNode.setProperty(RulePackageItem.FORMAT_PROPERTY_NAME, RulePackageItem.RULE_PACKAGE_FORMAT);
+            
+            Calendar lastModified = Calendar.getInstance();
+            rulePackageNode.setProperty(RulePackageItem.LAST_MODIFIED_PROPERTY_NAME, lastModified);
+            
+            this.session.save();
+            rulePackageNode.checkin();
+            return new RulePackageItem(this, rulePackageNode);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }                                       
+
+    /**
+     * Adds a rule package node in the repository. This node has a property called 
+     * drools:rule_reference that is a multi-value reference property.  It will hold an array of 
+     * references to rule nodes that are subsequently added.
+     *   
+     * @param name what to name the node added
+     * @param description what description to use for the node
+     * @return a RulePackageItem, encapsulating the created node
+     * @throws RulesRepositoryException
+     */
+    public RulePackageItem createRulePackage(String name, String description) throws RulesRepositoryException {
+        Node folderNode = this.getAreaNode(RULE_PACKAGE_AREA);
+                 
+        try {
+            //create the node - see section 6.7.22.6 of the spec
+            Node rulePackageNode = folderNode.addNode(name, RulePackageItem.RULE_PACKAGE_TYPE_NAME);
+            
+            rulePackageNode.setProperty(RulePackageItem.TITLE_PROPERTY_NAME, name);
+            
+            //TODO: set this property correctly once we've figured out logging in / JAAS
+            rulePackageNode.setProperty(RuleItem.CONTRIBUTOR_PROPERTY_NAME, "not yet implemented");
+                        
+            rulePackageNode.setProperty(RuleItem.DESCRIPTION_PROPERTY_NAME, description);
+            rulePackageNode.setProperty(RuleItem.FORMAT_PROPERTY_NAME, RuleItem.RULE_PACKAGE_FORMAT);
+            
+            Calendar lastModified = Calendar.getInstance();
+            rulePackageNode.setProperty(RulePackageItem.LAST_MODIFIED_PROPERTY_NAME, lastModified);
+            
+            this.session.save();
+            rulePackageNode.checkin();
+            return new RulePackageItem(this, rulePackageNode);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception", e);
+            throw new RulesRepositoryException(e);
+        }
+    }                                       
+    
+    /**
+     * Gets a StateItem for the specified state name.  If a node for the specified state does not
+     * yet exist, one is first created.
+     * 
+     * @param name the name of the state to get
+     * @return a StateItem object encapsulating the retreived node
+     * @throws RulesRepositoryException
+     */
+    public StateItem getState(String name) throws RulesRepositoryException {
+        try {
+            Node folderNode = this.getAreaNode(STATE_AREA);
+            Node stateNode = this.addNodeIfNew(folderNode, name, StateItem.STATE_NODE_TYPE_NAME);
+            return new StateItem(this, stateNode);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception: " + e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+        
+    /**
+     * Gets a TagItem object that encapsulates the node for the specified tag name.  If the tag does
+     * not already exist in the repository when this is called, it is first added to the repository
+     * and then returned.
+     * 
+     * @param tagName the name of the tag to get. If the tag to get is within a heirarchy of
+     *                tag nodes, specify the full path to the tag node of interest (e.g. if
+     *                you want to get back 'child-tag', use "parent-tag/child-tag")
+     * @return a TagItem object encapsulating the node for the tag in the repository
+     * @throws RulesRepositoryException 
+     */
+    public CategoryItem getOrCreateCategory(String tagName) throws RulesRepositoryException {
+        log.debug("getting tag with name: " + tagName);
+        
+        try {
+            Node folderNode = this.getAreaNode(TAG_AREA);
+            Node tagNode = null;
+            
+            StringTokenizer tok = new StringTokenizer(tagName, "/");
+            while(tok.hasMoreTokens()) {                                
+                String currentTagName = tok.nextToken();
+                
+                tagNode = this.addNodeIfNew(folderNode, currentTagName, CategoryItem.TAG_NODE_TYPE_NAME);
+                folderNode = tagNode;
+            }             
+                                    
+            return new CategoryItem(this, tagNode);
+        }
+        catch(Exception e) {
+            log.error("Caught Exception: " + e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+
+    /**
+     * This will retrieve a list of FunctionItem objects - that are allocated to the 
+     * provided category.
+     * Only the latest versions of each FunctionItem will be returned (you will have 
+     * to delve into the functions' deepest darkest history yourself... mahahahaha).
+     */
+    public List findFunctionsByTag(String categoryTag) throws RulesRepositoryException {        
+        CategoryItem item = this.getOrCreateCategory( categoryTag );
+        List results = new ArrayList();
+        try {
+            PropertyIterator it = item.getNode().getReferences();
+            while(it.hasNext()) {
+                Property ruleLink = (Property) it.next();
+                Node parentNode = ruleLink.getParent();
+                if(parentNode.getPrimaryNodeType().getName().equals(FunctionItem.FUNCTION_NODE_TYPE_NAME) ||
+                   (parentNode.getPrimaryNodeType().getName().equals("nt:version") && 
+                    parentNode.getProperty(VersionableItem.FORMAT_PROPERTY_NAME).getString().equals(VersionableItem.FUNCTION_FORMAT))) {
+                    results.add(new FunctionItem(this, parentNode));
+                }
+            }
+            return results;
+        } catch (RepositoryException e) {            
+            throw new RulesRepositoryException(e);
+        }        
+    }
+    
+    /**
+     * This will retrieve a list of RuleItem objects - that are allocated to the 
+     * provided category.
+     * Only the latest versions of each RuleItem will be returned (you will have 
+     * to delve into the rules deepest darkest history yourself... mahahahaha).
+     */
+    public List findRulesByTag(String categoryTag) throws RulesRepositoryException {
+        
+        CategoryItem item = this.getOrCreateCategory( categoryTag );
+        List results = new ArrayList();
+        try {
+            PropertyIterator it = item.getNode().getReferences();
+            while(it.hasNext()) {
+                Property ruleLink = (Property) it.next();
+                Node parentNode = ruleLink.getParent();
+                if(parentNode.getPrimaryNodeType().getName().equals(RuleItem.RULE_NODE_TYPE_NAME) ||
+                   (parentNode.getPrimaryNodeType().getName().equals("nt:version") && 
+                    parentNode.getProperty(VersionableItem.FORMAT_PROPERTY_NAME).getString().equals(VersionableItem.RULE_FORMAT))) {
+                    results.add(new RuleItem(this, parentNode));
+                }
+            }
+            return results;
+        } catch ( RepositoryException e ) {            
+            throw new RulesRepositoryException(e);
+        }        
+    }
+    
+    /**
+     * @return an Iterator which will provide RulePackageItem's.
+     * This will show ALL the packages, only returning latest versions, by default.
+     */
+    public Iterator listPackages()  {
+        Node folderNode = this.getAreaNode(RULE_PACKAGE_AREA);
+        try {
+            return new RulePackageIterator(this, folderNode.getNodes());
+        } catch ( RepositoryException e ) {
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /** 
+     * This will provide a list of top level category strings. 
+     * Use getCategory to get a specific category to drill down into it.
+     */
+    public List listCategoryNames() throws RulesRepositoryException {
+        try {
+            
+            Node folderNode = this.getAreaNode(TAG_AREA);
+            NodeIterator it = folderNode.getNodes();            
+            
+            List nodeNames = new ArrayList();
+            while(it.hasNext()) {
+                Node catNode = (Node) it.next();
+                nodeNames.add( catNode.getName() );
+            }
+            
+            return nodeNames;
+        } catch ( RepositoryException e ) {
+            throw new RulesRepositoryException(e);
+        }
+    }
+    
+    /**
+     * @return The JCR session that this repository is using.
+     */
+    public Session getSession() {
+        return this.session;
+    }
+}
\ No newline at end of file


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulesRepository.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulesRepositoryException.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulesRepositoryException.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulesRepositoryException.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,51 @@
+package org.drools.repository;
+
+/**
+ * The main exception thrown by classes in this package. May contain an error message and/or another
+ * nested exception.
+ * 
+ * @author btruitt
+ */
+public class RulesRepositoryException extends RuntimeException {
+
+    /**
+     * version id for serialization purposes
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Default constructor. constructs a RulesRepositoryException object with null as its detail 
+     * message
+     */
+    public RulesRepositoryException() {
+        //nothing extra
+    }
+
+    /**
+     * Constructs a new instance of this class with the specified detail message.
+     * 
+     * @param message the message to set for the exception
+     */
+    public RulesRepositoryException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new instance of this class with the specified root cause.
+     * 
+     * @param rootCause root failure cause
+     */
+    public RulesRepositoryException(Throwable rootCause) {
+        super(rootCause);
+    }
+    
+    /**
+     * Constructs a new instance of this class with the specified detail message and root cause.
+     * 
+     * @param message the message to set for the exception
+     * @param rootCause root failure cause
+     */
+    public RulesRepositoryException(String message, Throwable rootCause) {
+        super(message, rootCause);
+    }
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/RulesRepositoryException.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: 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-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/StateItem.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,43 @@
+package org.drools.repository;
+
+import javax.jcr.Node;
+
+import org.apache.log4j.Logger;
+
+/**
+ * The StateItem class abstracts away details of the underlying JCR repository.
+ * 
+ * @author btruitt
+ */
+public class StateItem extends Item {
+    private Logger log = Logger.getLogger(StateItem.class);
+
+    /**
+     * The name of the state node type
+     */
+    public static final String STATE_NODE_TYPE_NAME = "drools:stateNodeType";
+    
+    /**
+     * Constructs an object of type StateItem corresponding the specified node
+     * 
+     * @param rulesRepository the rulesRepository that instantiated this object
+     * @param node the node to which this object corresponds
+     * @throws RulesRepositoryException 
+     */
+    public StateItem(RulesRepository rulesRepository, Node node) throws RulesRepositoryException {
+        super(rulesRepository, node);
+        
+        try {
+            //make sure this node is a state node       
+            if(!(this.node.getPrimaryNodeType().getName().equals(STATE_NODE_TYPE_NAME))) {
+                String message = this.node.getName() + " is not a node of type " + STATE_NODE_TYPE_NAME + ". It is a node of type: " + this.node.getPrimaryNodeType().getName();
+                log.error(message);
+                throw new RulesRepositoryException(message);
+            }    
+        }
+        catch(Exception e) {
+            log.error("Caught exception: " + e);
+            throw new RulesRepositoryException(e);
+        }
+    }
+}
\ No newline at end of file


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/StateItem.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/VersionableItem.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/VersionableItem.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/VersionableItem.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,439 @@
+package org.drools.repository;
+
+import java.util.Calendar;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
+
+import org.drools.repository.Item;
+
+public abstract class VersionableItem extends Item {
+
+    /**
+     * The name of the title property on the node type
+     */
+    public static final String TITLE_PROPERTY_NAME         = "drools:title";
+
+    /**
+     * The name of the contributor property on the node type
+     */
+    public static final String CONTRIBUTOR_PROPERTY_NAME   = "drools:contributor";
+
+    /**
+     * The name of the description property on the rule node type
+     */
+    public static final String DESCRIPTION_PROPERTY_NAME   = "drools:description";
+
+    /**
+     * The name of the last modified property on the rule node type
+     */
+    public static final String LAST_MODIFIED_PROPERTY_NAME = "drools:lastModified";
+
+    /**
+     * The name of the last modified property on the rule node type
+     */
+    public static final String FORMAT_PROPERTY_NAME        = "drools:format";
+
+    
+    /** The name of the checkin/change comment for change tracking */
+    public static final String CHECKIN_COMMENT              = "drools:checkinComment";
+    
+    /**
+     * The possible formats for the format property of the node
+     */
+    public static final String RULE_FORMAT                 = "Rule";
+    public static final String DSL_FORMAT                  = "DSL";
+    public static final String RULE_PACKAGE_FORMAT         = "Rule Package";
+    public static final String FUNCTION_FORMAT             = "Function";
+
+    /** this is what is referred to when reading content from a versioned node */
+    private Node               contentNode                 = null;
+
+    /**
+     * Sets this object's node attribute to the specified node
+     * 
+     * @param rulesRepository the RulesRepository object that this object is being created from
+     * @param node the node in the repository that this item corresponds to
+     */
+    public VersionableItem(RulesRepository rulesRepository,
+                           Node node) {
+        super( rulesRepository,
+               node );
+    }
+
+    /**
+     * @return the predessor node of this node in the version history, or null if no predecessor version exists
+     * @throws RulesRepositoryException
+     */
+    protected Node getPrecedingVersionNode() throws RulesRepositoryException {
+        try {
+            Node versionNode;
+            if ( this.node.getPrimaryNodeType().getName().equals( "nt:version" ) ) {
+                versionNode = this.node;
+            } else {
+                versionNode = this.node.getBaseVersion();
+            }
+
+            Property predecessorsProperty = versionNode.getProperty( "jcr:predecessors" );
+            Value[] predecessorValues = predecessorsProperty.getValues();
+
+            if ( predecessorValues.length > 0 ) {
+                Node predecessorNode = this.node.getSession().getNodeByUUID( predecessorValues[0].getString() );
+
+                //we don't want to return the root node - it isn't a true predecessor
+                if ( predecessorNode.getName().equals( "jcr:rootVersion" ) ) {
+                    return null;
+                }
+
+                return predecessorNode;
+            }
+        } catch ( PathNotFoundException e ) {
+            //do nothing - this will happen if no predecessors exits
+        } catch ( Exception e ) {
+            log.error( "Caught exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
+        return null;
+    }
+
+    /**
+     * @return the successor node of this node in the version history
+     * @throws RulesRepositoryException
+     */
+    protected Node getSucceedingVersionNode() throws RulesRepositoryException {
+        try {
+            Property successorsProperty = this.node.getProperty( "jcr:successors" );
+            Value[] successorValues = successorsProperty.getValues();
+
+            if ( successorValues.length > 0 ) {
+                Node successorNode = this.node.getSession().getNodeByUUID( successorValues[0].getString() );
+                return successorNode;
+            }
+        } catch ( PathNotFoundException e ) {
+            //do nothing - this will happen if no successors exist
+        } catch ( Exception e ) {
+            log.error( "Caught exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
+        return null;
+    }
+
+    /**
+     * @return an Iterator over VersionableItem objects encapsulating each successor node of this 
+     *         Item's node
+     * @throws RulesRepositoryException
+     */
+    public ItemVersionIterator getSuccessorVersionsIterator() throws RulesRepositoryException {
+        return new ItemVersionIterator( this,
+                                        ItemVersionIterator.ITERATION_TYPE_SUCCESSOR );
+    }
+
+    /**
+     * @return an Iterator over VersionableItem objects encapsulating each predecessor node of this 
+     *         Item's node
+     * @throws RulesRepositoryException
+     */
+    public ItemVersionIterator getPredecessorVersionsIterator() throws RulesRepositoryException {
+        return new ItemVersionIterator( this,
+                                        ItemVersionIterator.ITERATION_TYPE_PREDECESSOR );
+    }
+
+    /**
+     * Clients of this method can cast the resulting object to the type of object they are 
+     * calling the method on (e.g. 
+     *         <pre>
+     *           RuleItem item;
+     *           ...
+     *           RuleItem predcessor = (RuleItem) item.getPrecedingVersion();
+     *         </pre>
+     * @return a VersionableItem object encapsulating the predessor node of this node in the 
+     *         version history, or null if no predecessor version exists
+     * @throws RulesRepositoryException
+     */
+    public abstract VersionableItem getPrecedingVersion() throws RulesRepositoryException;
+
+    /**
+     * Clients of this method can cast the resulting object to the type of object they are 
+     * calling the method on (e.g. 
+     *         <pre>
+     *           RuleItem item;
+     *           ...
+     *           RuleItem successor = (RuleItem) item.getSucceedingVersion();
+     *         </pre>
+     *         
+     * @return a VersionableItem object encapsulating the successor node of this node in the 
+     *         version history. 
+     * @throws RulesRepositoryException
+     */
+    public abstract VersionableItem getSucceedingVersion() throws RulesRepositoryException;
+
+    /** 
+     * Gets the Title of the versionable node.  See the Dublin Core documentation for more
+     * explanation: http://dublincore.org/documents/dces/
+     * 
+     * @return the title of the node this object encapsulates
+     * @throws RulesRepositoryException
+     */
+    public String getTitle() throws RulesRepositoryException {
+        try {
+            Node theNode = getVersionContentNode();
+
+            Property data = theNode.getProperty( TITLE_PROPERTY_NAME );
+            return data.getValue().getString();
+        } catch ( Exception e ) {
+            log.error( "Caught Exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
+    }
+
+    /** 
+     * Creates a new version of this object's node, updating the title content 
+     * for the node.
+     * <br>
+     * See the Dublin Core documentation for more
+     * explanation: http://dublincore.org/documents/dces/
+     * 
+     * @param title the new title for the node
+     * @throws RulesRepositoryException
+     */
+    public void updateTitle(String title) throws RulesRepositoryException {
+        try {
+            checkIsUpdateable();
+
+            node.checkout();
+            node.setProperty( TITLE_PROPERTY_NAME,
+                                 title );
+            Calendar lastModified = Calendar.getInstance();
+            this.node.setProperty( LAST_MODIFIED_PROPERTY_NAME,
+                                   lastModified );
+
+        } catch ( Exception e ) {
+            log.error( "Caught Exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
+    }
+
+    /** 
+     * Gets the Contributor of the versionable node.  See the Dublin Core documentation for more
+     * explanation: http://dublincore.org/documents/dces/
+     * 
+     * @return the contributor of the node this object encapsulates
+     * @throws RulesRepositoryException
+     */
+    public String getContributor() {
+        try {
+            Property data = getVersionContentNode().getProperty( CONTRIBUTOR_PROPERTY_NAME );
+            return data.getValue().getString();
+        } catch ( Exception e ) {
+            log.error( "Caught Exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
+    }
+
+    /**
+     * See the Dublin Core documentation for more
+     * explanation: http://dublincore.org/documents/dces/
+     * 
+     * @return the description of this object's node.
+     * @throws RulesRepositoryException
+     */
+    public String getDescription() throws RulesRepositoryException {
+        try {
+            
+            Property data = getVersionContentNode().getProperty( DESCRIPTION_PROPERTY_NAME );
+            return data.getValue().getString();
+        } catch ( Exception e ) {
+            log.error( "Caught Exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
+    }
+
+    /**
+     * This will return the checkin comment for the latest revision.
+     */
+    public String getCheckinComment() throws RulesRepositoryException {
+        try {            
+            Property data = getVersionContentNode().getProperty( CHECKIN_COMMENT );
+            return data.getValue().getString();
+        } catch ( Exception e ) {
+            log.error( "Caught Exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
+    }    
+    
+    /**
+     * @return the date the function node (this version) was last modified
+     * @throws RulesRepositoryException
+     */
+    public Calendar getLastModified() throws RulesRepositoryException {
+        try {
+
+            Property lastModifiedProperty = getVersionContentNode().getProperty( LAST_MODIFIED_PROPERTY_NAME );
+            return lastModifiedProperty.getDate();
+        } catch ( Exception e ) {
+            log.error( "Caught Exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
+    }
+
+    /**
+     * Creates a new version of this object's node, updating the description content 
+     * for the node.
+     * <br>
+     * See the Dublin Core documentation for more
+     * explanation: http://dublincore.org/documents/dces/ 
+     * 
+     * @param newDescriptionContent the new description content for the rule
+     * @throws RulesRepositoryException
+     */
+    public void updateDescription(String newDescriptionContent) throws RulesRepositoryException {
+        try {
+            this.node.checkout();
+        } catch ( UnsupportedRepositoryOperationException e ) {
+            String message = "";
+            try {
+                message = "Error: Caught UnsupportedRepositoryOperationException when attempting to checkout node: " + this.node.getName() + ". Are you sure your JCR repository supports versioning? ";
+                log.error( message,
+                           e );
+            } catch ( RepositoryException e1 ) {
+                log.error( "Caught Exception",
+                           e );
+                throw new RulesRepositoryException( e1 );
+            }
+            throw new RulesRepositoryException( message,
+                                                e );
+        } catch ( Exception e ) {
+            log.error( "Caught Exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
+
+        try {
+            this.node.setProperty( DESCRIPTION_PROPERTY_NAME,
+                                   newDescriptionContent );
+
+            Calendar lastModified = Calendar.getInstance();
+            this.node.setProperty( LAST_MODIFIED_PROPERTY_NAME,
+                                   lastModified );
+
+            this.node.getSession().save();
+
+            this.node.checkin();
+        } catch ( Exception e ) {
+            log.error( "Caught Exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
+    }
+
+    /**
+     * See the Dublin Core documentation for more
+     * explanation: http://dublincore.org/documents/dces/
+     * 
+     * @return the format of this object's node
+     * @throws RulesRepositoryException
+     */
+    public String getFormat() throws RulesRepositoryException {
+        try {
+            Node theNode;
+            if ( this.node.getPrimaryNodeType().getName().equals( "nt:version" ) ) {
+                theNode = this.node.getNode( "jcr:frozenNode" );
+            } else {
+                theNode = this.node;
+            }
+
+            Property data = theNode.getProperty( FORMAT_PROPERTY_NAME );
+            return data.getValue().getString();
+        } catch ( Exception e ) {
+            log.error( "Caught Exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
+    }
+
+    /**
+     * When retrieving content, if we are dealing with a version in the history, 
+     * we need to get the actual content node to retrieve values.
+     * 
+     */
+    public Node getVersionContentNode() throws RepositoryException,
+                                       PathNotFoundException {
+        if ( this.contentNode == null ) {
+            
+            if ( this.node.getPrimaryNodeType().getName().equals( "nt:version" ) ) {
+                contentNode = this.node.getNode( "jcr:frozenNode" );
+            } else {
+                contentNode = this.node;
+            }
+            
+        }
+
+        return contentNode;
+    }
+
+    /**
+     * This will check out the node prior to editing.
+     */
+    public void checkout() {
+
+        try {
+            this.node.checkout();
+        } catch ( UnsupportedRepositoryOperationException e ) {
+            String message = "";
+            try {
+                message = "Error: Caught UnsupportedRepositoryOperationException when attempting to checkout rule: " + this.node.getName() + ". Are you sure your JCR repository supports versioning? ";
+                log.error( message,
+                           e );
+            } catch ( RepositoryException e1 ) {
+                log.error( "Caught Exception",
+                           e );
+                throw new RulesRepositoryException( e1 );
+            }
+            throw new RulesRepositoryException( message,
+                                                e );
+        } catch ( Exception e ) {
+            log.error( "Caught Exception",
+                       e );
+            throw new RulesRepositoryException( e );
+        }
+    }
+    
+    /** 
+     * This will save the content (if it hasn't been already) and 
+     * then check it in to create a new version.
+     */
+    public void checkin(String comment)  {
+        try {
+        this.node.setProperty( VersionableItem.CHECKIN_COMMENT, comment);
+        this.node.getSession().save();        
+        this.node.checkin();
+        } catch (Exception e) {
+            throw new RulesRepositoryException("Unable to checkin.", e);
+        }
+    }
+
+    /**
+     * This will check to see if the node is the "head" and
+     * so can be updated (you can't update historical nodes ).
+     * @throws RepositoryException
+     */
+    protected void checkIsUpdateable() throws RepositoryException {
+        if(this.node.getPrimaryNodeType().getName().equals("nt:version")) {
+            String message = "Error. Tags can only be added to the head version of a rule node";
+            log.error(message);
+            throw new RulesRepositoryException(message);
+        }
+    }    
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/repository/VersionableItem.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/dsl_node_type.cnd
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/dsl_node_type.cnd	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/dsl_node_type.cnd	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,17 @@
+/*  The node type definition for the dsl node type.  
+    See http://jackrabbit.apache.org/doc/nodetype/cnd.html for an explanation
+*/
+
+// The namespace declaration
+<drools = 'http://www.jboss.org/drools-repository/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+
+// Node type name
+[drools:dslNodeType]
+
+// Supertypes
+> 'drools:versionableNodeType'
+
+// Properties
+- drools:dslContent (string)


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/dsl_node_type.cnd
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/function_node_type.cnd
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/function_node_type.cnd	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/function_node_type.cnd	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,31 @@
+/*  The node type definition for the function node type.  
+    See http://jackrabbit.apache.org/doc/nodetype/cnd.html for an explanation
+*/
+
+// The namespace declaration
+<drools = 'http://www.jboss.org/drools-repository/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+
+// Node type name
+[drools:functionNodeType]
+
+// Supertypes
+> 'drools:versionableNodeType'
+
+// Properties:
+- drools:content (string)
+  mandatory
+  
+- drools:functionLanguage (string)
+  = 'Java'
+  mandatory autocreated
+
+- drools:categoryReference (reference)
+  multiple 
+  copy
+  < 'drools:categoryNodeType'
+
+- drools:stateReference (reference)
+  copy
+  < 'drools:stateNodeType'
\ No newline at end of file


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/function_node_type.cnd
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/rule_node_type.cnd
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/rule_node_type.cnd	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/rule_node_type.cnd	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,42 @@
+/*  The node type definition for the rule node type.  
+    See http://jackrabbit.apache.org/doc/nodetype/cnd.html for an explanation
+*/
+
+// The namespace declaration
+<drools = 'http://www.jboss.org/drools-repository/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+
+// Node type name
+[drools:ruleNodeType]
+
+// Supertypes
+> 'drools:versionableNodeType'
+
+// Properties:
+- drools:lhs (string)
+  mandatory
+
+- drools:rhs (string)
+  mandatory
+
+- drools:dateEffective (date)
+
+- drools:dateExpired (date)
+  
+- drools:ruleLanguage (string)
+  = 'DRL'
+  mandatory autocreated
+
+- drools:dslReference (reference)
+  copy 
+  < 'drools:dslNodeType','nt:version'
+
+- drools:categoryReference (reference)
+  multiple 
+  copy
+  < 'drools:categoryNodeType'
+
+- drools:stateReference (reference)
+  copy
+  < 'drools:stateNodeType'
\ No newline at end of file


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/rule_node_type.cnd
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/rulepackage_node_type.cnd
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/rulepackage_node_type.cnd	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/rulepackage_node_type.cnd	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,24 @@
+/*  The node type definition for the ruleset node type.  
+    See http://jackrabbit.apache.org/doc/nodetype/cnd.html for an explanation
+*/
+
+// The namespace declaration
+<drools = 'http://www.jboss.org/drools-repository/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+
+// Node type name
+[drools:rulepackageNodeType]
+
+// Supertypes
+> 'drools:versionableNodeType'
+  
+- drools:ruleReference (reference)
+  multiple
+  copy
+  < 'drools:ruleNodeType','nt:version'
+  
+- drools:functionReference (reference)
+  multiple
+  copy
+  < 'drools:functionNodeType','nt:version'
\ No newline at end of file


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/rulepackage_node_type.cnd
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/state_node_type.cnd
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/state_node_type.cnd	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/state_node_type.cnd	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,14 @@
+/*  The node type definition for the tag node type.  
+    See http://jackrabbit.apache.org/doc/nodetype/cnd.html for an explanation
+*/
+
+// The namespace declaration
+<drools = 'http://www.jboss.org/drools-repository/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+
+// Node type name
+[drools:stateNodeType]
+
+// Supertypes
+> 'nt:hierarchyNode','mix:referenceable'


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/state_node_type.cnd
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/tag_node_type.cnd
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/tag_node_type.cnd	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/tag_node_type.cnd	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,21 @@
+/*  The node type definition for the tag node type.  
+    See http://jackrabbit.apache.org/doc/nodetype/cnd.html for an explanation
+*/
+
+// The namespace declaration
+<drools = 'http://www.jboss.org/drools-repository/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+
+// Node type name
+[drools:categoryNodeType]
+
+// Supertypes
+> 'nt:hierarchyNode','mix:referenceable'
+
+// Nodes of this node type have a child node called anything which must be of
+// at least the node type drools:categoryNodeType
++ * (drools:categoryNodeType)
+
+// and the default primary node type of the child node is...
+= drools:categoryNodeType


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/tag_node_type.cnd
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/versionable_node_type.cnd
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/versionable_node_type.cnd	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/versionable_node_type.cnd	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,34 @@
+/*  The node type definition for the rule node type.  
+    See http://jackrabbit.apache.org/doc/nodetype/cnd.html for an explanation
+    
+    See the Dublin Core documentation for more explanation: http://dublincore.org/documents/dces/
+*/
+
+// The namespace declaration
+<drools = 'http://www.jboss.org/drools-repository/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+
+// Node type name
+[drools:versionableNodeType]
+
+// Supertypes
+> 'nt:hierarchyNode','mix:versionable'
+
+// Properties:
+- drools:title (string)
+  mandatory
+  
+- drools:contributor (string)
+  mandatory
+
+- drools:lastModified (date)
+  mandatory
+  
+- drools:description (string)
+  mandatory
+
+  - drools:format (string)
+  mandatory 
+  
+  - drools:checkinComment (string)
\ No newline at end of file


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/resources/node_type_definitions/versionable_node_type.cnd
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/CategoryItemTestCase.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/CategoryItemTestCase.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/CategoryItemTestCase.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,128 @@
+package org.drools.repository;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.drools.repository.RulesRepository;
+import org.drools.repository.CategoryItem;
+
+import junit.framework.TestCase;
+
+public class CategoryItemTestCase extends TestCase {
+
+    
+    
+    public void testTagItem() {
+            CategoryItem tagItem1 = getRepo().getOrCreateCategory("TestTag");
+            assertNotNull(tagItem1);
+            assertEquals("TestTag", tagItem1.getName());                        
+            
+            CategoryItem tagItem2 = getRepo().getOrCreateCategory("TestTag");
+            assertNotNull(tagItem2);
+            assertEquals("TestTag", tagItem2.getName());
+            assertEquals(tagItem1, tagItem2);
+            
+            List originalCats = getRepo().listCategoryNames();
+            
+            
+            getRepo().getOrCreateCategory( "FootestTagItem" );
+            
+            List cats = getRepo().listCategoryNames();
+            assertEquals(originalCats.size() + 1, cats.size());
+            
+            
+            boolean found = false;
+            for ( Iterator iter = cats.iterator(); iter.hasNext(); ) {
+                String element = (String) iter.next();
+                if (element.equals( "FootestTagItem" )) {
+                    found = true; break;
+                }
+            }
+            
+            assertTrue(found);
+    
+    }    
+    
+    public void testGetChildTags() {
+        try {            
+            CategoryItem tagItem1 = getRepo().getOrCreateCategory("TestTag");
+            assertNotNull(tagItem1);
+            assertEquals("TestTag", tagItem1.getName());                        
+            
+            List childTags = tagItem1.getChildTags();
+            assertNotNull(childTags);
+            assertEquals(0, childTags.size());
+            
+            CategoryItem childTagItem1 = tagItem1.getChildTag("TestChildTag1");
+            assertNotNull(childTagItem1);
+            assertEquals("TestChildTag1", childTagItem1.getName());
+            
+            childTags = tagItem1.getChildTags();
+            assertNotNull(childTags);
+            assertEquals(1, childTags.size());
+            assertEquals("TestChildTag1", ((CategoryItem)childTags.get(0)).getName());
+            
+            CategoryItem childTagItem2 = tagItem1.getChildTag("TestChildTag2");
+            assertNotNull(childTagItem2);
+            assertEquals("TestChildTag2", childTagItem2.getName());
+            
+            childTags = tagItem1.getChildTags();
+            assertNotNull(childTags);
+            assertEquals(2, childTags.size());
+        }
+        catch(Exception e) {
+            fail("Unexpected Exception caught: " + e);
+        }
+    }
+    
+    public void testGetChildTag() {
+        try {            
+            CategoryItem tagItem1 = getRepo().getOrCreateCategory("testGetChildTag");
+            assertNotNull(tagItem1);
+            assertEquals("testGetChildTag", tagItem1.getName());                        
+            
+            //test that child is added if not already in existence
+            List childTags = tagItem1.getChildTags();
+            assertNotNull(childTags);
+            assertEquals(0, childTags.size());
+            
+            CategoryItem childTagItem1 = tagItem1.getChildTag("TestChildTag1");
+            assertNotNull(childTagItem1);
+            assertEquals("TestChildTag1", childTagItem1.getName());
+                        
+            //test that if already there, it is returned
+            CategoryItem childTagItem2 = tagItem1.getChildTag("TestChildTag1");
+            assertNotNull(childTagItem2);
+            assertEquals("TestChildTag1", childTagItem2.getName());
+            assertEquals(childTagItem1, childTagItem2);
+        }
+        catch(Exception e) {
+            fail("Unexpected Exception caught: " + e);
+        }
+    }
+    
+    public void testGetFullPath() {
+        try {            
+            CategoryItem tagItem1 = getRepo().getOrCreateCategory("TestTag");
+            assertNotNull(tagItem1);
+            assertEquals("TestTag", tagItem1.getFullPath());                        
+                                    
+            CategoryItem childTagItem1 = tagItem1.getChildTag("TestChildTag1");
+            assertNotNull(childTagItem1);
+            assertEquals("TestTag/TestChildTag1", childTagItem1.getFullPath());
+                        
+            CategoryItem childTagItem2 = childTagItem1.getChildTag("TestChildTag2");
+            assertNotNull(childTagItem2);
+            assertEquals("TestTag/TestChildTag1/TestChildTag2", childTagItem2.getFullPath());
+            
+            
+        }
+        catch(Exception e) {
+            fail("Unexpected Exception caught: " + e);
+        }
+    }
+
+    private RulesRepository getRepo() {
+        return RepositorySession.getRepository();
+    }
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/CategoryItemTestCase.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/DslItemTestCase.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/DslItemTestCase.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/DslItemTestCase.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,58 @@
+package org.drools.repository;
+
+
+import junit.framework.TestCase;
+
+import org.drools.repository.DslItem;
+import org.drools.repository.RuleItem;
+import org.drools.repository.RulesRepository;
+import org.drools.repository.RulesRepositoryException;
+
+public class DslItemTestCase extends TestCase {
+
+    private RulesRepository getRepo() {
+        return RepositorySession.getRepository();
+    }
+    
+    public void testDslItem() {
+        
+        try {
+            //This calls the constructor
+            String meth = StackUtil.getCurrentMethodName();
+            DslItem dslItem1 = getRepo().addDsl(meth, "blah");
+            
+            assertNotNull(dslItem1);
+            assertNotNull(dslItem1.getNode());         
+            assertEquals(meth, dslItem1.getName());
+        }
+        catch(Exception e) {
+            fail("Unexpected Exception caught: " + e);
+        }
+        
+        //try constructing a DslItem object with the wrong node type
+        try {
+            //Get a reference to a node of the incorrect type
+            RuleItem ruleItem1 = this.getRepo().addRule("test rule", "test lhs content", "test rhs content");
+            
+            //this should fail
+            DslItem dslItem2 = new DslItem(getRepo(), ruleItem1.getNode());
+            fail("Exception not thrown by constructor for node of type: " + ruleItem1.getNode().getPrimaryNodeType().getName());            
+        }
+        catch(RulesRepositoryException e) {
+            //this is what we expect
+        }
+        catch(Exception e) {
+            fail("Unexpected Exception caught: " + e);
+        }
+    }
+
+    public void testGetContent() {
+            DslItem dslItem1 = getRepo().addDsl(StackUtil.getCurrentMethodName(), "[then]Send escalation email=sendEscalationEmail( customer, ticket );");
+            
+            assertNotNull(dslItem1);
+            assertEquals("[then]Send escalation email=sendEscalationEmail( customer, ticket );", dslItem1.getContent());
+            assertEquals("DSL", dslItem1.getFormat());        
+    }
+       
+    
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/DslItemTestCase.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/FunctionItemTestCase.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/FunctionItemTestCase.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/FunctionItemTestCase.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,275 @@
+package org.drools.repository;
+
+import java.io.File;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.drools.repository.*;
+
+public class FunctionItemTestCase extends TestCase {
+
+    
+    
+
+    public void testFunctionItem() {
+        try {            
+            //calls constructor
+            FunctionItem functionItem1 = this.getRepo().addFunction("testFunctionItem", "test content");
+            
+            assertNotNull(functionItem1);
+            assertNotNull(functionItem1.getNode());
+            assertEquals("testFunctionItem", functionItem1.getName());            
+        }
+        catch(Exception e) {
+            fail("Caught unexpected exception: " + e);
+        }
+        
+        //try constructing with node of wrong type
+        try {
+            
+            DslItem dslItem = getRepo().addDsl("testFunctionItem", "content here");
+            FunctionItem functionItem = new FunctionItem(this.getRepo(), dslItem.getNode());
+            fail("Exception not thrown for node of type: " + dslItem.getNode().getPrimaryNodeType().getName());
+        }
+        catch(RulesRepositoryException e) {
+            //this is good
+        }
+        catch(Exception e) {
+            fail("Caught unexpected exception: " + e);
+        }
+    }
+
+    public void testGetContent() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testGetContent", "test content");
+            
+            assertNotNull(functionItem1);
+            assertNotNull(functionItem1.getNode());
+            assertEquals("test content", functionItem1.getContent());
+    }
+    
+    public void testUpdateContent() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testUpdateContent", "test content");
+                        
+            functionItem1.updateContent("new content");
+            
+            assertEquals("new content", functionItem1.getContent());
+    }
+        
+    public void testAddCategory() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testAddCategory", "test content");
+            
+            functionItem1.addTag("testAddCategoryTestTag");
+            List tags = functionItem1.getTags();
+            assertEquals(1, tags.size());
+            assertEquals("testAddCategoryTestTag", ((CategoryItem)tags.get(0)).getName());
+            
+            functionItem1.addTag("testAddCategoryTestTag2");
+            tags = functionItem1.getTags();
+            assertEquals(2, tags.size());   
+                        
+            //now test retrieve by tags
+            List result = this.getRepo().findFunctionsByTag("testAddCategoryTestTag");            
+            assertEquals(1, result.size());            
+            FunctionItem retItem = (FunctionItem) result.get(0);
+            assertEquals("testAddCategory", retItem.getName());            
+    }
+
+    public void testRemoveTag() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testRemoveTag", "test content");
+            
+            functionItem1.addTag("TestTag");                                    
+            functionItem1.removeTag("TestTag");
+            List tags = functionItem1.getTags();
+            assertEquals(0, tags.size());
+            
+            functionItem1.addTag("TestTag2");                                    
+            functionItem1.addTag("TestTag3");
+            functionItem1.removeTag("TestTag2");
+            tags = functionItem1.getTags();
+            assertEquals(1, tags.size());
+            assertEquals("TestTag3", ((CategoryItem)tags.get(0)).getName());            
+    }
+
+    public void testGetTags() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testGetTags", "test content");
+           
+            List tags = functionItem1.getTags();
+            assertNotNull(tags);
+            assertEquals(0, tags.size());
+            
+            functionItem1.addTag("TestTag");                                    
+            tags = functionItem1.getTags();
+            assertEquals(1, tags.size());
+            assertEquals("TestTag", ((CategoryItem)tags.get(0)).getName());
+    }
+
+    public void testSetStateString() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testSetStateString", "test content");
+           
+            functionItem1.setState("TestState1");
+            assertNotNull(functionItem1.getState());
+            assertEquals("TestState1", functionItem1.getState().getName());
+            
+            functionItem1.setState("TestState2");
+            assertNotNull(functionItem1.getState());
+            assertEquals("TestState2", functionItem1.getState().getName());            
+    }
+
+    public void testSetStateStateItem() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testSetStateStateItem", "test content");
+           
+            StateItem stateItem1 = getRepo().getState("TestState1");
+            functionItem1.setState(stateItem1);            
+            assertNotNull(functionItem1.getState());
+            assertEquals(functionItem1.getState().getName(), "TestState1");
+            
+            StateItem stateItem2 = getRepo().getState("TestState2");
+            functionItem1.setState(stateItem2);
+            assertNotNull(functionItem1.getState());
+            assertEquals("TestState2", functionItem1.getState().getName());            
+    }
+
+    public void testGetState() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testGetState", "test content");
+           
+            StateItem stateItem1 = functionItem1.getState();
+            assertNull(stateItem1);
+            
+            functionItem1.setState("TestState1");
+            assertNotNull(functionItem1.getState());
+            assertEquals("TestState1", functionItem1.getState().getName());                        
+    }
+
+    public void testToString() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testToString", "test content");           
+            assertNotNull(functionItem1.toString());                        
+    }
+    
+        
+    public void testFunctionRuleLanguage() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testFunctionRuleLanguage", "test content");
+           
+            //it should be initialized to 'Java'
+            assertEquals("Java", functionItem1.getFunctionLanguage());                        
+    }
+    
+    
+    public void testGetPrecedingVersion() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testGetPrecedingVersion", "test content");
+            
+            FunctionItem predecessorFunctionItem = (FunctionItem) functionItem1.getPrecedingVersion();
+            assertTrue(predecessorFunctionItem == null);            
+            
+            functionItem1.updateContent("new content");
+            
+            predecessorFunctionItem = (FunctionItem) functionItem1.getPrecedingVersion();
+            assertNotNull(predecessorFunctionItem);
+            assertEquals("test content", predecessorFunctionItem.getContent());
+            
+            functionItem1.updateContent("newer content");
+            
+            predecessorFunctionItem = (FunctionItem) functionItem1.getPrecedingVersion();
+            assertNotNull(predecessorFunctionItem);
+            assertEquals("new content", predecessorFunctionItem.getContent());
+            predecessorFunctionItem = (FunctionItem) predecessorFunctionItem.getPrecedingVersion();
+            assertNotNull(predecessorFunctionItem);
+            assertEquals("test content", predecessorFunctionItem.getContent());
+    }
+    
+    public void testGetSucceedingVersion() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testGetSucceedingVersion", "test content");
+            
+            FunctionItem succeedingFunctionItem = (FunctionItem) functionItem1.getSucceedingVersion();
+            assertTrue(succeedingFunctionItem == null);            
+            
+            functionItem1.updateContent("new content");
+            
+            FunctionItem predecessorFunctionItem = (FunctionItem) functionItem1.getPrecedingVersion();
+            assertEquals("test content", predecessorFunctionItem.getContent());
+            succeedingFunctionItem = (FunctionItem) predecessorFunctionItem.getSucceedingVersion();
+            assertNotNull(succeedingFunctionItem);
+            assertEquals(functionItem1.getContent(), succeedingFunctionItem.getContent());                       
+    } 
+    
+    public void testGetSuccessorVersionsIterator() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testGetSuccessorVersionsIterator", "test content");                        
+            
+            Iterator iterator = functionItem1.getSuccessorVersionsIterator();            
+            assertNotNull(iterator);
+            assertFalse(iterator.hasNext());
+            
+            functionItem1.updateContent("new content");
+            
+            iterator = functionItem1.getSuccessorVersionsIterator();            
+            assertNotNull(iterator);
+            assertFalse(iterator.hasNext());
+            
+            FunctionItem predecessorFunctionItem = (FunctionItem) functionItem1.getPrecedingVersion();
+            iterator = predecessorFunctionItem.getSuccessorVersionsIterator();
+            assertNotNull(iterator);
+            assertTrue(iterator.hasNext());
+            FunctionItem nextFunctionItem = (FunctionItem) iterator.next();
+            assertEquals("new content", nextFunctionItem.getContent());
+            assertFalse(iterator.hasNext());
+            
+            functionItem1.updateContent("newer content");
+                        
+            iterator = predecessorFunctionItem.getSuccessorVersionsIterator();
+            assertNotNull(iterator);
+            assertTrue(iterator.hasNext());
+            nextFunctionItem = (FunctionItem) iterator.next();
+            assertEquals("new content", nextFunctionItem.getContent());
+            assertTrue(iterator.hasNext());
+            nextFunctionItem = (FunctionItem)iterator.next();
+            assertEquals("newer content", nextFunctionItem.getContent());
+            assertFalse(iterator.hasNext());            
+    }
+    
+    public void testGetPredecessorVersionsIterator() {
+            FunctionItem functionItem1 = this.getRepo().addFunction("testGetPredecessorVersionsIterator", "test content");                        
+            
+            Iterator iterator = functionItem1.getPredecessorVersionsIterator();            
+            assertNotNull(iterator);
+            assertFalse(iterator.hasNext());
+            
+            functionItem1.updateContent("new content");
+            
+            iterator = functionItem1.getPredecessorVersionsIterator();            
+            assertNotNull(iterator);
+            assertTrue(iterator.hasNext());
+            FunctionItem nextFunctionItem = (FunctionItem) iterator.next();
+            assertFalse(iterator.hasNext());
+            assertEquals("test content", nextFunctionItem.getContent());
+            
+            functionItem1.updateContent("newer content");
+            
+            iterator = functionItem1.getPredecessorVersionsIterator();            
+            assertNotNull(iterator);
+            assertTrue(iterator.hasNext());
+            nextFunctionItem = (FunctionItem) iterator.next();
+            assertTrue(iterator.hasNext());            
+            assertEquals("new content", nextFunctionItem.getContent());
+            nextFunctionItem = (FunctionItem) iterator.next();
+            assertFalse(iterator.hasNext());
+            assertEquals("test content", nextFunctionItem.getContent());
+    }
+    
+    public void testGetTitle() {    
+            FunctionItem functionItem1 = this.getRepo().addFunction("testGetTitle", "test content");            
+            assertEquals("testGetTitle", functionItem1.getTitle());
+    }
+    
+    
+    public void testGetFormat() {        
+            FunctionItem functionItem1 = this.getRepo().addFunction("testGetFormat", "test content");
+            assertEquals("Function", functionItem1.getFormat());            
+    }
+
+    private RulesRepository getRepo() {
+
+        return RepositorySession.getRepository();
+    }        
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/FunctionItemTestCase.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RepositorySession.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RepositorySession.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RepositorySession.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,19 @@
+package org.drools.repository;
+
+import org.drools.repository.RulesRepository;
+
+public class RepositorySession {
+
+    private static ThreadLocal repo = new ThreadLocal();
+
+    public static RulesRepository getRepository() {
+        Object repoInstance = repo.get();
+        if ( repoInstance == null ) {
+            repoInstance = new RulesRepository( true );
+            repo.set( repoInstance );
+            
+        }
+        return (RulesRepository) repoInstance;        
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RepositorySession.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RuleItemTestCase.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RuleItemTestCase.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RuleItemTestCase.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,442 @@
+package org.drools.repository;
+
+import java.io.File;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+
+import junit.framework.TestCase;
+
+import org.drools.repository.*;
+
+public class RuleItemTestCase extends TestCase {
+
+
+    public RulesRepository getRepo() {
+        return RepositorySession.getRepository();
+    }
+    
+    public void testRuleItem() {
+            //calls constructor
+            RuleItem ruleItem1 = getRepo().addRule("testRuleItem", "test lhs content", "test rhs content");
+            
+            assertNotNull(ruleItem1);
+            assertNotNull(ruleItem1.getNode());
+            assertEquals("testRuleItem", ruleItem1.getName());
+        
+        //try constructing with node of wrong type
+        try {
+            
+            DslItem dslItem = getRepo().addDsl("testRuleItem", "content here");
+            RuleItem ruleItem = new RuleItem(getRepo(), dslItem.getNode());
+            fail("Exception not thrown for node of type: " + dslItem.getNode().getPrimaryNodeType().getName());
+        }
+        catch(RulesRepositoryException e) {
+            //this is good
+        }
+        catch(Exception e) {
+            fail("Caught unexpected exception: " + e);
+        }
+    }
+
+    public void testGetLhs() {
+            
+            RuleItem ruleItem1 = getRepo().addRule("testGetLhs", "test lhs content", "test rhs content");
+            
+            assertNotNull(ruleItem1);
+            assertNotNull(ruleItem1.getNode());
+            assertEquals("test lhs content", ruleItem1.getLhs());
+    }
+
+    public void testGetRhs() {
+            RuleItem ruleItem1 = getRepo().addRule("testGetRhs", "test lhs content", "test rhs content");
+            
+            assertNotNull(ruleItem1);
+            assertNotNull(ruleItem1.getNode());
+            assertEquals("test rhs content", ruleItem1.getRhs());
+
+    }
+    
+    public void testUpdateLhs() {
+            RuleItem ruleItem1 = getRepo().addRule("testUpdateLhs", "test lhs content", "test rhs content");
+                        
+            ruleItem1.updateLhs("new lhs content");
+            
+            assertEquals("new lhs content", ruleItem1.getLhs());
+            
+            ruleItem1.checkin( "yeah !" );
+            
+            assertEquals("yeah !", ruleItem1.getCheckinComment());
+            
+            RuleItem prev = (RuleItem) ruleItem1.getPredecessorVersionsIterator().next();
+            assertEquals("test lhs content", prev.getLhs());
+            assertFalse("yeah !".equals(prev.getCheckinComment()));
+            
+            
+            assertEquals(prev, ruleItem1.getPrecedingVersion());
+
+    }
+    
+    public void testUpdateRhs() {
+            RuleItem ruleItem1 = getRepo().addRule("testUpdateRhs", "test lhs content", "test rhs content");                        
+            ruleItem1.updateRhs("new rhs content");            
+            assertEquals("new rhs content", ruleItem1.getRhs());
+            ruleItem1.checkin( "la" );
+            RuleItem prev = (RuleItem) ruleItem1.getPrecedingVersion();
+            assertEquals("test rhs content", prev.getRhs());
+            
+    }
+
+    public void testAddTag() {
+            RuleItem ruleItem1 = getRepo().addRule("testAddTag", "test lhs content", "test rhs content");
+            
+            ruleItem1.addCategory("testAddTagTestTag");
+            List tags = ruleItem1.getCategories();
+            assertEquals(1, tags.size());
+            assertEquals("testAddTagTestTag", ((CategoryItem)tags.get(0)).getName());
+            
+            ruleItem1.addCategory("testAddTagTestTag2");
+            tags = ruleItem1.getCategories();
+            assertEquals(2, tags.size());   
+            
+            ruleItem1.checkin( "woot" );
+            
+            //now test retrieve by tags
+            List result = getRepo().findRulesByTag("testAddTagTestTag");            
+            assertEquals(1, result.size());            
+            RuleItem retItem = (RuleItem) result.get( 0 );
+            assertEquals("testAddTag", retItem.getName());
+            
+
+    }
+
+    public void testRemoveTag() {
+            RuleItem ruleItem1 = getRepo().addRule("testRemoveTag", "test lhs content", "test rhs content");
+            
+            ruleItem1.addCategory("TestTag");                                    
+            ruleItem1.removeCategory("TestTag");
+            List tags = ruleItem1.getCategories();
+            assertEquals(0, tags.size());
+            
+            ruleItem1.addCategory("TestTag2");                                    
+            ruleItem1.addCategory("TestTag3");
+            ruleItem1.removeCategory("TestTag2");
+            tags = ruleItem1.getCategories();
+            assertEquals(1, tags.size());
+            assertEquals("TestTag3", ((CategoryItem)tags.get(0)).getName());            
+
+    }
+
+    public void testGetTags() {
+            RuleItem ruleItem1 = getRepo().addRule("testGetTags", "test lhs content", "test rhs content");
+           
+            List tags = ruleItem1.getCategories();
+            assertNotNull(tags);
+            assertEquals(0, tags.size());
+            
+            ruleItem1.addCategory("testGetTagsTestTag");                                    
+            tags = ruleItem1.getCategories();
+            assertEquals(1, tags.size());
+            assertEquals("testGetTagsTestTag", ((CategoryItem)tags.get(0)).getName());
+
+    }
+
+    public void testSetStateString() {
+            RuleItem ruleItem1 = getRepo().addRule("testSetStateString", "test lhs content", "test rhs content");
+           
+            ruleItem1.setState("TestState1");
+            assertNotNull(ruleItem1.getState());
+            assertEquals("TestState1", ruleItem1.getState().getName());
+            
+            ruleItem1.setState("TestState2");
+            assertNotNull(ruleItem1.getState());
+            assertEquals("TestState2", ruleItem1.getState().getName());            
+
+    }
+
+    public void testSetStateStateItem() {
+            RuleItem ruleItem1 = getRepo().addRule("testSetStateStateItem", "test lhs content", "test rhs content");
+           
+            StateItem stateItem1 = getRepo().getState("TestState1");
+            ruleItem1.setState(stateItem1);            
+            assertNotNull(ruleItem1.getState());
+            assertEquals(ruleItem1.getState().getName(), "TestState1");
+            
+            StateItem stateItem2 = getRepo().getState("TestState2");
+            ruleItem1.setState(stateItem2);
+            assertNotNull(ruleItem1.getState());
+            assertEquals("TestState2", ruleItem1.getState().getName());            
+
+    }
+
+    public void testGetState() {
+            RuleItem ruleItem1 = getRepo().addRule("testGetState", "test lhs content", "test rhs content");
+           
+            StateItem stateItem1 = ruleItem1.getState();
+            assertNull(stateItem1);
+            
+            ruleItem1.setState("TestState1");
+            assertNotNull(ruleItem1.getState());
+            assertEquals("TestState1", ruleItem1.getState().getName());                        
+    }
+
+    public void testToString() {
+            RuleItem ruleItem1 = getRepo().addRule("testToString", "test lhs content", "test rhs content");
+           
+            assertNotNull(ruleItem1.toString());                        
+
+    }
+    
+    public void testGetLastModified() {
+            RuleItem ruleItem1 = getRepo().addRule("testGetLastModified", "test lhs content", "test rhs content");
+           
+            Calendar cal = Calendar.getInstance();
+            long before = cal.getTimeInMillis();           
+            
+            ruleItem1.updateLhs("new lhs");
+            ruleItem1.checkin( "woot" );
+            Calendar cal2 = ruleItem1.getLastModified();
+            long lastMod = cal2.getTimeInMillis();           
+            
+            cal = Calendar.getInstance();
+            long after = cal.getTimeInMillis();
+            assertTrue(before < after);
+            assertTrue(before < lastMod);
+            assertTrue(lastMod < after);
+
+    }
+    
+    public void testGetDateEffective() {
+
+            RuleItem ruleItem1 = getRepo().addRule("testGetDateEffective", "test lhs content", "test rhs content");
+           
+            //it should be initialized to null
+            assertTrue(ruleItem1.getDateEffective() == null);
+            
+            //now try setting it, then retrieving it
+            Calendar cal = Calendar.getInstance();
+            ruleItem1.updateDateEffective(cal);
+            Calendar cal2 = ruleItem1.getDateEffective();
+            
+            assertEquals(cal, cal2);            
+    }
+    
+    public void testGetDateExpired() {
+        try {
+            RuleItem ruleItem1 = getRepo().addRule("testGetDateExpired", "test lhs content", "test rhs content");
+           
+            //it should be initialized to null
+            assertTrue(ruleItem1.getDateExpired() == null);
+            
+            //now try setting it, then retrieving it
+            Calendar cal = Calendar.getInstance();
+            ruleItem1.updateDateExpired(cal);
+            Calendar cal2 = ruleItem1.getDateExpired();
+            
+            assertEquals(cal, cal2);            
+        }
+        catch(Exception e) {
+            fail("Caught unexpected exception: " + e);
+        }
+    }
+    
+    public void testGetRuleLanguage() {
+        try {
+            RuleItem ruleItem1 = getRepo().addRule("testGetRuleLanguage", "test lhs content", "test rhs content");
+           
+            //it should be initialized to 'DRL'
+            assertEquals("DRL", ruleItem1.getRuleLanguage());                        
+        }
+        catch(Exception e) {
+            fail("Caught unexpected exception: " + e);
+        }
+    }
+    
+    public void testSaveAndCheckinDescriptionAndTitle() throws Exception {
+            RuleItem ruleItem1 = getRepo().addRule("testGetDescription", "test lhs content", "test rhs content");
+            
+            //it should be "" to begin with
+            assertEquals("", ruleItem1.getDescription());
+            
+            ruleItem1.updateDescription("test description");
+            assertEquals("test description", ruleItem1.getDescription());
+            
+            
+            
+            
+            assertFalse(getRepo().getSession().hasPendingChanges());
+            
+            ruleItem1.updateTitle( "This is a title" );
+            assertTrue(getRepo().getSession().hasPendingChanges());
+            ruleItem1.checkin( "ya" );
+
+            
+            //we can save without a checkin
+            getRepo().getSession().save();
+
+            assertFalse(getRepo().getSession().hasPendingChanges());
+
+            
+            try {
+                ruleItem1.getPrecedingVersion().updateTitle( "baaad" );
+                fail("should not be able to do this");
+            } catch (RulesRepositoryException e) {
+                assertNotNull(e.getMessage());
+            }
+            
+    }
+    
+    public void testGetPrecedingVersion() {
+            RuleItem ruleItem1 = getRepo().addRule("testGetPrecedingVersion", "test lhs content", "test rhs content");
+            
+            RuleItem predecessorRuleItem = (RuleItem) ruleItem1.getPrecedingVersion();
+            assertTrue(predecessorRuleItem == null);            
+            
+            ruleItem1.updateLhs("new lhs");
+            ruleItem1.updateRhs( "hola" );
+            ruleItem1.checkin( "two changes" );
+            
+            
+            predecessorRuleItem = (RuleItem) ruleItem1.getPrecedingVersion();
+            assertNotNull(predecessorRuleItem);
+            assertEquals("test lhs content", predecessorRuleItem.getLhs());
+            assertEquals("test rhs content", predecessorRuleItem.getRhs());
+            
+            
+            
+            ruleItem1.updateLhs("newer lhs");
+            ruleItem1.checkin( "another" );
+            
+            predecessorRuleItem = (RuleItem) ruleItem1.getPrecedingVersion();
+            assertNotNull(predecessorRuleItem);
+            assertEquals("new lhs", predecessorRuleItem.getLhs());
+            predecessorRuleItem = (RuleItem) predecessorRuleItem.getPrecedingVersion();
+            assertNotNull(predecessorRuleItem);
+            assertEquals("test lhs content", predecessorRuleItem.getLhs());
+ 
+    }
+    
+    public void testGetSucceedingVersion() {
+        try {
+            RuleItem ruleItem1 = getRepo().addRule("testGetSucceedingVersion", "test lhs content", "test rhs content");
+            
+            RuleItem succeedingRuleItem = (RuleItem) ruleItem1.getSucceedingVersion();
+            assertTrue(succeedingRuleItem == null);            
+            
+            ruleItem1.updateLhs("new lhs");
+            ruleItem1.checkin( "la" );
+            
+            
+            RuleItem predecessorRuleItem = (RuleItem) ruleItem1.getPrecedingVersion();
+            assertEquals("test lhs content", predecessorRuleItem.getLhs());
+            succeedingRuleItem = (RuleItem) predecessorRuleItem.getSucceedingVersion();
+            assertNotNull(succeedingRuleItem);
+            assertEquals(ruleItem1.getLhs(), succeedingRuleItem.getLhs());                       
+        }        
+        catch(Exception e) {
+            fail("Caught unexpected exception: " + e);
+        }   
+    } 
+    
+    public void testGetSuccessorVersionsIterator() {
+        try {
+            RuleItem ruleItem1 = getRepo().addRule("testGetSuccessorVersionsIterator", "test lhs content", "test rhs content");                        
+            
+            Iterator iterator = ruleItem1.getSuccessorVersionsIterator();            
+            assertNotNull(iterator);
+            assertFalse(iterator.hasNext());
+            
+            ruleItem1.updateLhs("new lhs").checkin( "ya" );
+            
+            
+            iterator = ruleItem1.getSuccessorVersionsIterator();            
+            assertNotNull(iterator);
+            assertFalse(iterator.hasNext());
+            
+            RuleItem predecessorRuleItem = (RuleItem) ruleItem1.getPrecedingVersion();
+            iterator = predecessorRuleItem.getSuccessorVersionsIterator();
+            assertNotNull(iterator);
+            assertTrue(iterator.hasNext());
+            RuleItem nextRuleItem = (RuleItem) iterator.next();
+            assertEquals("new lhs", nextRuleItem.getLhs());
+            assertFalse(iterator.hasNext());
+            
+            ruleItem1.updateLhs("newer lhs");
+            ruleItem1.checkin( "boo" );
+                        
+            iterator = predecessorRuleItem.getSuccessorVersionsIterator();
+            assertNotNull(iterator);
+            assertTrue(iterator.hasNext());
+            nextRuleItem = (RuleItem) iterator.next();
+            assertEquals("new lhs", nextRuleItem.getLhs());
+            assertTrue(iterator.hasNext());
+            nextRuleItem = (RuleItem)iterator.next();
+            assertEquals("newer lhs", nextRuleItem.getLhs());
+            assertFalse(iterator.hasNext());            
+        }
+        catch(Exception e) {
+            fail("Caught unexpected exception: " + e);
+        }
+    }
+    
+    public void testGetPredecessorVersionsIterator() {
+        try {
+            RuleItem ruleItem1 = getRepo().addRule("testGetPredecessorVersionsIterator", "test lhs content", "test rhs content");                        
+            
+            Iterator iterator = ruleItem1.getPredecessorVersionsIterator();            
+            assertNotNull(iterator);
+            assertFalse(iterator.hasNext());
+            
+            ruleItem1.updateLhs("new lhs");
+            ruleItem1.checkin( "boo" );
+            
+            iterator = ruleItem1.getPredecessorVersionsIterator();            
+            assertNotNull(iterator);
+            assertTrue(iterator.hasNext());
+            RuleItem nextRuleItem = (RuleItem) iterator.next();
+            assertFalse(iterator.hasNext());
+            assertEquals("test lhs content", nextRuleItem.getLhs());
+            
+            ruleItem1.updateLhs("newer lhs");
+            ruleItem1.checkin( "wee" );
+            
+            
+            iterator = ruleItem1.getPredecessorVersionsIterator();            
+            assertNotNull(iterator);
+            assertTrue(iterator.hasNext());
+            nextRuleItem = (RuleItem) iterator.next();
+            assertTrue(iterator.hasNext());            
+            assertEquals("new lhs", nextRuleItem.getLhs());
+            nextRuleItem = (RuleItem) iterator.next();
+            assertFalse(iterator.hasNext());
+            assertEquals("test lhs content", nextRuleItem.getLhs());
+        }
+        catch(Exception e) {
+            fail("Caught unexpected exception: " + e);
+        }
+    }
+    
+    public void testGetTitle() {    
+        try {
+            RuleItem ruleItem1 = getRepo().addRule("testGetTitle", "test lhs content", "test rhs content");            
+                        
+            assertEquals("testGetTitle", ruleItem1.getTitle());
+        }
+        catch(Exception e) {
+            fail("Caught unexpected exception: " + e);
+        }
+    }
+    
+    public void testGetFormat() {        
+        try {
+            RuleItem ruleItem1 = getRepo().addRule("testGetFormat", "test lhs content", "test rhs content");
+            
+            assertEquals("Rule", ruleItem1.getFormat());            
+        }
+        catch(Exception e) {
+            fail("Caught unexpected exception: " + e);
+        }
+    }        
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RuleItemTestCase.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: 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-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RulePackageItemTestCase.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,408 @@
+package org.drools.repository;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.List;
+
+import org.drools.repository.*;
+
+import junit.framework.TestCase;
+
+public class RulePackageItemTestCase extends TestCase {
+
+    public void testRulePackageItem() throws Exception {
+        RulesRepository repo = getRepo();
+        try {
+            
+            //calls constructor
+            RulePackageItem rulePackageItem1 = repo.createRulePackage("testRulePackage");
+            assertNotNull(rulePackageItem1);
+            assertEquals("testRulePackage", rulePackageItem1.getName());
+            
+            Iterator it = getRepo().listPackages();
+            assertTrue(it.hasNext());
+
+            while (it.hasNext()) {
+                RulePackageItem pack = (RulePackageItem) it.next();
+                if (pack.getName().equals( "testRulePackage" )) {
+                    return;
+                }
+                
+               
+            }
+            fail("should have picked up the testRulePackage but didnt.");
+            
+        }
+        catch(Exception e) {
+            e.printStackTrace();
+            fail("Caught unexpected exception: " + e);
+        }
+        
+        //try constructing with node of wrong type
+        try {            
+            DslItem dslItem = repo.addDsl("testRulePackageItem", "content");
+            RulePackageItem rulePackageItem2 = new RulePackageItem(repo, dslItem.getNode());
+            fail("Exception not thrown for node of type: " + dslItem.getNode().getPrimaryNodeType().getName());
+        }
+        catch(RulesRepositoryException e) {
+            //this is good
+        }
+        catch(Exception e) {
+            e.printStackTrace();
+            fail("Caught unexpected exception: " + e);
+        }
+    }
+
+    private RulesRepository getRepo() {
+        return RepositorySession.getRepository();
+    }
+
+    public void testAddRuleRuleItem() {
+            RulePackageItem rulePackageItem1 = getRepo().createRulePackage("testAddRuleRuleItem");
+            
+            RuleItem ruleItem1 = getRepo().addRule("testAddRuleRuleItem", "test lhs content", "test rhs content");
+            
+            rulePackageItem1.addRule(ruleItem1);
+            
+            List rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(1, rules.size());
+            assertEquals("testAddRuleRuleItem", ((RuleItem)rules.get(0)).getName());
+            
+            //test that it is following the head revision                        
+            ruleItem1.updateLhs("new lhs");
+            rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(1, rules.size());
+            assertEquals("testAddRuleRuleItem", ((RuleItem)rules.get(0)).getName());
+            assertEquals("new lhs", ((RuleItem)rules.get(0)).getLhs());
+                        
+            RuleItem ruleItem2 = getRepo().addRule("testAddRuleRuleItem2", "test lhs content", "test rhs content");
+            rulePackageItem1.addRule(ruleItem2);
+            
+            rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(2, rules.size());  
+
+    }
+
+    public void testAddRuleRuleItemBoolean() {
+            RulePackageItem rulePackageItem1 = getRepo().createRulePackage("testAddRuleRuleItemBoolean");
+            
+            RuleItem ruleItem1 = getRepo().addRule("testAddRuleRuleItemBoolean", "test lhs content", "test rhs content");
+            
+            rulePackageItem1.addRule(ruleItem1, true);
+            
+            List rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(1, rules.size());
+            assertEquals("testAddRuleRuleItemBoolean", ((RuleItem)rules.get(0)).getName());
+            
+            //test that it is following the head revision                        
+            ruleItem1.updateLhs("new lhs");
+            rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(1, rules.size());
+            assertEquals("testAddRuleRuleItemBoolean", ((RuleItem)rules.get(0)).getName());
+            assertEquals("new lhs", ((RuleItem)rules.get(0)).getLhs());
+            
+            RuleItem ruleItem2 = getRepo().addRule("testAddRuleRuleItemBoolean2", "test lhs content", "test rhs content");
+            rulePackageItem1.addRule(ruleItem2);
+            
+            rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(2, rules.size());
+            
+            //test not following the head revision
+            rulePackageItem1.removeAllRules();
+            RuleItem ruleItem3 = getRepo().addRule("testAddRuleRuleItemBoolean3", "test lhs content", "test rhs content");
+            
+            rulePackageItem1.addRule(ruleItem3, false);
+            
+            rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(1, rules.size());
+            assertEquals("test lhs content", ((RuleItem)rules.get(0)).getLhs());
+                                    
+            ruleItem3.updateLhs("new lhs");
+            rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(1, rules.size());
+            assertEquals("test lhs content", ((RuleItem)rules.get(0)).getLhs());
+
+    }
+
+    public void testAddFunctionFunctionItem() {
+            RulePackageItem rulePackageItem1 = getRepo().createRulePackage("testAddFunctionFunctionItem");
+            
+            FunctionItem functionItem1 = getRepo().addFunction("test function", "test content");
+            
+            rulePackageItem1.addFunction(functionItem1);
+            
+            List functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(1, functions.size());
+            assertEquals("test function", ((FunctionItem)functions.get(0)).getName());
+            
+            //test that it is following the head revision                        
+            functionItem1.updateContent("new content");
+            functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(1, functions.size());
+            assertEquals("test function", ((FunctionItem)functions.get(0)).getName());
+            assertEquals("new content", ((FunctionItem)functions.get(0)).getContent());
+                        
+            FunctionItem functionItem2 = getRepo().addFunction("test function 2", "test content");
+            rulePackageItem1.addFunction(functionItem2);
+            
+            functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(2, functions.size());                          
+
+    }
+
+    public void testAddFunctionFunctionItemBoolean() {
+            RulePackageItem rulePackageItem1 = getRepo().createRulePackage("testAddFunctionFunctionItemBoolean");
+            
+            FunctionItem functionItem1 = getRepo().addFunction("testAddFunctionFunctionItemBoolean", "test content");
+            
+            rulePackageItem1.addFunction(functionItem1, true);
+            
+            List functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(1, functions.size());
+            assertEquals("testAddFunctionFunctionItemBoolean", ((FunctionItem)functions.get(0)).getName());
+            
+            //test that it is following the head revision                        
+            functionItem1.updateContent("new content");
+            functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(1, functions.size());
+            assertEquals("testAddFunctionFunctionItemBoolean", ((FunctionItem)functions.get(0)).getName());
+            assertEquals("new content", ((FunctionItem)functions.get(0)).getContent());
+            
+            FunctionItem functionItem2 = getRepo().addFunction("testAddFunctionFunctionItemBoolean2", "test content");
+            rulePackageItem1.addFunction(functionItem2);
+            
+            functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(2, functions.size());
+            
+            //test not following the head revision
+            rulePackageItem1.removeAllFunctions();
+            FunctionItem functionItem3 = getRepo().addFunction("testAddFunctionFunctionItemBoolean3", "test content");
+            
+            rulePackageItem1.addFunction(functionItem3, false);
+            
+            functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(1, functions.size());
+            assertEquals("test content", ((FunctionItem)functions.get(0)).getContent());
+                                    
+            functionItem3.updateContent("new content");
+            functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(1, functions.size());
+            assertEquals("test content", ((FunctionItem)functions.get(0)).getContent());
+
+    }
+
+    public void testGetFunctions() {
+            RulePackageItem rulePackageItem1 = getRepo().createRulePackage("testGetFunctions");
+                        
+            FunctionItem functionItem1 = getRepo().addFunction("testGetFunctions", "test content");
+            
+            rulePackageItem1.addFunction(functionItem1);
+            
+            List functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(1, functions.size());
+            assertEquals("testGetFunctions", ((FunctionItem)functions.get(0)).getName());
+                                  
+            FunctionItem functionItem2 = getRepo().addFunction("testGetFunctions2", "test content");
+            rulePackageItem1.addFunction(functionItem2);
+            
+            functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(2, functions.size());            
+
+    }
+    
+    public void testGetRules() {
+            RulePackageItem rulePackageItem1 = getRepo().createRulePackage("testGetRules");
+                        
+            RuleItem ruleItem1 = getRepo().addRule("testGetRules", "test lhs content", "test rhs content");
+            
+            rulePackageItem1.addRule(ruleItem1);
+            
+            List rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(1, rules.size());
+            assertEquals("testGetRules", ((RuleItem)rules.get(0)).getName());
+                                  
+            RuleItem ruleItem2 = getRepo().addRule("testGetRules2", "test lhs content", "test rhs content");
+            rulePackageItem1.addRule(ruleItem2);
+            
+            rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(2, rules.size());            
+
+    }
+
+    public void testToString() {
+            RulePackageItem rulePackageItem1 = getRepo().createRulePackage("testToStringPackage");
+            
+            RuleItem ruleItem1 = getRepo().addRule("testToStringPackage", "test lhs content", "test rhs content");
+            
+            rulePackageItem1.addRule(ruleItem1);
+            assertNotNull(rulePackageItem1.toString());                        
+
+    }
+    
+    public void testRemoveRule() {
+            RulePackageItem rulePackageItem1 = getRepo().createRulePackage("testRemoveRule");
+            
+            RuleItem ruleItem1 = getRepo().addRule("testRemoveRule", "test lhs content", "test rhs content");
+            
+            rulePackageItem1.addRule(ruleItem1);
+            
+            List rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(1, rules.size());
+            assertEquals("testRemoveRule", ((RuleItem)rules.get(0)).getName());
+                                    
+            ruleItem1.updateLhs("new lhs");
+            rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(1, rules.size());
+            assertEquals("testRemoveRule", ((RuleItem)rules.get(0)).getName());
+            assertEquals("new lhs", ((RuleItem)rules.get(0)).getLhs());
+            
+            RuleItem ruleItem2 = getRepo().addRule("testRemoveRule2", "test lhs content", "test rhs content");
+            rulePackageItem1.addRule(ruleItem2);
+            
+            //remove the rule, make sure the other rule in the pacakge stays around
+            rulePackageItem1.removeRule(ruleItem1);
+            rules = rulePackageItem1.getRules();
+            assertEquals(1, rules.size());
+            assertEquals("testRemoveRule2", ((RuleItem)rules.get(0)).getName());
+            
+            //remove the rule that is following the head revision, make sure the pacakge is now empty
+            rulePackageItem1.removeRule(ruleItem2);
+            rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(0, rules.size());
+
+    }
+    
+    public void testRemoveAllRules() {
+            RulePackageItem rulePackageItem1 = getRepo().createRulePackage("testRemoveAllRules");
+            
+            RuleItem ruleItem1 = getRepo().addRule("testRemoveAllRules", "test lhs content", "test rhs content");
+            
+            rulePackageItem1.addRule(ruleItem1);
+            
+            List rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(1, rules.size());
+            assertEquals("testRemoveAllRules", ((RuleItem)rules.get(0)).getName());
+            
+            rulePackageItem1.removeAllRules();
+            
+            rules = rulePackageItem1.getRules();
+            assertNotNull(rules);
+            assertEquals(0, rules.size());            
+
+    }    
+    
+    public void testRemoveFunction() {
+            RulePackageItem rulePackageItem1 = getRepo().createRulePackage("testRemoveFunction");
+            
+            FunctionItem functionItem1 = getRepo().addFunction("testRemoveFunction", "test content");
+            
+            rulePackageItem1.addFunction(functionItem1);
+            
+            List functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(1, functions.size());
+            assertEquals("testRemoveFunction", ((FunctionItem)functions.get(0)).getName());
+                                    
+            functionItem1.updateContent("new content");
+            functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(1, functions.size());
+            assertEquals("testRemoveFunction", ((FunctionItem)functions.get(0)).getName());
+            assertEquals("new content", ((FunctionItem)functions.get(0)).getContent());
+            
+            FunctionItem functionItem2 = getRepo().addFunction("testRemoveFunction2", "test content");
+            rulePackageItem1.addFunction(functionItem2);
+            
+            //remove the function, make sure the other function in the package stays around
+            rulePackageItem1.removeFunction(functionItem1);
+            functions = rulePackageItem1.getFunctions();
+            assertEquals(1, functions.size());
+            assertEquals("testRemoveFunction2", ((FunctionItem)functions.get(0)).getName());
+            
+            //remove the function that is following the head revision, make sure the package is now empty
+            rulePackageItem1.removeFunction(functionItem2);
+            functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(0, functions.size());
+
+    }
+    
+    public void testRemoveAllFunctions() {
+            RulePackageItem rulePackageItem1 = getRepo().createRulePackage("testRemoveAllFunctions");
+            
+            FunctionItem functionItem1 = getRepo().addFunction("testRemoveAllFunctions", "test content");
+            
+            rulePackageItem1.addFunction(functionItem1);
+            
+            List functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(1, functions.size());
+            assertEquals("testRemoveAllFunctions", ((FunctionItem)functions.get(0)).getName());
+            
+            rulePackageItem1.removeAllFunctions();
+            
+            functions = rulePackageItem1.getFunctions();
+            assertNotNull(functions);
+            assertEquals(0, functions.size());            
+
+    }
+    
+    public void testGetPrecedingVersion() {
+        //not bothering to implement this test since it is pretty much covered by the RuleItemTestCase   
+    }
+    
+    public void testGetSucceedingVersion() {
+        //not bothering to implement this test since it is pretty much covered by the RuleItemTestCase   
+    } 
+    
+    public void testGetSuccessorVersionsIterator() {
+        //This is covered by the test in RuleItemTestCase - all functionality under test
+        // resides in the common subclass, VersionableItem
+    }
+    
+    public void testGetPredecessorVersionsIterator() {
+        //This is covered by the test in RuleItemTestCase - all functionality under test
+        // resides in the common subclass, VersionableItem
+    }
+    
+    public void testGetTitle() {
+        //This is covered by the test in RuleItemTestCase - all functionality under test
+        // resides in the common subclass, VersionableItem
+    }
+    
+    public void testGetContributor() {
+        //This is covered by the test in RuleItemTestCase - all functionality under test
+        // resides in the common subclass, VersionableItem        
+    }
+    
+    public void testGetFormat() {        
+            RulePackageItem rulePackageItem1 = getRepo().createRulePackage("testGetFormat");
+            assertNotNull(rulePackageItem1);
+            assertEquals("Rule Package", rulePackageItem1.getFormat());    
+
+    }        
+}
\ No newline at end of file


Property changes on: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RulePackageItemTestCase.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RulesRepositoryTestCase.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RulesRepositoryTestCase.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RulesRepositoryTestCase.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,197 @@
+package org.drools.repository;
+
+import java.io.File;
+import java.util.Calendar;
+import java.util.Iterator;
+
+import org.drools.repository.*;
+
+import junit.framework.TestCase;
+
+public class RulesRepositoryTestCase extends TestCase {
+
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testAddRuleDslItemBoolean() {
+        RulesRepository rulesRepository = RepositorySession.getRepository();
+            
+            
+            
+            DslItem dslItem1 = rulesRepository.addDsl("testAddRuleDslItemBoolean", "original content");
+            assertNotNull(dslItem1);
+            
+            RuleItem ruleItem1 = rulesRepository.addRule("testAddRuleDslItemBoolean", "test lhs content", "test rhs content", dslItem1, true);
+            
+            assertNotNull(ruleItem1);
+            assertNotNull(ruleItem1.getNode());
+            assertNotNull(ruleItem1.getDsl());
+            assertEquals(dslItem1.getContent(), ruleItem1.getDsl().getContent());
+            
+            //test that this follows the head version
+            
+            dslItem1.updateContent("new content");
+            assertNotNull(ruleItem1.getNode());
+            assertNotNull(ruleItem1.getDsl());
+            assertEquals(dslItem1.getContent(), ruleItem1.getDsl().getContent());
+            
+            //now do the same thing, but test not following head:                                    
+            RuleItem ruleItem2 = rulesRepository.addRule("testAddRuleDslItemBoolean2", "test lhs content", "test rhs content", dslItem1, false);
+            
+            assertNotNull(ruleItem2);
+            assertNotNull(ruleItem2.getNode());
+            assertNotNull(ruleItem2.getDsl());
+            assertEquals(dslItem1.getContent(), ruleItem2.getDsl().getContent());
+            
+            //test that this stays tied to the specific revision of the DSL node
+            String originalContent = ruleItem2.getDsl().getContent();
+            dslItem1.updateContent("new content");
+            assertNotNull(ruleItem2.getNode());
+            assertNotNull(ruleItem2.getDsl());
+            assertEquals(originalContent, ruleItem2.getDsl().getContent());
+    }
+    
+    public void testAddRuleCalendarCalendar() {
+        RulesRepository rulesRepository = RepositorySession.getRepository();
+
+                        
+            Calendar effectiveDate = Calendar.getInstance();
+            Calendar expiredDate = Calendar.getInstance();
+            expiredDate.setTimeInMillis(effectiveDate.getTimeInMillis() + (1000 * 60 * 60 * 24));
+            RuleItem ruleItem1 = rulesRepository.addRule("testAddRuleCalendarCalendar", "test lhs content", "test rhs content", effectiveDate, expiredDate);
+            
+            assertNotNull(ruleItem1);
+            assertNotNull(ruleItem1.getNode());
+            assertEquals(effectiveDate, ruleItem1.getDateEffective());
+            assertEquals(expiredDate, ruleItem1.getDateExpired());                       
+    }
+    
+    public void testAddRuleDslItemBooleanCalendarCalendar() {
+        RulesRepository rulesRepository = RepositorySession.getRepository();
+            DslItem dslItem1 = rulesRepository.addDsl("testAddRuleDslItemBooleanCalendarCalendar", "content here");
+            assertNotNull(dslItem1);
+            
+            Calendar effectiveDate = Calendar.getInstance();
+            Calendar expiredDate = Calendar.getInstance();
+            expiredDate.setTimeInMillis(effectiveDate.getTimeInMillis() + (1000 * 60 * 60 * 24));
+            
+            RuleItem ruleItem1 = rulesRepository.addRule("testAddRuleDslItemBooleanCalendarCalendar", "test lhs content", "test rhs content", dslItem1, true, effectiveDate, expiredDate, "test description");
+            
+            assertNotNull(ruleItem1);
+            assertNotNull(ruleItem1.getNode());
+            assertNotNull(ruleItem1.getDsl());
+            assertEquals(dslItem1.getContent(), ruleItem1.getDsl().getContent());
+            assertEquals(effectiveDate, ruleItem1.getDateEffective());
+            assertEquals(expiredDate, ruleItem1.getDateExpired());
+            assertEquals("test description", ruleItem1.getDescription());
+            
+            //test that this follows the head version
+            
+            dslItem1.updateContent("more content");
+            assertNotNull(ruleItem1.getNode());
+            assertNotNull(ruleItem1.getDsl());
+            assertEquals(dslItem1.getContent(), ruleItem1.getDsl().getContent());
+            
+            //now do the same thing, but test not following head:                                    
+            RuleItem ruleItem2 = rulesRepository.addRule("testAddRuleDslItemBooleanCalendarCalendar2", "test lhs content", "test rhs content", dslItem1, false, effectiveDate, expiredDate, "test description 2");
+            
+            assertNotNull(ruleItem2);
+            assertNotNull(ruleItem2.getNode());
+            assertNotNull(ruleItem2.getDsl());
+            assertEquals(dslItem1.getContent(), ruleItem2.getDsl().getContent());
+            assertEquals(effectiveDate, ruleItem2.getDateEffective());
+            assertEquals(expiredDate, ruleItem2.getDateExpired());
+            assertEquals("test description 2", ruleItem2.getDescription());
+            
+            //test that this stays tied to the specific revision of the DSL node
+            String originalContent = ruleItem2.getDsl().getContent();
+            dslItem1.updateContent("more content");
+            assertNotNull(ruleItem2.getNode());
+            assertNotNull(ruleItem2.getDsl());
+            assertEquals(originalContent, ruleItem2.getDsl().getContent());
+    }
+    
+
+    public void testGetState() {
+        RulesRepository rulesRepository = RepositorySession.getRepository();
+            
+            
+            StateItem stateItem1 = rulesRepository.getState("testGetState");
+            assertNotNull(stateItem1);
+            assertEquals("testGetState", stateItem1.getName());
+            
+            StateItem stateItem2 = rulesRepository.getState("testGetState");
+            assertNotNull(stateItem2);
+            assertEquals("testGetState", stateItem2.getName());
+            assertEquals(stateItem1, stateItem2);
+    }
+
+    public void testGetTag() {
+        RulesRepository rulesRepository = RepositorySession.getRepository();
+            CategoryItem tagItem1 = rulesRepository.getOrCreateCategory("testGetTag");
+            assertNotNull(tagItem1);
+            assertEquals("testGetTag", tagItem1.getName());
+            assertEquals("testGetTag", tagItem1.getFullPath());
+            
+            CategoryItem tagItem2 = rulesRepository.getOrCreateCategory("testGetTag");
+            assertNotNull(tagItem2);
+            assertEquals("testGetTag", tagItem2.getName());
+            assertEquals(tagItem1, tagItem2);
+            
+            //now test getting a tag down in the tag hierarchy
+            CategoryItem tagItem3 = rulesRepository.getOrCreateCategory("testGetTag/TestChildTag1");
+            assertNotNull(tagItem3);
+            assertEquals("TestChildTag1", tagItem3.getName());
+            assertEquals("testGetTag/TestChildTag1", tagItem3.getFullPath());                                   
+    }
+    
+    public void testAddFunctionStringString() {
+        RulesRepository rulesRepository = RepositorySession.getRepository();
+            FunctionItem functionItem1 = rulesRepository.addFunction("testAddFunctionStringString", "test content");
+            
+            assertNotNull(functionItem1);
+            assertNotNull(functionItem1.getNode());
+            assertEquals("testAddFunctionStringString", functionItem1.getName());
+            assertEquals("test content", functionItem1.getContent());
+            assertEquals("", functionItem1.getDescription());
+    }
+    
+    public void testAddFunctionStringStringString() {
+        RulesRepository rulesRepository = RepositorySession.getRepository();
+                        
+            FunctionItem functionItem1 = rulesRepository.addFunction("testAddFunctionStringStringString", "test content", "test description");
+            
+            assertNotNull(functionItem1);
+            assertNotNull(functionItem1.getNode());
+            assertEquals("testAddFunctionStringStringString", functionItem1.getName());
+            assertEquals("test content", functionItem1.getContent());
+            assertEquals("test description", functionItem1.getDescription());
+    }
+    
+    public void testListPackages() {
+        RulesRepository rulesRepository = RepositorySession.getRepository();
+        
+        
+            RulePackageItem rulePackageItem1 = rulesRepository.createRulePackage("testListPackages");
+            
+            Iterator it = rulesRepository.listPackages();
+            assertTrue(it.hasNext());
+            
+            boolean found = false;
+            while ( it.hasNext() ) {
+                RulePackageItem element = (RulePackageItem) it.next();
+                if (element.getName().equals( "testListPackages" ))
+                {
+                    found = true;
+                    break;
+                }
+            }
+            assertTrue(found);
+            
+    }
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/RulesRepositoryTestCase.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/ScalabilityTest.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/ScalabilityTest.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/ScalabilityTest.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,180 @@
+package org.drools.repository;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.UnsupportedRepositoryOperationException;
+
+import org.apache.jackrabbit.core.TransientRepository;
+import org.drools.repository.RuleItem;
+import org.drools.repository.RulesRepository;
+import org.drools.repository.RulesRepositoryException;
+import org.drools.repository.VersionableItem;
+
+import junit.framework.TestCase;
+
+
+/** 
+ * This is a bit of a hacked scalability test. 
+ * It will add 5000 odd rule nodes, and then do some basic operations.
+ * It will take a LONG time to add these nodes, and does it in batches.
+ *
+ */
+public class ScalabilityTest extends TestCase {
+
+    private static final int NUM = 5000;
+    private RulesRepository repo;
+    
+    public void testDummy() {
+        
+    }
+    
+    public void xxtestRun() throws Exception {        
+        repo = new RulesRepository(false);   
+        
+        long start = System.currentTimeMillis();
+        //setupData( repo );
+        System.out.println("time to add, version and tag 5000: " + (System.currentTimeMillis() - start));
+        List list = listACat(repo);
+        System.out.println("list size is: " + list.size());
+        
+        start = System.currentTimeMillis();
+        RuleItem item = (RuleItem) list.get( 0 );
+        item.updateLhs( "this is a description" );
+        item.checkin( "newer" );
+        System.out.println("time to update and version: " + (System.currentTimeMillis() - start));
+        
+        start = System.currentTimeMillis();
+        item = (RuleItem) list.get( 42 );
+        item.updateLhs( "this is a description" );
+        item.updateRhs( "wooooooooooooooooooooooooooooooooooot" );
+        item.checkin( "latest" );
+        System.out.println("time to update and version: " + (System.currentTimeMillis() - start));        
+        
+    }
+    
+    /** This tests it "bare" just setting properties on node types directly. */
+    public void xxxtestBare() throws Exception {
+        hackit();
+    }
+
+    private List listACat(RulesRepository repo) {
+        long start = System.currentTimeMillis();
+        List results = repo.findRulesByTag( "HR/CAT_1" );
+        System.out.println("Time for listing a cat: " + (System.currentTimeMillis() - start));
+        
+        start = System.currentTimeMillis();
+        List results2 = repo.findRulesByTag( "HR/CAT_1" );
+        System.out.println("Time for listing a cat: " + (System.currentTimeMillis() - start));
+
+
+        start = System.currentTimeMillis();
+        results2 = repo.findRulesByTag( "HR/CAT_100" );
+        System.out.println("Time for listing a cat: " + (System.currentTimeMillis() - start));
+
+        start = System.currentTimeMillis();
+        results2 = repo.findRulesByTag( "HR/CAT_100" );
+        System.out.println("Time for listing a cat: " + (System.currentTimeMillis() - start));
+
+        
+        return results;
+    }
+
+    /** To run this, need to hack the addRule method to not save a session */
+    private void setupData(RulesRepository repo) throws Exception {
+        
+
+        int count = 1;
+        
+        List list = new ArrayList();
+        
+        String prefix = "HR/";
+        String cat = prefix + "CAT_1";
+        for (int i=1; i <= NUM; i++ ) {
+            
+            if (i % 500 == 0) {
+                repo.getSession().save();
+                for ( Iterator iter = list.iterator(); iter.hasNext(); ) {
+                    RuleItem element = (RuleItem) iter.next();                    
+                    element.getNode().checkin();                    
+                }
+                list.clear();
+            }
+            
+            
+            if (i > 2500) {
+                prefix = "FINANCE/";
+            }
+            
+            if (count == 100) {
+                count = 1;
+                cat = prefix + "CAT_" + i;
+                System.err.println("changing CAT");
+                System.gc();
+                
+            } else {
+                count++;
+            }            
+            
+            String ruleName = "rule_" + i + "_" + System.currentTimeMillis();
+            System.out.println("ADDING rule: " + ruleName);
+                        
+            
+            RuleItem item = repo.addRule( ruleName, "Foo(bar == " + i + ")", "panic(" + i + ");" );            
+            item.addCategory( cat );
+            list.add( item );
+            
+        }
+        
+        
+        
+
+    }
+    
+
+    private void hackit() throws Exception {
+        
+        
+        RulesRepository repo = new RulesRepository(true);
+        Session session = repo.getSession();
+        
+        
+        Node folderNode = session.getRootNode().getNode("drools:repository/drools:rule_area");
+        
+        for (int i=1 ; i <= 50; i++) {
+            
+            System.out.println("doing: Rule " + i);
+            
+            //create the node - see section 6.7.22.6 of the spec
+            Node ruleNode = folderNode.addNode("Rule_" + i, RuleItem.RULE_NODE_TYPE_NAME );
+                        
+            ruleNode.setProperty(RuleItem.TITLE_PROPERTY_NAME, "Rule_" + i);
+            
+            //TODO: set this property correctly once we've figured out logging in / JAAS
+            ruleNode.setProperty(RuleItem.CONTRIBUTOR_PROPERTY_NAME, "not yet implemented");
+                        
+            ruleNode.setProperty(RuleItem.DESCRIPTION_PROPERTY_NAME, "");
+            ruleNode.setProperty(RuleItem.FORMAT_PROPERTY_NAME, RuleItem.RULE_FORMAT);
+            ruleNode.setProperty(RuleItem.LHS_PROPERTY_NAME, "LHS_" + i);
+            ruleNode.setProperty(RuleItem.RHS_PROPERTY_NAME, "RHS_" + i);                        
+            ruleNode.setProperty( VersionableItem.CHECKIN_COMMENT, "Initial" );
+            
+            
+            Calendar lastModified = Calendar.getInstance();
+            ruleNode.setProperty(RuleItem.LAST_MODIFIED_PROPERTY_NAME, lastModified);
+            if (i % 500 == 0) {
+                System.out.println("saving......");
+                session.save();
+                System.out.println("finished.");                
+            }
+        }
+        
+    }
+    
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/ScalabilityTest.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/StackUtil.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/StackUtil.java	2006-09-07 08:39:37 UTC (rev 6099)
+++ labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/StackUtil.java	2006-09-07 09:37:31 UTC (rev 6100)
@@ -0,0 +1,34 @@
+package org.drools.repository;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.util.StringTokenizer;
+
+public class StackUtil {
+
+    /**
+     * Return the name of the routine that called getCurrentMethodName
+     *
+     * @author Johan Känngård, http://dev.kanngard.net
+     * (found on the net in 2000, donŽt remember where...)
+     */
+    public static String getCurrentMethodName() {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        PrintWriter pw = new PrintWriter(baos);
+        (new Throwable()).printStackTrace(pw);
+        pw.flush();
+        String stackTrace = baos.toString();
+        pw.close();
+
+        StringTokenizer tok = new StringTokenizer(stackTrace, "\n");
+        String l = tok.nextToken(); // 'java.lang.Throwable'
+        l = tok.nextToken(); // 'at ...getCurrentMethodName'
+        l = tok.nextToken(); // 'at ...<caller to getCurrentRoutine>'
+        // Parse line 3
+        tok = new StringTokenizer(l.trim(), " <(");
+        String t = tok.nextToken(); // 'at'
+        t = tok.nextToken(); // '...<caller to getCurrentRoutine>'
+        return t;
+    }    
+    
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/test/java/org/drools/repository/StackUtil.java
___________________________________________________________________
Name: svn:eol-style
   + native




More information about the jboss-svn-commits mailing list