[jboss-svn-commits] JBL Code SVN: r8181 - in labs/jbossrules/contrib: . dynamic dynamic/.externalToolBuilders dynamic/.settings dynamic/libs dynamic/src dynamic/src/java dynamic/src/java/com dynamic/src/java/com/sample dynamic/src/rules

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sun Dec 10 14:26:05 EST 2006


Author: tirelli
Date: 2006-12-10 14:25:46 -0500 (Sun, 10 Dec 2006)
New Revision: 8181

Added:
   labs/jbossrules/contrib/dynamic/
   labs/jbossrules/contrib/dynamic/.classpath
   labs/jbossrules/contrib/dynamic/.externalToolBuilders/
   labs/jbossrules/contrib/dynamic/.externalToolBuilders/org.drools.ide.droolsbuilder.launch
   labs/jbossrules/contrib/dynamic/.project
   labs/jbossrules/contrib/dynamic/.settings/
   labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.core.prefs
   labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.ui.prefs
   labs/jbossrules/contrib/dynamic/.settings/org.eclipse.ltk.core.refactoring.prefs
   labs/jbossrules/contrib/dynamic/libs/
   labs/jbossrules/contrib/dynamic/libs/asm-all-3.0.jar
   labs/jbossrules/contrib/dynamic/src/
   labs/jbossrules/contrib/dynamic/src/java/
   labs/jbossrules/contrib/dynamic/src/java/com/
   labs/jbossrules/contrib/dynamic/src/java/com/sample/
   labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassBuilder.java
   labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassDefinition.java
   labs/jbossrules/contrib/dynamic/src/java/com/sample/Customer.java
   labs/jbossrules/contrib/dynamic/src/java/com/sample/DroolsTest.java
   labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessor.java
   labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessorBuilder.java
   labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldDefinition.java
   labs/jbossrules/contrib/dynamic/src/rules/
   labs/jbossrules/contrib/dynamic/src/rules/Shipper.drl
Log:
Adding sample project using dynamically generated classes

Added: labs/jbossrules/contrib/dynamic/.classpath
===================================================================
--- labs/jbossrules/contrib/dynamic/.classpath	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/.classpath	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/java"/>
+	<classpathentry kind="src" path="src/rules"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="DROOLS/JBoss Rules"/>
+	<classpathentry kind="lib" path="libs/asm-all-3.0.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>


Property changes on: labs/jbossrules/contrib/dynamic/.classpath
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/dynamic/.externalToolBuilders/org.drools.ide.droolsbuilder.launch
===================================================================
--- labs/jbossrules/contrib/dynamic/.externalToolBuilders/org.drools.ide.droolsbuilder.launch	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/.externalToolBuilders/org.drools.ide.droolsbuilder.launch	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
+<mapAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_DISABLED_BUILDER" value="org.drools.ide.droolsbuilder"/>
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
+</launchConfiguration>


Property changes on: labs/jbossrules/contrib/dynamic/.externalToolBuilders/org.drools.ide.droolsbuilder.launch
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/dynamic/.project
===================================================================
--- labs/jbossrules/contrib/dynamic/.project	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/.project	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>DynamicBeans</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+				<dictionary>
+					<key>LaunchConfigHandle</key>
+					<value>&lt;project&gt;/.externalToolBuilders/org.drools.ide.droolsbuilder.launch</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>


Property changes on: labs/jbossrules/contrib/dynamic/.project
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.core.prefs	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.core.prefs	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,12 @@
+#Thu Oct 19 22:42:03 GMT-03:00 2006
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5


Property changes on: labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.core.prefs
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.ui.prefs
===================================================================
--- labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.ui.prefs	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.ui.prefs	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,3 @@
+#Thu Oct 19 22:42:03 GMT-03:00 2006
+eclipse.preferences.version=1
+internal.default.compliance=default


Property changes on: labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.ui.prefs
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/dynamic/.settings/org.eclipse.ltk.core.refactoring.prefs
===================================================================
--- labs/jbossrules/contrib/dynamic/.settings/org.eclipse.ltk.core.refactoring.prefs	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/.settings/org.eclipse.ltk.core.refactoring.prefs	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,3 @@
+#Sun Dec 10 16:13:10 GMT-03:00 2006
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false


Property changes on: labs/jbossrules/contrib/dynamic/.settings/org.eclipse.ltk.core.refactoring.prefs
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/dynamic/libs/asm-all-3.0.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossrules/contrib/dynamic/libs/asm-all-3.0.jar
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassBuilder.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassBuilder.java	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassBuilder.java	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,844 @@
+package com.sample;
+
+import java.beans.IntrospectionException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.drools.RuntimeDroolsException;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A builder to dinamically build simple JavaBean classes
+ *
+ * @author <mailto:etirelli at redhat.com>Edson Tirelli</mailto>
+ * 
+ */
+public class ClassBuilder {
+    private boolean            debug       = false;
+
+    private PackageClassLoader classLoader = new PackageClassLoader( ClassBuilder.class.getClassLoader() );
+
+    public ClassBuilder() {
+        this.debug = "false".equalsIgnoreCase( System.getProperty( "com.sample.debug" ) );
+    }
+
+    /**
+     * Dinamically builds, defines and loads a class based on the given class definition
+     *  
+     * @param classDef the class definition object structure
+     * 
+     * @return the Class instance for the given class definition
+     * 
+     * @throws IOException
+     * @throws IntrospectionException 
+     * @throws InvocationTargetException 
+     * @throws IllegalAccessException 
+     * @throws NoSuchMethodException 
+     * @throws ClassNotFoundException 
+     * @throws IllegalArgumentException 
+     * @throws SecurityException 
+     * @throws NoSuchFieldException 
+     * @throws InstantiationException 
+     */
+    public Class buildAndLoadClass(ClassDefinition classDef) throws IOException,
+                                                            IntrospectionException,
+                                                            SecurityException,
+                                                            IllegalArgumentException,
+                                                            ClassNotFoundException,
+                                                            NoSuchMethodException,
+                                                            IllegalAccessException,
+                                                            InvocationTargetException,
+                                                            InstantiationException,
+                                                            NoSuchFieldException {
+        try {
+            Class clazz = Class.forName( classDef.getClassName() );
+
+            classDef.setDefinedClass( clazz );
+
+            return clazz;
+
+        } catch ( ClassNotFoundException e ) {
+            // class not loaded, so create and load it
+            byte[] serializedClazz = this.buildClass( classDef );
+
+            Class clazz = this.loadClass( classDef.getClassName(),
+                                          serializedClazz );
+            classDef.setDefinedClass( clazz );
+
+            return clazz;
+        }
+    }
+
+    /**
+     * Dinamically builds, defines and loads a class based on the given class definition
+     *  
+     * @param classDef the class definition object structure
+     * 
+     * @return the Class instance for the given class definition
+     * 
+     * @throws IOException
+     * @throws IntrospectionException 
+     * @throws InvocationTargetException 
+     * @throws IllegalAccessException 
+     * @throws NoSuchMethodException 
+     * @throws ClassNotFoundException 
+     * @throws IllegalArgumentException 
+     * @throws SecurityException 
+     * @throws NoSuchFieldException 
+     * @throws InstantiationException 
+     */
+    public byte[] buildClass(ClassDefinition classDef) throws IOException,
+                                                      IntrospectionException,
+                                                      SecurityException,
+                                                      IllegalArgumentException,
+                                                      ClassNotFoundException,
+                                                      NoSuchMethodException,
+                                                      IllegalAccessException,
+                                                      InvocationTargetException,
+                                                      InstantiationException,
+                                                      NoSuchFieldException {
+
+        ClassWriter cw = new ClassWriter( ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES );
+
+        this.buildClassHeader( cw,
+                               classDef );
+
+        // Building fields
+        for ( FieldDefinition fieldDef : classDef.getFields() ) {
+            this.buildField( cw,
+                             fieldDef );
+        }
+
+        // Building default constructor
+        this.buildDefaultConstructor( cw,
+                                      classDef );
+
+        // Building methods
+        for ( FieldDefinition fieldDef : classDef.getFields() ) {
+            this.buildGetMethod( cw,
+                                 classDef,
+                                 fieldDef );
+            this.buildSetMethod( cw,
+                                 classDef,
+                                 fieldDef );
+        }
+
+        this.buildEquals( cw,
+                          classDef );
+        this.buildHashCode( cw,
+                            classDef );
+
+        this.buildToString( cw,
+                            classDef );
+
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+
+    /**
+     * Defines the class header for the given class definition
+     * 
+     * @param cw
+     * @param dimDef
+     */
+    private void buildClassHeader(ClassWriter cw,
+                                  ClassDefinition classDef) {
+        // Building class header
+        cw.visit( Opcodes.V1_4,
+                  Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
+                  classDef.getClassNameAsInternal(),
+                  null,
+                  classDef.getSuperClassAsInternal(),
+                  classDef.getInterfacesAsInternal() );
+
+        cw.visitSource( classDef.getClassName() + ".java",
+                        null );
+    }
+
+    /**
+     * Creates the field defined by the given FieldDefinition 
+     * 
+     * @param cw
+     * @param fieldDef
+     */
+    private void buildField(ClassWriter cw,
+                            FieldDefinition fieldDef) {
+        FieldVisitor fv;
+        fv = cw.visitField( Opcodes.ACC_PRIVATE,
+                            fieldDef.getName(),
+                            fieldDef.getInternalType(),
+                            null,
+                            null );
+        fv.visitEnd();
+    }
+
+    /**
+     * Creates a default constructor for the class
+     * 
+     * @param cw
+     */
+    private void buildDefaultConstructor(ClassWriter cw,
+                                         ClassDefinition classDef) {
+        MethodVisitor mv;
+        // Building default constructor
+        {
+            mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+                                 "<init>",
+                                 Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                           new Type[]{} ),
+                                 null,
+                                 null );
+            mv.visitCode();
+            Label l0 = null;
+            if ( this.debug ) {
+                l0 = new Label();
+                mv.visitLabel( l0 );
+            }
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             0 );
+            mv.visitMethodInsn( Opcodes.INVOKESPECIAL,
+                                Type.getInternalName( Object.class ),
+                                "<init>",
+                                Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                          new Type[]{} ) );
+            mv.visitInsn( Opcodes.RETURN );
+            Label l1 = null;
+            if ( this.debug ) {
+                l1 = new Label();
+                mv.visitLabel( l1 );
+                mv.visitLocalVariable( "this",
+                                       classDef.getInternalName(),
+                                       null,
+                                       l0,
+                                       l1,
+                                       0 );
+            }
+            mv.visitMaxs( 0,
+                          0 );
+            mv.visitEnd();
+        }
+    }
+
+    /**
+     * Creates the set method for the given field definition
+     * 
+     * @param cw
+     * @param classDef
+     * @param fieldDef
+     */
+    private void buildSetMethod(ClassWriter cw,
+                                ClassDefinition classDef,
+                                FieldDefinition fieldDef) {
+        MethodVisitor mv;
+        // set method
+        {
+            mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+                                 fieldDef.getWriteMethod(),
+                                 Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                           new Type[]{Type.getType( fieldDef.getInternalType() )} ),
+                                 null,
+                                 null );
+            mv.visitCode();
+            Label l0 = null;
+            if ( this.debug ) {
+                l0 = new Label();
+                mv.visitLabel( l0 );
+            }
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             0 );
+            mv.visitVarInsn( Type.getType( fieldDef.getInternalType() ).getOpcode( Opcodes.ILOAD ),
+                             1 );
+            mv.visitFieldInsn( Opcodes.PUTFIELD,
+                               classDef.getClassNameAsInternal(),
+                               fieldDef.getName(),
+                               fieldDef.getInternalType() );
+
+            mv.visitInsn( Opcodes.RETURN );
+            Label l1 = null;
+            if ( this.debug ) {
+                l1 = new Label();
+                mv.visitLabel( l1 );
+                mv.visitLocalVariable( "this",
+                                       classDef.getInternalName(),
+                                       null,
+                                       l0,
+                                       l1,
+                                       0 );
+            }
+            mv.visitMaxs( 0,
+                          0 );
+            mv.visitEnd();
+        }
+    }
+
+    /**
+     * Creates the get method for the given field definition
+     * 
+     * @param cw
+     * @param classDef
+     * @param fieldDef
+     */
+    private void buildGetMethod(ClassWriter cw,
+                                ClassDefinition classDef,
+                                FieldDefinition fieldDef) {
+        MethodVisitor mv;
+        // Get method
+        {
+            mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+                                 fieldDef.getReadMethod(),
+                                 Type.getMethodDescriptor( Type.getType( fieldDef.getInternalType() ),
+                                                           new Type[]{} ),
+                                 null,
+                                 null );
+            mv.visitCode();
+            Label l0 = null;
+            if ( this.debug ) {
+                l0 = new Label();
+                mv.visitLabel( l0 );
+            }
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             0 );
+            mv.visitFieldInsn( Opcodes.GETFIELD,
+                               classDef.getClassNameAsInternal(),
+                               fieldDef.getName(),
+                               fieldDef.getInternalType() );
+            mv.visitInsn( Type.getType( fieldDef.getInternalType() ).getOpcode( Opcodes.IRETURN ) );
+            Label l1 = null;
+            if ( this.debug ) {
+                l1 = new Label();
+                mv.visitLabel( l1 );
+                mv.visitLocalVariable( "this",
+                                       classDef.getInternalName(),
+                                       null,
+                                       l0,
+                                       l1,
+                                       0 );
+            }
+            mv.visitMaxs( 0,
+                          0 );
+            mv.visitEnd();
+        }
+    }
+
+    private void buildEquals(ClassWriter cw,
+                             ClassDefinition classDef) {
+        MethodVisitor mv;
+        // Building equals method
+        {
+            mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+                                 "equals",
+                                 "(Ljava/lang/Object;)Z",
+                                 null,
+                                 null );
+            mv.visitCode();
+            Label l0 = null;
+            if ( this.debug ) {
+                l0 = new Label();
+                mv.visitLabel( l0 );
+            }
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             0 );
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             1 );
+            Label l1 = new Label();
+            mv.visitJumpInsn( Opcodes.IF_ACMPNE,
+                              l1 );
+            mv.visitInsn( Opcodes.ICONST_1 );
+            mv.visitInsn( Opcodes.IRETURN );
+            mv.visitLabel( l1 );
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             1 );
+            Label l3 = new Label();
+            mv.visitJumpInsn( Opcodes.IFNULL,
+                              l3 );
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             1 );
+            mv.visitTypeInsn( Opcodes.INSTANCEOF,
+                              classDef.getClassNameAsInternal() );
+            Label l4 = new Label();
+            mv.visitJumpInsn( Opcodes.IFNE,
+                              l4 );
+            mv.visitLabel( l3 );
+            mv.visitInsn( Opcodes.ICONST_0 );
+            mv.visitInsn( Opcodes.IRETURN );
+            mv.visitLabel( l4 );
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             1 );
+            mv.visitTypeInsn( Opcodes.CHECKCAST,
+                              classDef.getClassNameAsInternal() );
+            mv.visitVarInsn( Opcodes.ASTORE,
+                             2 );
+
+            int count = 0;
+            for ( FieldDefinition field : classDef.getFields() ) {
+                if ( field.isKey() ) {
+                    count++;
+                    Label goNext = new Label();
+                    if ( field.isPrimitive() ) {
+                        mv.visitVarInsn( Opcodes.ALOAD,
+                                         0 );
+                        mv.visitFieldInsn( Opcodes.GETFIELD,
+                                           classDef.getClassNameAsInternal(),
+                                           field.getName(),
+                                           field.getInternalType() );
+                        mv.visitVarInsn( Opcodes.ALOAD,
+                                         2 );
+                        mv.visitFieldInsn( Opcodes.GETFIELD,
+                                           classDef.getClassNameAsInternal(),
+                                           field.getName(),
+                                           field.getInternalType() );
+                        if ( field.getType().equals( "long" ) ) {
+                            mv.visitInsn( Opcodes.LCMP );
+                            mv.visitJumpInsn( Opcodes.IFEQ,
+                                              goNext );
+                        } else if ( field.getType().equals( "double" ) ) {
+                            mv.visitInsn( Opcodes.DCMPL );
+                            mv.visitJumpInsn( Opcodes.IFEQ,
+                                              goNext );
+                        } else if ( field.getType().equals( "float" ) ) {
+                            mv.visitInsn( Opcodes.FCMPL );
+                            mv.visitJumpInsn( Opcodes.IFEQ,
+                                              goNext );
+                        } else {
+                            mv.visitJumpInsn( Opcodes.IF_ICMPEQ,
+                                              goNext );
+                        }
+                        mv.visitInsn( Opcodes.ICONST_0 );
+                        mv.visitInsn( Opcodes.IRETURN );
+                    } else {
+                        mv.visitVarInsn( Opcodes.ALOAD,
+                                         0 );
+                        mv.visitFieldInsn( Opcodes.GETFIELD,
+                                           classDef.getClassNameAsInternal(),
+                                           field.getName(),
+                                           field.getInternalType() );
+                        Label secondIfPart = new Label();
+                        mv.visitJumpInsn( Opcodes.IFNONNULL,
+                                          secondIfPart );
+                        mv.visitVarInsn( Opcodes.ALOAD,
+                                         2 );
+                        mv.visitFieldInsn( Opcodes.GETFIELD,
+                                           classDef.getClassNameAsInternal(),
+                                           field.getName(),
+                                           field.getInternalType() );
+                        Label returnFalse = new Label();
+                        mv.visitJumpInsn( Opcodes.IFNONNULL,
+                                          returnFalse );
+                        mv.visitLabel( secondIfPart );
+                        mv.visitVarInsn( Opcodes.ALOAD,
+                                         0 );
+                        mv.visitFieldInsn( Opcodes.GETFIELD,
+                                           classDef.getClassNameAsInternal(),
+                                           field.getName(),
+                                           field.getInternalType() );
+                        mv.visitJumpInsn( Opcodes.IFNULL,
+                                          goNext );
+                        mv.visitVarInsn( Opcodes.ALOAD,
+                                         0 );
+                        mv.visitFieldInsn( Opcodes.GETFIELD,
+                                           classDef.getClassNameAsInternal(),
+                                           field.getName(),
+                                           field.getInternalType() );
+                        mv.visitVarInsn( Opcodes.ALOAD,
+                                         2 );
+                        mv.visitFieldInsn( Opcodes.GETFIELD,
+                                           classDef.getClassNameAsInternal(),
+                                           field.getName(),
+                                           field.getInternalType() );
+                        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                            field.getBoxTypeName(),
+                                            "equals",
+                                            "(Ljava/lang/Object;)Z" );
+                        mv.visitJumpInsn( Opcodes.IFNE,
+                                          goNext );
+                        mv.visitLabel( returnFalse );
+                        mv.visitInsn( Opcodes.ICONST_0 );
+                        mv.visitInsn( Opcodes.IRETURN );
+                    }
+                    mv.visitLabel( goNext );
+                }
+            }
+            if ( count > 0 ) {
+                mv.visitInsn( Opcodes.ICONST_1 );
+            } else {
+                mv.visitInsn( Opcodes.ICONST_0 );
+            }
+            mv.visitInsn( Opcodes.IRETURN );
+            Label lastLabel = null;
+            if ( this.debug ) {
+                lastLabel = new Label();
+                mv.visitLabel( lastLabel );
+                mv.visitLocalVariable( "this",
+                                       classDef.getInternalName(),
+                                       null,
+                                       l0,
+                                       lastLabel,
+                                       0 );
+                mv.visitLocalVariable( "obj",
+                                       Type.getDescriptor( Object.class ),
+                                       null,
+                                       l0,
+                                       lastLabel,
+                                       1 );
+                mv.visitLocalVariable( "other",
+                                       classDef.getInternalName(),
+                                       null,
+                                       l0,
+                                       lastLabel,
+                                       2 );
+            }
+            mv.visitMaxs( 0,
+                          0 );
+            mv.visitEnd();
+        }
+    }
+
+    private void buildHashCode(ClassWriter cw,
+                               ClassDefinition classDef) {
+
+        MethodVisitor mv;
+        // Building hashCode() method
+        {
+            mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+                                 "hashCode",
+                                 "()I",
+                                 null,
+                                 null );
+            mv.visitCode();
+            Label l0 = null;
+            if ( this.debug ) {
+                l0 = new Label();
+                mv.visitLabel( l0 );
+            }
+            mv.visitInsn( Opcodes.ICONST_0 );
+            mv.visitVarInsn( Opcodes.ISTORE,
+                             1 );
+
+            for ( FieldDefinition field : classDef.getFields() ) {
+                if ( field.isKey() ) {
+                    mv.visitVarInsn( Opcodes.ILOAD,
+                                     1 );
+                    if ( field.isPrimitive() ) {
+                        mv.visitTypeInsn( Opcodes.NEW,
+                                          field.getBoxTypeName() );
+                        mv.visitInsn( Opcodes.DUP );
+                        mv.visitVarInsn( Opcodes.ALOAD,
+                                         0 );
+                        mv.visitFieldInsn( Opcodes.GETFIELD,
+                                           classDef.getClassNameAsInternal(),
+                                           field.getName(),
+                                           field.getInternalType() );
+                        mv.visitMethodInsn( Opcodes.INVOKESPECIAL,
+                                            field.getBoxTypeName(),
+                                            "<init>",
+                                            Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                                      new Type[]{Type.getType( field.getInternalType() )} ) );
+                    } else {
+                        mv.visitVarInsn( Opcodes.ALOAD,
+                                         0 );
+                        mv.visitFieldInsn( Opcodes.GETFIELD,
+                                           classDef.getClassNameAsInternal(),
+                                           field.getName(),
+                                           field.getInternalType() );
+
+                    }
+                    mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                        field.getBoxTypeName(),
+                                        "hashCode",
+                                        "()I" );
+                    mv.visitInsn( Opcodes.IADD );
+                    mv.visitVarInsn( Opcodes.ISTORE,
+                                     1 );
+                }
+            }
+            mv.visitVarInsn( Opcodes.ILOAD,
+                             1 );
+            mv.visitIntInsn( Opcodes.SIPUSH,
+                             9653 );
+            mv.visitInsn( Opcodes.IREM );
+            mv.visitInsn( Opcodes.IRETURN );
+
+            Label lastLabel = null;
+            if ( this.debug ) {
+                lastLabel = new Label();
+                mv.visitLabel( lastLabel );
+                mv.visitLocalVariable( "this",
+                                       classDef.getInternalName(),
+                                       null,
+                                       l0,
+                                       lastLabel,
+                                       0 );
+                mv.visitLocalVariable( "hash",
+                                       Type.getDescriptor( int.class ),
+                                       null,
+                                       l0,
+                                       lastLabel,
+                                       1 );
+            }
+            mv.visitMaxs( 0,
+                          0 );
+            mv.visitEnd();
+        }
+    }
+
+    private void buildToString(ClassWriter cw,
+                               ClassDefinition classDef) {
+        MethodVisitor mv;
+        {
+            mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+                                 "toString",
+                                 "()Ljava/lang/String;",
+                                 null,
+                                 null );
+            mv.visitCode();
+
+            Label l0 = null;
+            if ( this.debug ) {
+                l0 = new Label();
+                mv.visitLabel( l0 );
+            }
+
+            // StringBuffer buf = new StringBuffer();
+            mv.visitTypeInsn( Opcodes.NEW,
+                              "java/lang/StringBuffer" );
+            mv.visitInsn( Opcodes.DUP );
+            mv.visitMethodInsn( Opcodes.INVOKESPECIAL,
+                                "java/lang/StringBuffer",
+                                "<init>",
+                                "()V" );
+            mv.visitVarInsn( Opcodes.ASTORE,
+                             1 );
+
+            // buf.append(this.getClass().getSimpleName())
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             1 );
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             0 );
+            mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                classDef.getClassNameAsInternal(),
+                                "getClass",
+                                "()Ljava/lang/Class;" );
+            mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                "java/lang/Class",
+                                "getSimpleName",
+                                "()Ljava/lang/String;" );
+            mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                "java/lang/StringBuffer",
+                                "append",
+                                "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
+
+            // buf.append("( ");
+            mv.visitLdcInsn( "( " );
+            mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                "java/lang/StringBuffer",
+                                "append",
+                                "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
+
+            boolean previous = false;
+            for ( FieldDefinition field : classDef.getFields() ) {
+                if ( previous ) {
+                    // buf.append(", ");
+                    mv.visitLdcInsn( ", " );
+                    mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                        "java/lang/StringBuffer",
+                                        "append",
+                                        "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
+                }
+                // buf.append(attrName)
+                mv.visitLdcInsn( field.getName() );
+                mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                    "java/lang/StringBuffer",
+                                    "append",
+                                    "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
+
+                // buf.append("=");
+                mv.visitLdcInsn( "=" );
+                mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                    "java/lang/StringBuffer",
+                                    "append",
+                                    "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
+
+                // buf.append(attrValue)
+                mv.visitVarInsn( Opcodes.ALOAD,
+                                 0 );
+                mv.visitFieldInsn( Opcodes.GETFIELD,
+                                   classDef.getClassNameAsInternal(),
+                                   field.getName(),
+                                   field.getInternalType() );
+
+                if ( field.isPrimitive() ) {
+                    mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                        "java/lang/StringBuffer",
+                                        "append",
+                                        Type.getMethodDescriptor( Type.getType( StringBuffer.class ),
+                                                                  new Type[]{Type.getType( field.getInternalType() )} ) );
+                } else {
+                    mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                        "java/lang/StringBuffer",
+                                        "append",
+                                        Type.getMethodDescriptor( Type.getType( StringBuffer.class ),
+                                                                  new Type[]{Type.getType( Object.class )} ) );
+                }
+                previous = true;
+            }
+
+            mv.visitLdcInsn( " )" );
+            mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                "java/lang/StringBuffer",
+                                "append",
+                                "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
+            mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                "java/lang/StringBuffer",
+                                "toString",
+                                "()Ljava/lang/String;" );
+            mv.visitInsn( Opcodes.ARETURN );
+
+            Label lastLabel = null;
+            if ( this.debug ) {
+                lastLabel = new Label();
+                mv.visitLabel( lastLabel );
+                mv.visitLocalVariable( "this",
+                                       classDef.getInternalName(),
+                                       null,
+                                       l0,
+                                       lastLabel,
+                                       0 );
+                mv.visitLocalVariable( "buf",
+                                       Type.getDescriptor( StringBuffer.class ),
+                                       null,
+                                       l0,
+                                       lastLabel,
+                                       1 );
+            }
+            mv.visitMaxs( 0,
+                          0 );
+            mv.visitEnd();
+        }
+    }
+
+    private Class loadClass(String classname,
+                            byte[] b) throws ClassNotFoundException,
+                                     SecurityException,
+                                     NoSuchMethodException,
+                                     IllegalArgumentException,
+                                     IllegalAccessException,
+                                     InvocationTargetException {
+        this.classLoader.write( classname,
+                                b );
+
+        return this.classLoader.loadClass( classname );
+    }
+
+    public ClassLoader getDynamicClassesClassLoader() {
+        return this.classLoader;
+    }
+
+    public class PackageClassLoader extends ClassLoader {
+        private Map store = new HashMap();
+
+        public PackageClassLoader(final ClassLoader parentClassLoader) {
+            super( parentClassLoader );
+        }
+
+        public Class fastFindClass(final String name) {
+            Class clazz = findLoadedClass( name );
+
+            if ( clazz == null ) {
+                final byte[] clazzBytes = read( name );
+                if ( clazzBytes != null ) {
+                    java.lang.reflect.Method method = null;
+
+                    try {
+                        Class cls = Class.forName( "java.lang.ClassLoader" );
+                        method = cls.getDeclaredMethod( "defineClass",
+                                                        new Class[]{String.class, byte[].class, int.class, int.class} );
+
+                        // protected method invocaton
+                        method.setAccessible( true );
+                        Object[] args = new Object[]{name, clazzBytes, new Integer( 0 ), new Integer( clazzBytes.length )};
+                        clazz = (Class) method.invoke( this.getParent(),
+                                                       args );
+                    } catch( Exception e ) {
+                        // not possible to load the class
+                    } finally {
+                        method.setAccessible( false );
+                    }
+                }
+            }
+
+            return clazz;
+        }
+
+        /**
+         * Javadocs recommend that this method not be overloaded. We overload this so that we can prioritise the fastFindClass 
+         * over method calls to parent.loadClass(name, false); and c = findBootstrapClass0(name); which the default implementation
+         * would first - hence why we call it "fastFindClass" instead of standard findClass, this indicates that we give it a 
+         * higher priority than normal.
+         * 
+         */
+        protected synchronized Class loadClass(final String name,
+                                               final boolean resolve) throws ClassNotFoundException {
+            Class clazz = fastFindClass( name );
+
+            if ( clazz == null ) {
+                final ClassLoader parent = getParent();
+                if ( parent != null ) {
+                    clazz = parent.loadClass( name );
+                } else {
+                    throw new ClassNotFoundException( name );
+                }
+            }
+
+            if ( resolve ) {
+                resolveClass( clazz );
+            }
+
+            return clazz;
+        }
+
+        protected Class findClass(final String name) throws ClassNotFoundException {
+            final Class clazz = fastFindClass( name );
+            if ( clazz == null ) {
+                throw new ClassNotFoundException( name );
+            }
+            return clazz;
+        }
+
+        public InputStream getResourceAsStream(final String name) {
+            final byte[] bytes = (byte[]) store.get( name );
+            if ( bytes != null ) {
+                return new ByteArrayInputStream( bytes );
+            } else {
+                return super.getResourceAsStream( name );
+            }
+        }
+
+        public byte[] read(final String resourceName) {
+            final byte[] bytes = null;
+
+            if ( this.store != null ) {
+                return (byte[]) this.store.get( resourceName.replace( '.',
+                                                                      '/' ) + ".class" );
+            }
+            return bytes;
+        }
+
+        public void write(final String resourceName,
+                          final byte[] clazzData) throws RuntimeDroolsException {
+            this.store.put( resourceName.replace( '.',
+                                                  '/' ) + ".class",
+                            clazzData );
+        }
+    }
+
+}


Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassBuilder.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassDefinition.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassDefinition.java	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassDefinition.java	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,228 @@
+package com.sample;
+
+import java.beans.IntrospectionException;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Defines a class attributes and structure that will 
+ * later be dynamically generated.
+ * 
+ * @author <mailto:etirelli at redhat.com>Edson Tirelli</mailto>
+ * 
+ */
+public class ClassDefinition {
+    private String                       className;
+    private String                       superClass;
+    private String[]                     interfaces;
+    private Class                        definedClass;
+
+    private Map<String, FieldDefinition> fields = new LinkedHashMap<String, FieldDefinition>();
+
+    public ClassDefinition(String className) {
+        this( className,
+              null,
+              null );
+    }
+
+    public ClassDefinition(String className,
+                           String superClass) {
+        this( className,
+              superClass,
+              null );
+    }
+
+    public ClassDefinition(String className,
+                           String[] interfaces) {
+        this( className,
+              null,
+              interfaces );
+    }
+
+    public ClassDefinition(String className,
+                           String superClass,
+                           String[] interfaces) {
+        this.setClassName( className );
+        this.setSuperClass( superClass );
+        this.setInterfaces( interfaces );
+    }
+
+    /**
+     * @return Returns the name.
+     */
+    public final String getClassName() {
+        return this.className;
+    }
+
+    /**
+     * @param name The name to set.
+     */
+    public final void setClassName(final String className) {
+        this.className = className;
+    }
+
+    /**
+     * @return the class name replacing '.' by '/'
+     */
+    final String getClassNameAsInternal() {
+        return this.getClassName().replace( '.',
+                                            '/' );
+    }
+
+    /**
+     * @return Returns the name.
+     */
+    public final String getInternalName() {
+        return "L" + this.getClassNameAsInternal() + ";";
+    }
+
+    /**
+     * @return Returns the className.
+     */
+    public final Class getDefinedClass() {
+        return definedClass;
+    }
+
+    /**
+     * @param className The className to set.
+     * @throws IntrospectionException 
+     * @throws NoSuchFieldException 
+     * @throws InvocationTargetException 
+     * @throws NoSuchMethodException 
+     * @throws ClassNotFoundException 
+     * @throws IOException 
+     * @throws IllegalAccessException 
+     * @throws InstantiationException 
+     * @throws IllegalArgumentException 
+     * @throws SecurityException 
+     */
+    final void setDefinedClass(final Class definedClass) throws IntrospectionException,
+                                                        SecurityException,
+                                                        IllegalArgumentException,
+                                                        InstantiationException,
+                                                        IllegalAccessException,
+                                                        IOException,
+                                                        ClassNotFoundException,
+                                                        NoSuchMethodException,
+                                                        InvocationTargetException,
+                                                        NoSuchFieldException {
+
+        this.definedClass = definedClass;
+
+        if ( this.definedClass != null ) {
+            this.buildFieldAccessors();
+        }
+    }
+
+    /**
+     * Adds a field definition to this class
+     * @param attr
+     */
+    public final void addField(FieldDefinition attr) {
+        this.fields.put( attr.getName(),
+                         attr );
+    }
+
+    /**
+     * @return Returns an unmodifiable collection of field definitions
+     */
+    public final Collection<FieldDefinition> getFields() {
+        return Collections.unmodifiableCollection( this.fields.values() );
+    }
+
+    /**
+     * Returns the field definition object for the given field name
+     * 
+     * @param fieldName
+     * @return
+     */
+    public final FieldDefinition getField(final String fieldName) {
+        return this.fields.get( fieldName );
+    }
+
+    /**
+     * @param beanInfo The beanInfo to set.
+     * @throws NoSuchFieldException 
+     * @throws InvocationTargetException 
+     * @throws NoSuchMethodException 
+     * @throws ClassNotFoundException 
+     * @throws IntrospectionException 
+     * @throws IOException 
+     * @throws IllegalAccessException 
+     * @throws InstantiationException 
+     * @throws IllegalArgumentException 
+     * @throws SecurityException 
+     * @throws IntrospectionException 
+     */
+    public final void buildFieldAccessors() throws SecurityException,
+                                           IllegalArgumentException,
+                                           InstantiationException,
+                                           IllegalAccessException,
+                                           IOException,
+                                           IntrospectionException,
+                                           ClassNotFoundException,
+                                           NoSuchMethodException,
+                                           InvocationTargetException,
+                                           NoSuchFieldException {
+        FieldAccessorBuilder builder = new FieldAccessorBuilder();
+
+        for ( FieldDefinition attrDef : this.fields.values() ) {
+            FieldAccessor accessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( this.getDefinedClass(),
+                                                                                        attrDef.getName() ).newInstance();
+            attrDef.setFieldAccessor( accessor );
+        }
+    }
+
+    /**
+     * @return Returns the interfaces.
+     */
+    public final String[] getInterfaces() {
+        return interfaces;
+    }
+
+    /**
+     * @param interfaces The interfaces to set.
+     */
+    public final void setInterfaces(String[] interfaces) {
+        this.interfaces = (interfaces != null) ? interfaces : new String[0];
+    }
+
+    /**
+     * @return
+     */
+    final String[] getInterfacesAsInternal() {
+        String[] interfaces = new String[this.interfaces.length];
+        for ( int i = 0; i < interfaces.length; i++ ) {
+            interfaces[i] = this.interfaces[i].replace( '.',
+                                                        '/' );
+        }
+        return interfaces;
+    }
+
+    /**
+     * @return Returns the superClass.
+     */
+    public final String getSuperClass() {
+        return superClass;
+    }
+
+    /**
+     * @param superClass The superClass to set.
+     */
+    public final void setSuperClass(final String superClass) {
+        this.superClass = (superClass != null) ? superClass : "java/lang/Object";
+    }
+
+    /**
+     * @return Returns superclass name in the internal String representation
+     */
+    final String getSuperClassAsInternal() {
+        return this.superClass.replace( '.',
+                                        '/' );
+    }
+
+}
\ No newline at end of file


Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassDefinition.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/Customer.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/Customer.java	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/Customer.java	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */ 
+package com.sample;
+
+import java.io.Serializable;
+
+
+public class Customer
+     implements Serializable
+{
+
+    private static final long serialVersionUID = 1L;
+
+    long    id;
+
+	String 	name;
+    Integer region;
+    Integer age;
+    Long    income;
+
+    public Customer() {
+    }
+    
+    public Customer(int id, String name, Integer region, Integer age, Long income) {
+        this.id = id;
+    	this.name = name;
+    	this.region = region;
+    	this.age = age;
+    	this.income = income;
+    }
+
+    public String getName() {
+        return name;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getRegion() {
+        return region;
+    }
+    public void setRegion(Integer region) {
+        this.region = region;
+    }
+ 
+    public Integer getAge() {
+        return age;
+    }
+    public void setAge(Integer age) {
+        this.age = age;
+    }
+
+    public Long getIncome() {
+        return income;
+    }
+    public void setIncome(Long income) {
+        this.income = income;
+    }
+
+    public int hashCode() {
+        final int PRIME = 31;
+        int result = 1;
+        result = PRIME * result + (int) (id ^ (id >>> 32));
+        return result;
+    }
+
+    public boolean equals(Object obj) {
+        if ( this == obj ) return true;
+        if ( obj == null ) return false;
+        if ( getClass() != obj.getClass() ) return false;
+        final Customer other = (Customer) obj;
+        if ( id != other.id ) return false;
+        return true;
+    }
+
+}


Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/Customer.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/DroolsTest.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/DroolsTest.java	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/DroolsTest.java	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,162 @@
+package com.sample;
+
+import java.beans.IntrospectionException;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.WorkingMemory;
+import org.drools.compiler.PackageBuilder;
+import org.drools.reteoo.ReteooRuleBase;
+import org.drools.rule.Package;
+
+/**
+ * This is a sample file to launch a rule package from a rule source file.
+ */
+public class DroolsTest {
+
+    public static final void main(String[] args) {
+        try {
+            ClassBuilder builder = new ClassBuilder();
+            Thread.currentThread().setContextClassLoader( builder.getDynamicClassesClassLoader() );
+            Package pkg = new Package( "com.jbpm.action" );
+            PackageBuilder pkgBuilder = new PackageBuilder( pkg );
+            // Defining OrderLine
+            ClassDefinition lineitemClassDef = new ClassDefinition( "com.sample.LineItem" );
+            FieldDefinition lineId = new FieldDefinition( "lineId",
+                                                          "int" );
+            lineId.setKey( true );
+            FieldDefinition product = new FieldDefinition( "product",
+                                                           "java.lang.String" );
+            FieldDefinition amount = new FieldDefinition( "amount",
+                                                          "double" );
+            FieldDefinition processed = new FieldDefinition( "processed",
+                                                             "boolean" );
+            lineitemClassDef.addField( lineId );
+            lineitemClassDef.addField( product );
+            lineitemClassDef.addField( amount );
+            lineitemClassDef.addField( processed );
+            Class lineItemClass = defineAndLoadClass( pkgBuilder,
+                                                      lineitemClassDef,
+                                                      builder );
+            // Defining the class 
+            ClassDefinition classdef = new ClassDefinition( "com.sample.Order" );
+            FieldDefinition orderId = new FieldDefinition( "orderId",
+                                                           "int" );
+            orderId.setKey( true );
+            FieldDefinition customer = new FieldDefinition( "customer",
+                                                            "com.sample.Customer" );
+            FieldDefinition lineItems = new FieldDefinition( "lineItems",
+                                                             "java.util.List" );
+            FieldDefinition totalAmount = new FieldDefinition( "totalAmount",
+                                                               "double" );
+            classdef.addField( orderId );
+            classdef.addField( customer );
+            classdef.addField( lineItems );
+            classdef.addField( totalAmount );
+            Class orderClass = defineAndLoadClass( pkgBuilder,
+                                                   classdef,
+                                                   builder );
+            //load up the rulebase
+            ReteooRuleBase ruleBase = (ReteooRuleBase) readRule( pkgBuilder );
+            WorkingMemory workingMemory = ruleBase.newWorkingMemory();
+            Object line1 = lineItemClass.newInstance();
+            lineId.setValue( line1,
+                             1 );
+            product.setValue( line1,
+                              "cheese" );
+            amount.setValue( line1,
+                             25.10 );
+            Object line2 = lineItemClass.newInstance();
+            lineId.setValue( line2,
+                             2 );
+            product.setValue( line2,
+                              "chocolate" );
+            amount.setValue( line2,
+                             12.50 );
+            List items = new ArrayList();
+            items.add( line1 );
+            items.add( line2 );
+            Customer cust = new Customer( 1,
+                                          "Fred",
+                                          new Integer( 5 ),
+                                          new Integer( 25 ),
+                                          new Long( 100000 ) );
+            // Instantiating the class
+            Object order = orderClass.newInstance();
+            orderId.setValue( order,
+                              10 );
+            customer.setValue( order,
+                               cust );
+            lineItems.setValue( order,
+                                items );
+            workingMemory.assertObject( order );
+            workingMemory.assertObject( cust );
+            workingMemory.assertObject( line1 );
+            workingMemory.assertObject( line2 );
+            workingMemory.fireAllRules();
+        } catch ( Exception e ) {
+            e.printStackTrace();
+        }        
+
+    }
+
+    /**
+     * @param classdef
+     * @param builder
+     * @return
+     * @throws IOException
+     * @throws IntrospectionException
+     * @throws ClassNotFoundException
+     * @throws NoSuchMethodException
+     * @throws IllegalAccessException
+     * @throws InvocationTargetException
+     * @throws InstantiationException
+     * @throws NoSuchFieldException
+     * @throws FileNotFoundException
+     */
+    private static Class defineAndLoadClass(PackageBuilder pkgBuilder,
+                                            ClassDefinition classdef,
+                                            ClassBuilder builder) throws IOException,
+                                                                 IntrospectionException,
+                                                                 ClassNotFoundException,
+                                                                 NoSuchMethodException,
+                                                                 IllegalAccessException,
+                                                                 InvocationTargetException,
+                                                                 InstantiationException,
+                                                                 NoSuchFieldException,
+                                                                 FileNotFoundException {
+        //        FileOutputStream fos = new FileOutputStream( "generated/"+ classdef.getClassNameAsInternal()+".class" );
+        //        fos.write( generatedClass );
+        //        fos.close();
+
+        // loading the class
+        Class orderClass = builder.buildAndLoadClass( classdef );
+        orderClass.getMethods();
+        return orderClass;
+    }
+
+    /**
+     * Please note that this is the "low level" rule assembly API.
+     */
+    private static RuleBase readRule(PackageBuilder builder) throws Exception {
+        //read in the source
+        Reader source = new InputStreamReader( DroolsTest.class.getResourceAsStream( "/Shipper.drl" ) );
+
+        builder.addPackageFromDrl( source );
+
+        Package pkg = builder.getPackage();
+
+        //add the package to a rulebase (deploy the rule package).
+        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+        ruleBase.addPackage( pkg );
+        return ruleBase;
+    }
+
+}


Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/DroolsTest.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessor.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessor.java	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessor.java	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,26 @@
+package com.sample;
+
+/**
+ * An interface for dynamically generated FieldAccessor classes </p>
+ *
+ * @author etirelli
+ */
+public interface FieldAccessor {
+    
+    /**
+     * Sets the attribute value in the given instance
+     * 
+     * @param instance
+     * @param value
+     */
+    public void setValue(Object instance, Object value);
+    
+    /**
+     * Gets the attribute value in the given instance
+     * 
+     * @param instance
+     * @return
+     */
+    public Object getValue(Object instance);
+
+}


Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessor.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessorBuilder.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessorBuilder.java	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessorBuilder.java	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,406 @@
+package com.sample;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A builder for FieldAccessor instances
+ * 
+ * @author <mailto:etirelli at redhat.com>Edson Tirelli</mailto>
+ * 
+ */
+public class FieldAccessorBuilder {
+    private Map typeMap = null;
+
+    public FieldAccessorBuilder() {
+        typeMap = new HashMap();
+        typeMap.put( Boolean.TYPE,
+                     Boolean.class );
+        typeMap.put( Byte.TYPE,
+                     Byte.class );
+        typeMap.put( Character.TYPE,
+                     Character.class );
+        typeMap.put( Double.TYPE,
+                     Double.class );
+        typeMap.put( Float.TYPE,
+                     Float.class );
+        typeMap.put( Integer.TYPE,
+                     Integer.class );
+        typeMap.put( Long.TYPE,
+                     Long.class );
+        typeMap.put( Short.TYPE,
+                     Short.class );
+        typeMap.put( Void.TYPE,
+                     Void.class );
+    }
+
+    public Class buildAndLoadFieldAccessor(Class clazz,
+                                           String fieldName) throws SecurityException,
+                                                            IllegalArgumentException,
+                                                            IOException,
+                                                            IntrospectionException,
+                                                            ClassNotFoundException,
+                                                            NoSuchMethodException,
+                                                            IllegalAccessException,
+                                                            InvocationTargetException,
+                                                            NoSuchFieldException {
+        
+        ClassDefinition accClass = new ClassDefinition( clazz.getName() + fieldName.substring( 0,
+                                                                                               1 ).toUpperCase() + fieldName.substring( 1 ) + "FA" );
+        try {
+            return Class.forName( accClass.getClassName() );
+        } catch ( ClassNotFoundException e ) {
+            byte[] serializedClazz = this.buildFieldAccessor( clazz,
+                                                              fieldName );
+            Class newClazz = this.loadClass( accClass.getClassName(),
+                                             serializedClazz );
+            return newClazz;
+        }
+    }
+
+    /**
+     * Dinamically builds, defines and loads a field accessor class for the given field
+     *  
+     * @param class the class to build the field accessor for
+     * @param fieldName the name of the field to build the field accessor for
+     * 
+     * @return the Class instance for the given class definition
+     * 
+     * @throws IOException
+     * @throws IntrospectionException 
+     * @throws InvocationTargetException 
+     * @throws IllegalAccessException 
+     * @throws NoSuchMethodException 
+     * @throws ClassNotFoundException 
+     * @throws IllegalArgumentException 
+     * @throws SecurityException 
+     * @throws NoSuchFieldException 
+     */
+    public byte[] buildFieldAccessor(Class clazz,
+                                     String fieldName) throws IOException,
+                                                      IntrospectionException,
+                                                      SecurityException,
+                                                      IllegalArgumentException,
+                                                      ClassNotFoundException,
+                                                      NoSuchMethodException,
+                                                      IllegalAccessException,
+                                                      InvocationTargetException,
+                                                      NoSuchFieldException {
+
+        ClassDefinition accClass = new ClassDefinition( clazz.getName() + fieldName.substring( 0,
+                                                                                               1 ).toUpperCase() + fieldName.substring( 1 ) + "FA" );
+        accClass.setInterfaces( new String[]{FieldAccessor.class.getName()} );
+        accClass.setSuperClass( Object.class.getName() );
+
+        PropertyDescriptor field = getPropertyDescriptor( clazz,
+                                                          fieldName );
+
+        ClassWriter cw = new ClassWriter( ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES );
+
+        this.buildClassHeader( cw,
+                               accClass );
+
+        // Building default constructor
+        this.buildDefaultConstructor( cw );
+
+        // Building methods
+        this.buildGetMethod( cw,
+                             accClass,
+                             clazz,
+                             field );
+        this.buildSetMethod( cw,
+                             accClass,
+                             clazz,
+                             field );
+
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+
+    /**
+     * @param clazz
+     * @param fieldName
+     * @param field
+     * @return
+     * @throws IntrospectionException
+     * @throws NoSuchFieldException
+     */
+    private PropertyDescriptor getPropertyDescriptor(Class clazz,
+                                                     String fieldName) throws IntrospectionException,
+                                                                      NoSuchFieldException {
+        PropertyDescriptor field = null;
+        PropertyDescriptor[] propDescr = Introspector.getBeanInfo( clazz ).getPropertyDescriptors();
+        for ( int i = 0; i < propDescr.length; i++ ) {
+            if ( fieldName.equals( propDescr[i].getName() ) ) {
+                field = propDescr[i];
+                break;
+            }
+        }
+        if ( field == null ) {
+            throw new NoSuchFieldException( "Field [" + fieldName + "] not found in class [" + clazz.getName() + "]" );
+        }
+        return field;
+    }
+
+    /**
+     * Defines the class header for the given class definition
+     * 
+     * @param cw
+     * @param dimDef
+     */
+    private void buildClassHeader(ClassWriter cw,
+                                  ClassDefinition classDef) {
+        // Building class header
+        cw.visit( Opcodes.V1_4,
+                  Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
+                  classDef.getClassNameAsInternal(),
+                  null,
+                  classDef.getSuperClassAsInternal(),
+                  classDef.getInterfacesAsInternal() );
+
+        cw.visitSource( classDef.getClassName() + ".java",
+                        null );
+    }
+
+    /**
+     * Creates the get method for the given field definition
+     * 
+     * @param cw
+     * @param classDef
+     * @param fieldDef
+     */
+    private void buildGetMethod(ClassWriter cw,
+                                ClassDefinition classDef,
+                                Class clazz,
+                                PropertyDescriptor field) {
+        MethodVisitor mv;
+        // Get method
+        {
+            mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+                                 "getValue",
+                                 Type.getMethodDescriptor( Type.getType( Object.class ),
+                                                           new Type[]{Type.getType( Object.class )} ),
+                                 null,
+                                 null );
+            mv.visitCode();
+            if ( field.getPropertyType().isPrimitive() ) {
+                mv.visitTypeInsn( Opcodes.NEW,
+                                  Type.getInternalName( (Class) typeMap.get( field.getPropertyType() ) ) );
+                mv.visitInsn( Opcodes.DUP );
+            }
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             1 );
+            mv.visitTypeInsn( Opcodes.CHECKCAST,
+                              Type.getInternalName( clazz ) );
+            mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                Type.getInternalName( clazz ),
+                                field.getReadMethod().getName(),
+                                Type.getMethodDescriptor( Type.getType( field.getPropertyType() ),
+                                                          new Type[]{} ) );
+
+            if ( field.getPropertyType().isPrimitive() ) {
+                mv.visitMethodInsn( Opcodes.INVOKESPECIAL,
+                                    Type.getInternalName( (Class) typeMap.get( field.getPropertyType() ) ),
+                                    "<init>",
+                                    Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                              new Type[]{Type.getType( field.getPropertyType() )} ) );
+            }
+            mv.visitInsn( Opcodes.ARETURN );
+            mv.visitMaxs( 0,
+                          0 ); // automatically calculated
+            mv.visitEnd();
+        }
+    }
+
+    /**
+     * Creates the set method for the given field definition
+     * 
+     * @param cw
+     * @param classDef
+     * @param fieldDef
+     */
+    private void buildSetMethod(ClassWriter cw,
+                                ClassDefinition classDef,
+                                Class clazz,
+                                PropertyDescriptor field) {
+        MethodVisitor mv;
+        // set method
+        {
+            mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+                                 "setValue",
+                                 Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                           new Type[]{Type.getType( Object.class ), Type.getType( Object.class )} ),
+                                 null,
+                                 null );
+
+            mv.visitCode();
+
+            if ( field.getPropertyType().isPrimitive() ) {
+                // value != null ?
+                mv.visitVarInsn( Opcodes.ALOAD,
+                                 2 );
+
+                Label ifnull = new Label();
+                mv.visitJumpInsn( Opcodes.IFNULL,
+                                  ifnull );
+
+                // ((PrimitiveWrapper)value).xxxValue() :
+                mv.visitVarInsn( Opcodes.ALOAD,
+                                 2 );
+                mv.visitTypeInsn( Opcodes.CHECKCAST,
+                                  Type.getInternalName( (Class) typeMap.get( field.getPropertyType() ) ) );
+                mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                    Type.getInternalName( (Class) typeMap.get( field.getPropertyType() ) ),
+                                    field.getPropertyType().getName() + "Value",
+                                    Type.getMethodDescriptor( Type.getType( field.getPropertyType() ),
+                                                              new Type[]{} ) );
+
+                Label afterif = new Label();
+                mv.visitJumpInsn( Opcodes.GOTO,
+                                  afterif );
+
+                // 0
+                mv.visitLabel( ifnull );
+                if ( field.getPropertyType().isAssignableFrom( long.class ) ) {
+                    mv.visitInsn( Opcodes.LCONST_0 );
+                } else if ( field.getPropertyType().isAssignableFrom( double.class ) ) {
+                    mv.visitInsn( Opcodes.DCONST_0 );
+                } else if ( field.getPropertyType().isAssignableFrom( float.class ) ) {
+                    mv.visitInsn( Opcodes.FCONST_0 );
+                } else {
+                    mv.visitInsn( Opcodes.ICONST_0 );
+                }
+
+                // localVar = pop()
+                mv.visitLabel( afterif );
+                mv.visitVarInsn( Type.getType( field.getPropertyType() ).getOpcode( Opcodes.ISTORE ),
+                                 3 );
+            } else {
+                // localVar = (xxxClass) value 
+                mv.visitVarInsn( Opcodes.ALOAD,
+                                 2 );
+                mv.visitTypeInsn( Opcodes.CHECKCAST,
+                                  Type.getInternalName( field.getPropertyType() ) );
+                mv.visitVarInsn( Opcodes.ASTORE,
+                                 3 );
+            }
+
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             1 );
+            mv.visitTypeInsn( Opcodes.CHECKCAST,
+                              Type.getInternalName( clazz ) );
+            mv.visitVarInsn( Type.getType( field.getPropertyType() ).getOpcode( Opcodes.ILOAD ),
+                             3 );
+
+            mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                                Type.getInternalName( clazz ),
+                                field.getWriteMethod().getName(),
+                                Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                          new Type[]{Type.getType( field.getPropertyType() )} ) );
+
+            mv.visitInsn( Opcodes.RETURN );
+            mv.visitMaxs( 0,
+                          0 ); // auto calculated
+            mv.visitEnd();
+        }
+    }
+
+    /**
+     * Creates a default constructor for the class
+     * 
+     * @param cw
+     */
+    private void buildDefaultConstructor(ClassWriter cw) {
+        MethodVisitor mv;
+        // Building default constructor
+        {
+            mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+                                 "<init>",
+                                 Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                           new Type[]{} ),
+                                 null,
+                                 null );
+            mv.visitCode();
+            mv.visitVarInsn( Opcodes.ALOAD,
+                             0 );
+            mv.visitMethodInsn( Opcodes.INVOKESPECIAL,
+                                Type.getInternalName( Object.class ),
+                                "<init>",
+                                Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                          new Type[]{} ) );
+            mv.visitInsn( Opcodes.RETURN );
+            mv.visitMaxs( 0,
+                          0 );
+            mv.visitEnd();
+        }
+    }
+
+    private Class loadClass(String classname,
+                            byte[] b) throws ClassNotFoundException,
+                                     SecurityException,
+                                     NoSuchMethodException,
+                                     IllegalArgumentException,
+                                     IllegalAccessException,
+                                     InvocationTargetException {
+        //override classDefine (as it is protected) and define the class.
+        Class clazz = null;
+        ClassLoader loader = FieldAccessorBuilder.class.getClassLoader();
+        Class cls = Class.forName( "java.lang.ClassLoader" );
+        java.lang.reflect.Method method = cls.getDeclaredMethod( "defineClass",
+                                                                 new Class[]{String.class, byte[].class, int.class, int.class} );
+
+        // protected method invocaton
+        method.setAccessible( true );
+        try {
+            Object[] args = new Object[]{classname, b, new Integer( 0 ), new Integer( b.length )};
+            clazz = (Class) method.invoke( loader,
+                                           args );
+        } finally {
+            method.setAccessible( false );
+        }
+        return clazz;
+    }
+
+    /**
+     * Creates the String name for the get method for a field with the given name and type
+     * @param name
+     * @param type
+     * @return
+     */
+    public String getReadMethod(Field field) {
+        String prefix = null;
+        if ( Boolean.TYPE.equals( field.getType() ) ) {
+            prefix = "is";
+        } else {
+            prefix = "get";
+        }
+        return prefix + field.getName().substring( 0,
+                                                   1 ).toUpperCase() + field.getName().substring( 1 );
+    }
+
+    /**
+     * Creates the String name for the set method for a field with the given name and type
+     * 
+     * @param name
+     * @param type
+     * @return
+     */
+    public String getWriteMethod(Field field) {
+        return "set" + field.getName().substring( 0,
+                                                  1 ).toUpperCase() + field.getName().substring( 1 );
+    }
+
+}


Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessorBuilder.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldDefinition.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldDefinition.java	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldDefinition.java	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,279 @@
+package com.sample;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Declares a field that will later be added to a dynamically
+ * generated class.
+ *
+ * @author <mailto:etirelli at redhat.com>Edson Tirelli</mailto>
+ * 
+ */
+public class FieldDefinition {
+    private String             name         = null;
+    private String             type         = null;
+    private boolean            key          = false;
+    
+    private String             internalType = null;
+    private String             boxTypeName  = null;
+    private boolean            primitive    = false;
+    private String             unboxMethod  = null;
+    private FieldAccessor      accessor     = null;
+
+    /**
+     * Default constructor
+     * 
+     * @param name the field's name
+     * @param type the fully qualified fields type
+     */
+    public FieldDefinition(String name,
+                           String type) {
+        this(name, type, false);
+    }
+
+    /**
+     * Default constructor
+     * 
+     * @param name the field's name
+     * @param type the fully qualified fields type
+     */
+    public FieldDefinition(String name,
+                           String type, 
+                           boolean key) {
+        this.name = name;
+        this.type = type;
+        this.key  = key;
+        this.setInternals();
+    }
+
+    /**
+     * @return Returns the name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets the name of the field
+     * @param name The name to be set.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return Returns the fully qualified type.
+     */
+    public String getType() {
+        return this.type;
+    }
+
+    /**
+     * @param type The fully qualified type to set.
+     */
+    public void setType(String type) {
+        this.type = type;
+        this.setInternals();
+    }
+
+    /**
+     * @return Returns the fully qualified internal type representation
+     */
+    String getInternalType() {
+        return this.internalType;
+    }
+
+    String getBoxTypeName() {
+        return this.boxTypeName;
+    }
+
+    /**
+     * @return Returns the primitive.
+     */
+    boolean isPrimitive() {
+        return primitive;
+    }
+
+    /**
+     * @return Returns the unboxMethod.
+     */
+    String getUnboxMethod() {
+        return unboxMethod;
+    }
+
+    /**
+     * @return Returns the key.
+     */
+    public boolean isKey() {
+        return key;
+    }
+
+    /**
+     * If set to true, this field will be used as part of the 
+     * primary key for the created class. It means, it will
+     * be included in the equals()/hashcode() verification
+     * 
+     * @param key The key to set.
+     */
+    public void setKey(boolean key) {
+        this.key = key;
+    }
+
+    /**
+     * Creates the String name for the get method for a field with the given name and type
+     * @param name
+     * @param type
+     * @return
+     */
+    public String getReadMethod() {
+        String prefix = null;
+        if ( "boolean".equals( this.type ) ) {
+            prefix = "is";
+        } else {
+            prefix = "get";
+        }
+        return prefix + this.name.substring( 0,
+                                             1 ).toUpperCase() + this.name.substring( 1 );
+    }
+
+    /**
+     * Creates the String name for the set method for a field with the given name and type
+     * 
+     * @param name
+     * @param type
+     * @return
+     */
+    public String getWriteMethod() {
+        return "set" + this.name.substring( 0,
+                                            1 ).toUpperCase() + this.name.substring( 1 );
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public boolean equals(Object o) {
+        return this.getName().equals( ((FieldDefinition) o).getName() );
+    }
+
+    /**
+     * @return Returns the field accessor
+     */
+    FieldAccessor getFieldAccessor() {
+        return this.accessor;
+    }
+
+    /**
+     * @param property The property descriptor to set.
+     */
+    void setFieldAccessor(FieldAccessor accessor) {
+        this.accessor = accessor;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public int hashCode() {
+        return this.getName().hashCode();
+    }
+
+    /**
+     * Sets the value of this attribute in the target
+     * bean instance
+     * 
+     * @param bean the target bean instance where the attribute shall be set
+     * @param value the value to set the attribute to
+     * 
+     * @throws IllegalArgumentException
+     * @throws IllegalAccessException
+     * @throws InvocationTargetException
+     */
+    public void setValue(Object bean,
+                         Object value) throws IllegalArgumentException,
+                                      IllegalAccessException,
+                                      InvocationTargetException {
+        if(this.accessor == null) {
+            System.out.println("ACCESSOR NULL");
+        }
+        this.accessor.setValue( bean, value );
+    }
+
+    /**
+     * Returns the value of this attribute in the target bean instance
+     * 
+     * @param bean the target bean instance
+     * 
+     * @return target bean instance attribute value
+     *  
+     * @throws IllegalArgumentException
+     * @throws IllegalAccessException
+     * @throws InvocationTargetException
+     */
+    public Object getValue(Object bean) throws IllegalArgumentException,
+                                       IllegalAccessException,
+                                       InvocationTargetException {
+        return this.accessor.getValue( bean );
+    }
+
+    /**
+     * Creates the internal string representation of this attribute's type
+     * 
+     * @param type
+     * @return
+     */
+    private void setInternals() {
+        if ( "byte".equals( this.type ) ) {
+            this.internalType = "B";
+            this.boxTypeName = "java/lang/Byte";
+            this.primitive = true;
+            this.unboxMethod = "byteValue";
+        } else if ( "char".equals( type ) ) {
+            this.internalType = "C";
+            this.boxTypeName = "java/lang/Character";
+            this.primitive = true;
+            this.unboxMethod = "charValue";
+        } else if ( "double".equals( type ) ) {
+            this.internalType = "D";
+            this.boxTypeName = "java/lang/Double";
+            this.primitive = true;
+            this.unboxMethod = "doubleValue";
+        } else if ( "float".equals( type ) ) {
+            this.internalType = "F";
+            this.boxTypeName = "java/lang/Float";
+            this.primitive = true;
+            this.unboxMethod = "floatValue";
+        } else if ( "int".equals( type ) ) {
+            this.internalType = "I";
+            this.boxTypeName = "java/lang/Integer";
+            this.primitive = true;
+            this.unboxMethod = "intValue";
+        } else if ( "long".equals( type ) ) {
+            this.internalType = "J";
+            this.boxTypeName = "java/lang/Long";
+            this.primitive = true;
+            this.unboxMethod = "longValue";
+        } else if ( "short".equals( type ) ) {
+            this.internalType = "S";
+            this.boxTypeName = "java/lang/Short";
+            this.primitive = true;
+            this.unboxMethod = "shortValue";
+        } else if ( "boolean".equals( type ) ) {
+            this.internalType = "Z";
+            this.boxTypeName = "java/lang/Boolean";
+            this.primitive = true;
+            this.unboxMethod = "booleanValue";
+        } else if ( "void".equals( type ) ) {
+            this.internalType = "V";
+            this.boxTypeName = "java/lang/Void";
+            this.primitive = true;
+            this.unboxMethod = null;
+        } else if ( type != null ) {
+            this.internalType = "L" + type.replace( '.',
+                                                    '/' ) + ";";
+            this.boxTypeName = type.replace( '.',
+                                             '/' );
+            this.primitive = false;
+            this.unboxMethod = null;
+        }
+    }
+
+}
\ No newline at end of file


Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldDefinition.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/contrib/dynamic/src/rules/Shipper.drl
===================================================================
--- labs/jbossrules/contrib/dynamic/src/rules/Shipper.drl	2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/rules/Shipper.drl	2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,45 @@
+package com.jbpm.action
+ 
+import com.sample.Customer;
+import com.sample.Order;
+import com.sample.LineItem;
+
+rule "Total order"
+    salience 10 
+    when
+        $item : LineItem( $amount : amount, processed == false );
+        $order: Order( lineItems contains $item )
+    then
+        System.out.println("Adding "+$item.getAmount()+" to the total amount");
+        $order.setTotalAmount( $order.getTotalAmount() + $item.getAmount() );
+        $item.setProcessed( true );
+        modify( $order );
+        modify( $item );
+end
+        
+rule "Show total"
+    salience 5
+    when
+        $order: Order( )
+    then
+        System.out.println("Total: "+$order.getTotalAmount());
+end
+        
+
+rule "Shipper FEDX"
+	when
+		$cust  : Customer( region >= 1 )
+		$order : Order( customer == $cust, totalAmount > 30 )
+	then
+		System.out.println("TotalAmount: "+$order.getTotalAmount()+" -> ship via FEDX " );
+		
+end
+
+rule "Shipper USPS"
+	when
+		$cust  : Customer( region >= 1 )
+		$order : Order( customer == $cust, totalAmount <= 30 )
+	then
+		System.out.println("TotalAmount: "+$order.getTotalAmount()+" -> ship via USPS" );
+		
+end


Property changes on: labs/jbossrules/contrib/dynamic/src/rules/Shipper.drl
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:eol-style
   + native




More information about the jboss-svn-commits mailing list