[jboss-svn-commits] JBL Code SVN: r19693 - in labs/jbossrules/trunk/drools-core/src: main/java/org/drools/factmodel and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Apr 23 00:32:45 EDT 2008


Author: michael.neale at jboss.com
Date: 2008-04-23 00:32:45 -0400 (Wed, 23 Apr 2008)
New Revision: 19693

Added:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/ClassBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/ClassDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/Fact.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/Field.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldAccessor.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldAccessorBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/Jenerator.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/ClassBuilderTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/FieldAccessorBuilderTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/InstancesHashcodedTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/JeneratorTest.java
Log:
JBRULES-1573 poor mans ontology

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/ClassBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/ClassBuilder.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/ClassBuilder.java	2008-04-23 04:32:45 UTC (rev 19693)
@@ -0,0 +1,753 @@
+package org.drools.factmodel;
+
+
+import java.beans.IntrospectionException;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+
+import org.drools.asm.ClassWriter;
+import org.drools.asm.FieldVisitor;
+import org.drools.asm.Label;
+import org.drools.asm.MethodVisitor;
+import org.drools.asm.Opcodes;
+import org.drools.asm.Type;
+
+/**
+ * <p><b>Title:</b> ClassBuilder</p>
+ * <p><b>Description:</b> A builder to dinamically build simple Value Object classes</p>
+ * <p><b>Copyright:</b> Copyright (c) 2005</p>
+ * <p><b>Company:</b> Auster Solutions</p>
+ *
+ * @author etirelli
+ * @version $Id: ClassBuilder.java 241 2006-05-11 19:48:25Z framos $
+ */
+public class ClassBuilder {
+    private boolean debug = false;
+
+    public ClassBuilder() {
+        this.debug = "false".equalsIgnoreCase( System.getProperty( "br.com.auster.common.asm.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( true );
+
+        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 {
+        //override classDefine (as it is protected) and define the class.
+        Class clazz = null;
+        ClassLoader loader = ClassBuilder.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;
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/ClassBuilder.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/ClassDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/ClassDefinition.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/ClassDefinition.java	2008-04-23 04:32:45 UTC (rev 19693)
@@ -0,0 +1,231 @@
+package org.drools.factmodel;
+
+
+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;
+
+/**
+ * <p><b>Title:</b> ClassDefinition</p>
+ * <p><b>Description:</b> Declares a class to be dinamically created</p>
+ * <p><b>Copyright:</b> Copyright (c) 2004-2006</p>
+ * <p><b>Company:</b> Auster Solutions</p>
+ *
+ * @author etirelli
+ * @version $Id: ClassDefinition.java 216 2006-03-24 19:16:31Z etirelli $
+ */
+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/trunk/drools-core/src/main/java/org/drools/factmodel/ClassDefinition.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/Fact.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/Fact.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/Fact.java	2008-04-23 04:32:45 UTC (rev 19693)
@@ -0,0 +1,17 @@
+package org.drools.factmodel;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A temporary AST.
+ * @author michaelneale
+ *
+ */
+public class Fact {
+
+	public String name;
+	public List fields = new ArrayList();
+
+}


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

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/Field.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/Field.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/Field.java	2008-04-23 04:32:45 UTC (rev 19693)
@@ -0,0 +1,14 @@
+package org.drools.factmodel;
+
+
+/**
+ * A temporary AST
+ * @author michaelneale
+ *
+ */
+public class Field {
+
+	public String name;
+	public String type;
+
+}


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

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldAccessor.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldAccessor.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldAccessor.java	2008-04-23 04:32:45 UTC (rev 19693)
@@ -0,0 +1,19 @@
+package org.drools.factmodel;
+
+
+/**
+ * <p><b>Title:</b> FieldAccessor</p>
+ * <p><b>Description:</b> An interface for dynamic generated FieldAccessor classes </p>
+ * <p><b>Copyright:</b> Copyright (c) 2004-2006</p>
+ * <p><b>Company:</b> Auster Solutions</p>
+ *
+ * @author etirelli
+ * @version $Id: FieldAccessor.java 203 2006-03-20 21:44:48Z etirelli $
+ */
+public interface FieldAccessor {
+    
+    public void setValue(Object instance, Object value);
+    
+    public Object getValue(Object instance);
+
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldAccessor.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldAccessorBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldAccessorBuilder.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldAccessorBuilder.java	2008-04-23 04:32:45 UTC (rev 19693)
@@ -0,0 +1,410 @@
+package org.drools.factmodel;
+
+
+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.drools.asm.ClassWriter;
+import org.drools.asm.Label;
+import org.drools.asm.MethodVisitor;
+import org.drools.asm.Opcodes;
+import org.drools.asm.Type;
+
+/**
+ * <p><b>Title:</b> FieldAccessorBuilder</p>
+ * <p><b>Description:</b> A builder for FieldAccessor instances</p>
+ * <p><b>Copyright:</b> Copyright (c) 2004-2006</p>
+ * <p><b>Company:</b> Auster Solutions</p>
+ *
+ * @author etirelli
+ * @version $Id: FieldAccessorBuilder.java 241 2006-05-11 19:48:25Z framos $
+ */
+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( true );
+
+        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 = ClassBuilder.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/trunk/drools-core/src/main/java/org/drools/factmodel/FieldAccessorBuilder.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldDefinition.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/FieldDefinition.java	2008-04-23 04:32:45 UTC (rev 19693)
@@ -0,0 +1,277 @@
+package org.drools.factmodel;
+
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * <p><b>Title:</b> FieldDefinition</p>
+ * <p><b>Description:</b> Declares a field to be dynamically generated</p>
+ * <p><b>Copyright:</b> Copyright (c) 2004-2006</p>
+ * <p><b>Company:</b> Auster Solutions</p>
+ *
+ * @author etirelli
+ * @version $Id: FieldDefinition.java 205 2006-03-21 18:27:52Z etirelli $
+ */
+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;
+    }
+
+    /**
+     * @param name The name to 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;
+    }
+
+    /**
+     * @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/trunk/drools-core/src/main/java/org/drools/factmodel/FieldDefinition.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/Jenerator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/Jenerator.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/factmodel/Jenerator.java	2008-04-23 04:32:45 UTC (rev 19693)
@@ -0,0 +1,78 @@
+package org.drools.factmodel;
+
+
+import java.beans.IntrospectionException;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
+/**
+ * This will generate a jar from a meta model.
+ * @author Michael Neale
+ *
+ */
+public class Jenerator {
+
+
+
+	public byte[] createJar(Fact[] facts, String packageName) throws SecurityException, IllegalArgumentException, IOException, IntrospectionException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
+		ByteArrayOutputStream result = new ByteArrayOutputStream();
+		JarOutputStream jout = new JarOutputStream(result);
+
+		JarEntry metaModel = new JarEntry("factmodel.xml");
+		jout.putNextEntry(metaModel);
+		jout.write(toXML(facts));
+		jout.closeEntry();
+
+		String packagePath = packageName.replace('.', '/');
+
+		for (int i = 0; i < facts.length; i++) {
+			ClassBuilder cb = new ClassBuilder();
+            ClassDefinition classDef = new ClassDefinition( packageName, null, new String[]{"java.io.Serializable"} );
+            for (int j = 0; j < facts[i].fields.size(); j++) {
+				Field fd = (Field) facts[i].fields.get(j);
+				classDef.addField(new FieldDefinition(fd.name, fd.type));
+			}
+            JarEntry je = new JarEntry(packagePath + "/" + facts[i].name + ".class");
+            jout.putNextEntry(je);
+            jout.write(cb.buildClass(classDef));
+            jout.closeEntry();
+		}
+		jout.flush();
+		jout.close();
+
+		return result.toByteArray();
+	}
+
+	private byte[] toXML(Fact[] facts) {
+		XStream x = new XStream(new DomDriver());
+		return x.toXML(facts).getBytes();
+
+	}
+
+	public Fact[] loadMetaModel(JarInputStream jis) throws Exception {
+        JarEntry entry = null;
+        while ( (entry = jis.getNextJarEntry()) != null ) {
+        	if (entry.getName().equals("factmodel.xml")) {
+        		return fromXML(jis);
+            }
+        }
+
+        throw new IllegalArgumentException("This is not a valid drools model jar - no factmodel.xml found.");
+	}
+
+	private Fact[] fromXML(JarInputStream jis) {
+		XStream x = new XStream(new DomDriver());
+		return (Fact[]) x.fromXML(jis);
+
+	}
+
+
+}


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

Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/ClassBuilderTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/ClassBuilderTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/ClassBuilderTest.java	2008-04-23 04:32:45 UTC (rev 19693)
@@ -0,0 +1,312 @@
+package org.drools.factmodel;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+public class ClassBuilderTest extends TestCase {
+
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /*
+     * Test method for 'br.com.auster.common.asm.ClassBuilder.buildClass(ClassDefinition)'
+     */
+    public void testBuildClass() {
+        try {
+            ClassBuilder builder = new ClassBuilder();
+
+            ClassDefinition classDef = new ClassDefinition( "br.com.auster.TestClass1",
+                                                            null,
+                                                            new String[]{"java.io.Serializable"} );
+            FieldDefinition intDef = new FieldDefinition( "intAttr",
+                                                          "int" );
+
+
+            FieldDefinition stringDef = new FieldDefinition( "stringAttr",
+                                                             "java.lang.String");//"java.lang.String" );
+            classDef.addField( intDef );
+            classDef.addField( stringDef );
+
+            Class clazz = builder.buildAndLoadClass( classDef );
+
+
+            byte[] data = builder.buildClass(classDef);
+
+
+
+            Assert.assertSame( "Returned class should be the same",
+                               clazz,
+                               classDef.getDefinedClass() );
+            Assert.assertEquals( "Class name should be equal",
+                                 classDef.getClassName(),
+                                 clazz.getName() );
+
+            Serializable instance = (Serializable) clazz.newInstance();
+
+            String stringValue = "Atributo String ok";
+            stringDef.setValue( instance,
+                                stringValue );
+            Assert.assertEquals( "Attribute should have been correctly set",
+                                 stringValue,
+                                 stringDef.getValue( instance ) );
+
+            int intValue = 50;
+            intDef.setValue( instance,
+                             new Integer( intValue ) );
+            Assert.assertEquals( "Attribute should have been correctly set",
+                                 intValue,
+                                 ((Integer) intDef.getValue( instance )).intValue() );
+
+            // testing class rebuilding
+            clazz = builder.buildAndLoadClass( classDef );
+
+        } catch ( Exception e ) {
+            e.printStackTrace();
+            Assert.fail( "Error creating class" );
+        }
+    }
+
+    /**
+     * how to write to a jar.
+     * @param data
+     * @throws FileNotFoundException
+     * @throws IOException
+     */
+	private void writeJar(byte[] data) throws FileNotFoundException,
+			IOException {
+		FileOutputStream out  = new FileOutputStream(new File("/Users/michaelneale/edson.jar"));
+		JarOutputStream jout = new JarOutputStream(out);
+		JarEntry je = new JarEntry("br/com/auster/TestClass1.class");
+		jout.putNextEntry(je);
+		jout.write(data);
+		jout.closeEntry();
+		jout.close();
+	}
+
+    public void testEquals() {
+        try {
+            ClassBuilder builder = new ClassBuilder();
+
+            ClassDefinition classDef = new ClassDefinition( "br.com.auster.TestClass2",
+                                                            null,
+                                                            new String[]{} );
+            FieldDefinition long1Def = new FieldDefinition( "longAttr1",
+                                                          "long",
+                                                          true);
+            FieldDefinition long2Def = new FieldDefinition( "longAttr2",
+                                                          "long",
+                                                          true);
+            FieldDefinition doubleDef = new FieldDefinition( "doubleAttr",
+                                                            "double",
+                                                            true);
+            FieldDefinition intDef = new FieldDefinition( "intAttr",
+                                                          "int",
+                                                          true);
+            FieldDefinition strDef = new FieldDefinition( "stringAttr",
+                                                          "java.lang.String",
+                                                          true);
+            FieldDefinition dateDef = new FieldDefinition( "dateAttr",
+                                                           "java.util.Date",
+                                                           true);
+            FieldDefinition str2Def = new FieldDefinition( "stringAttr2",
+                                                           "java.lang.String" );
+            classDef.addField( long1Def );
+            classDef.addField( long2Def );
+            classDef.addField( doubleDef );
+            classDef.addField( intDef );
+            classDef.addField( strDef );
+            classDef.addField( dateDef );
+            classDef.addField( str2Def );
+
+            Class clazz = builder.buildAndLoadClass( classDef );
+            Object x = clazz.newInstance();
+            Object y = clazz.newInstance();
+
+            long1Def.setValue( x,
+                               new Long( 20 ) );
+            long2Def.setValue( x,
+                               new Long( 30 ) );
+            doubleDef.setValue( x,
+                               new Double( 50.0 ) );
+            intDef.setValue( x,
+                             new Integer( 10 ) );
+            strDef.setValue( x,
+                             "abc" );
+            dateDef.setValue( x,
+                              new Date( 1000 ) );
+            str2Def.setValue( x,
+                              "instance1" );
+
+            long1Def.setValue( y,
+                               new Long( 20 ) );
+            long2Def.setValue( y,
+                               new Long( 30 ) );
+            doubleDef.setValue( y,
+                                new Double( 50.0 ) );
+            intDef.setValue( y,
+                             new Integer( 10 ) );
+            strDef.setValue( y,
+                             "abc" );
+            dateDef.setValue( y,
+                              new Date( 1000 ) );
+            str2Def.setValue( y,
+                              "instance2" );
+
+            Object o = new Object();
+
+            Assert.assertTrue( x.equals( x ) );
+            Assert.assertFalse( x.equals( null ) );
+            Assert.assertFalse( x.equals( o ) );
+
+            Assert.assertTrue( x.equals( y ) );
+
+            intDef.setValue( y,
+                             new Integer( 1 ) );
+            Assert.assertFalse( x.equals( y ) );
+
+            intDef.setValue( y,
+                             new Integer( 10 ) );
+            strDef.setValue( y,
+                             "xyz" );
+            Assert.assertFalse( x.equals( y ) );
+
+            strDef.setValue( y,
+                             null );
+            Assert.assertFalse( x.equals( y ) );
+
+            strDef.setValue( y,
+                             "abc" );
+            dateDef.setValue( y,
+                              new Date( 1 ) );
+            Assert.assertFalse( x.equals( y ) );
+
+            dateDef.setValue( y,
+                              null );
+            Assert.assertFalse( x.equals( y ) );
+
+        } catch ( Exception e ) {
+            e.printStackTrace();
+            Assert.fail("Exception not expected");
+        }
+    }
+
+    public void testHashCode() {
+        try {
+            ClassBuilder builder = new ClassBuilder();
+
+            ClassDefinition classDef = new ClassDefinition( "br.com.auster.TestClass3",
+                                                            null,
+                                                            new String[]{} );
+            FieldDefinition intDef = new FieldDefinition( "intAttr",
+                                                          "int",
+                                                          true);
+            FieldDefinition strDef = new FieldDefinition( "stringAttr",
+                                                          "java.lang.String",
+                                                          false);
+            classDef.addField( intDef );
+            classDef.addField( strDef );
+
+            Class clazz = builder.buildAndLoadClass( classDef );
+            Object x = clazz.newInstance();
+
+            intDef.setValue( x,
+                             new Integer( 10 ) );
+            strDef.setValue( x, "abc" );
+
+            Assert.assertEquals("Wrong hashcode calculation", (new Integer(10)).hashCode(), x.hashCode());
+            Assert.assertEquals("Wrong hashcode calculation", x.hashCode(), x.hashCode());
+
+        } catch ( Exception e ) {
+            e.printStackTrace();
+            Assert.fail("Exception not expected");
+        }
+    }
+
+    public void testToString() {
+        try {
+            ClassBuilder builder = new ClassBuilder();
+
+            ClassDefinition classDef = new ClassDefinition( "br.com.auster.TestClass2",
+                                                            null,
+                                                            new String[]{} );
+            FieldDefinition long1Def = new FieldDefinition( "longAttr1",
+                                                          "long",
+                                                          true);
+            FieldDefinition long2Def = new FieldDefinition( "longAttr2",
+                                                          "long",
+                                                          true);
+            FieldDefinition doubleDef = new FieldDefinition( "doubleAttr",
+                                                            "double",
+                                                            true);
+            FieldDefinition intDef = new FieldDefinition( "intAttr",
+                                                          "int",
+                                                          true);
+            FieldDefinition strDef = new FieldDefinition( "stringAttr",
+                                                          "java.lang.String",
+                                                          true);
+            FieldDefinition dateDef = new FieldDefinition( "dateAttr",
+                                                           "java.util.Date",
+                                                           true);
+            FieldDefinition str2Def = new FieldDefinition( "stringAttr2",
+                                                           "java.lang.String" );
+            classDef.addField( long1Def );
+            classDef.addField( long2Def );
+            classDef.addField( doubleDef );
+            classDef.addField( intDef );
+            classDef.addField( strDef );
+            classDef.addField( dateDef );
+            classDef.addField( str2Def );
+
+            Class clazz = builder.buildAndLoadClass( classDef );
+            Object x = clazz.newInstance();
+
+            long1Def.setValue( x,
+                               new Long( 20 ) );
+            long2Def.setValue( x,
+                               new Long( 30 ) );
+            doubleDef.setValue( x,
+                               new Double( 50.0 ) );
+            intDef.setValue( x,
+                             new Integer( 10 ) );
+            strDef.setValue( x,
+                             "abc" );
+            dateDef.setValue( x,
+                              new Date( 1000 ) );
+            str2Def.setValue( x,
+                              "instance1" );
+
+            String result = x.toString();
+
+            Assert.assertTrue( result.contains( long1Def.getName() ));
+            Assert.assertTrue( result.contains( long2Def.getName() ));
+            Assert.assertTrue( result.contains( doubleDef.getName() ));
+            Assert.assertTrue( result.contains( intDef.getName() ));
+            Assert.assertTrue( result.contains( strDef.getName() ));
+            Assert.assertTrue( result.contains( dateDef.getName() ));
+            Assert.assertTrue( result.contains( str2Def.getName() ));
+
+        } catch ( Exception e ) {
+            e.printStackTrace();
+            Assert.fail("Exception not expected");
+        }
+
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/ClassBuilderTest.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/FieldAccessorBuilderTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/FieldAccessorBuilderTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/FieldAccessorBuilderTest.java	2008-04-23 04:32:45 UTC (rev 19693)
@@ -0,0 +1,319 @@
+package org.drools.factmodel;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+public class FieldAccessorBuilderTest extends TestCase {
+    FieldAccessorBuilder builder;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        this.builder = new FieldAccessorBuilder();
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /*
+     * Test method for 'br.com.auster.common.asm.FieldAccessorBuilder.buildFieldAccessor(ClassDefinition, FieldDefinition)'
+     */
+    public void testBuildFieldAccessor() {
+        try {
+            FieldAccessor intAccessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( TestClass.class,
+                                                                                           "intAttr" ).newInstance();
+            FieldAccessor strAccessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( TestClass.class,
+                                                                                           "strAttr" ).newInstance();
+
+            String testString1 = "TestAttr1";
+            String testString2 = "TestAttr2";
+            TestClass instance = new TestClass();
+            instance.setIntAttr( 10 );
+            instance.setStrAttr( testString1 );
+
+            Assert.assertEquals( "Error reading int attr",
+                                 10,
+                                 ((Integer) intAccessor.getValue( instance )).intValue() );
+            Assert.assertEquals( "Error reading String attr",
+                                 testString1,
+                                 strAccessor.getValue( instance ) );
+
+            intAccessor.setValue( instance,
+                                  new Integer( 50 ) );
+            strAccessor.setValue( instance,
+                                  testString2 );
+
+            Assert.assertEquals( "Error setting int attr",
+                                 50,
+                                 instance.getIntAttr() );
+            Assert.assertEquals( "Error setting String attr",
+                                 testString2,
+                                 instance.getStrAttr() );
+
+            Assert.assertEquals( "Error reading int attr",
+                                 50,
+                                 ((Integer) intAccessor.getValue( instance )).intValue() );
+            Assert.assertEquals( "Error reading String attr",
+                                 testString2,
+                                 strAccessor.getValue( instance ) );
+
+        } catch ( Exception e ) {
+            e.printStackTrace();
+            Assert.fail( "No exception is supposed to be generated when creating field accessor: " + e );
+        }
+    }
+
+    public void testNullOnPrimitives() {
+        try {
+            FieldAccessor intAccessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( TestClass.class,
+                                                                                    "intAttr" ).newInstance();
+            FieldAccessor strAccessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( TestClass.class,
+                                                                                    "strAttr" ).newInstance();
+            FieldAccessor byteAccessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( TestClass.class,
+                                                                                     "byteAttr" ).newInstance();
+            FieldAccessor booleanAccessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( TestClass.class,
+                                                                                        "booleanAttr" ).newInstance();
+            FieldAccessor charAccessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( TestClass.class,
+                                                                                     "charAttr" ).newInstance();
+            FieldAccessor doubleAccessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( TestClass.class,
+                                                                                       "doubleAttr" ).newInstance();
+            FieldAccessor floatAccessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( TestClass.class,
+                                                                                      "floatAttr" ).newInstance();
+            FieldAccessor longAccessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( TestClass.class,
+                                                                                     "longAttr" ).newInstance();
+            FieldAccessor shortAccessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( TestClass.class,
+                                                                                      "shortAttr" ).newInstance();
+
+            String testString1 = "TestAttr1";
+            TestClass instance = new TestClass();
+            instance.setIntAttr( 25 );
+            instance.setStrAttr( testString1 );
+            instance.setByteAttr( (byte) 10 );
+            instance.setBooleanAttr( true );
+            instance.setCharAttr( 'x' );
+            instance.setDoubleAttr( 10.5d );
+            instance.setFloatAttr( 40.3f );
+            instance.setLongAttr( 43l );
+            instance.setShortAttr( (short) 20 );
+
+            intAccessor.setValue( instance,
+                                  null );
+            strAccessor.setValue( instance,
+                                  null );
+            byteAccessor.setValue( instance,
+                                   null );
+            booleanAccessor.setValue( instance,
+                                      null );
+            charAccessor.setValue( instance,
+                                   null );
+            doubleAccessor.setValue( instance,
+                                     null );
+            floatAccessor.setValue( instance,
+                                    null );
+            longAccessor.setValue( instance,
+                                   null );
+            shortAccessor.setValue( instance,
+                                    null );
+
+            Assert.assertEquals( "Error setting attr",
+                                 0,
+                                 instance.getIntAttr() );
+            Assert.assertNull( "Error setting attr",
+                               instance.getStrAttr() );
+            Assert.assertEquals( "Error setting attr",
+                                 0,
+                                 instance.getByteAttr() );
+            Assert.assertEquals( "Error setting attr",
+                                 false,
+                                 instance.isBooleanAttr() );
+            Assert.assertEquals( "Error setting attr",
+                                 '\0',
+                                 instance.getCharAttr() );
+            Assert.assertEquals( "Error setting attr",
+                                 0.0d,
+                                 instance.getDoubleAttr(),
+                                 0.1d );
+            Assert.assertEquals( "Error setting attr",
+                                 0.0f,
+                                 instance.getFloatAttr(),
+                                 0.1f );
+            Assert.assertEquals( "Error setting attr",
+                                 0l,
+                                 instance.getLongAttr() );
+            Assert.assertEquals( "Error setting attr",
+                                 (short) 0,
+                                 instance.getShortAttr() );
+
+            Assert.assertEquals( "Error reading int attr",
+                                 0,
+                                 ((Integer) intAccessor.getValue( instance )).intValue() );
+            Assert.assertNull( "Error reading String attr",
+                               strAccessor.getValue( instance ) );
+            Assert.assertEquals( "Error reading attr",
+                                 0,
+                                 ((Byte) byteAccessor.getValue( instance )).byteValue() );
+            Assert.assertEquals( "Error reading attr",
+                                 false,
+                                 ((Boolean) booleanAccessor.getValue( instance )).booleanValue() );
+            Assert.assertEquals( "Error reading attr",
+                                 '\0',
+                                 ((Character) charAccessor.getValue( instance )).charValue() );
+            Assert.assertEquals( "Error reading attr",
+                                 0.0d,
+                                 ((Double) doubleAccessor.getValue( instance )).doubleValue(),
+                                 0.1d );
+            Assert.assertEquals( "Error reading attr",
+                                 0.0f,
+                                 ((Float) floatAccessor.getValue( instance )).floatValue(),
+                                 0.1f );
+            Assert.assertEquals( "Error reading attr",
+                                 0l,
+                                 ((Long) longAccessor.getValue( instance )).longValue() );
+            Assert.assertEquals( "Error reading attr",
+                                 (short) 0,
+                                 ((Short) shortAccessor.getValue( instance )).shortValue() );
+
+        } catch ( Exception e ) {
+            e.printStackTrace();
+            Assert.fail( "No exception is supposed to be generated when creating field accessor: " + e );
+        }
+    }
+
+    public static class TestClass {
+        private int     intAttr;
+        private String  strAttr;
+        private byte    byteAttr;
+        private boolean booleanAttr;
+        private char    charAttr;
+        private double  doubleAttr;
+        private float   floatAttr;
+        private long    longAttr;
+        private short   shortAttr;
+
+        /**
+         * @return Returns the intAttr.
+         */
+        public int getIntAttr() {
+            return intAttr;
+        }
+
+        /**
+         * @param intAttr The intAttr to set.
+         */
+        public void setIntAttr(int intAttr) {
+            this.intAttr = intAttr;
+        }
+
+        /**
+         * @return Returns the strAttr.
+         */
+        public String getStrAttr() {
+            return strAttr;
+        }
+
+        /**
+         * @param strAttr The strAttr to set.
+         */
+        public void setStrAttr(String strAttr) {
+            this.strAttr = strAttr;
+        }
+
+        /**
+         * @return Returns the booleanAttr.
+         */
+        public boolean isBooleanAttr() {
+            return booleanAttr;
+        }
+
+        /**
+         * @param booleanAttr The booleanAttr to set.
+         */
+        public void setBooleanAttr(boolean booleanAttr) {
+            this.booleanAttr = booleanAttr;
+        }
+
+        /**
+         * @return Returns the byteAttr.
+         */
+        public byte getByteAttr() {
+            return byteAttr;
+        }
+
+        /**
+         * @param byteAttr The byteAttr to set.
+         */
+        public void setByteAttr(byte byteAttr) {
+            this.byteAttr = byteAttr;
+        }
+
+        /**
+         * @return Returns the charAttr.
+         */
+        public char getCharAttr() {
+            return charAttr;
+        }
+
+        /**
+         * @param charAttr The charAttr to set.
+         */
+        public void setCharAttr(char charAttr) {
+            this.charAttr = charAttr;
+        }
+
+        /**
+         * @return Returns the doubleAttr.
+         */
+        public double getDoubleAttr() {
+            return doubleAttr;
+        }
+
+        /**
+         * @param doubleAttr The doubleAttr to set.
+         */
+        public void setDoubleAttr(double doubleAttr) {
+            this.doubleAttr = doubleAttr;
+        }
+
+        /**
+         * @return Returns the floatAttr.
+         */
+        public float getFloatAttr() {
+            return floatAttr;
+        }
+
+        /**
+         * @param floatAttr The floatAttr to set.
+         */
+        public void setFloatAttr(float floatAttr) {
+            this.floatAttr = floatAttr;
+        }
+
+        /**
+         * @return Returns the longAttr.
+         */
+        public long getLongAttr() {
+            return longAttr;
+        }
+
+        /**
+         * @param longAttr The longAttr to set.
+         */
+        public void setLongAttr(long longAttr) {
+            this.longAttr = longAttr;
+        }
+
+        /**
+         * @return Returns the shortAttr.
+         */
+        public short getShortAttr() {
+            return shortAttr;
+        }
+
+        /**
+         * @param shortAttr The shortAttr to set.
+         */
+        public void setShortAttr(short shortAttr) {
+            this.shortAttr = shortAttr;
+        }
+    }
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/FieldAccessorBuilderTest.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/InstancesHashcodedTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/InstancesHashcodedTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/InstancesHashcodedTest.java	2008-04-23 04:32:45 UTC (rev 19693)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2004-2006 Auster Solutions. All Rights Reserved.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Created on 26/08/2006
+ */
+package org.drools.factmodel;
+
+import java.sql.Types;
+import java.util.Calendar;
+import java.util.Date;
+
+import junit.framework.TestCase;
+
+/**
+ * @author framos
+ * @version $Id$
+ *
+ */
+public class InstancesHashcodedTest extends TestCase {
+	
+	
+/*
+		<dimension name="bck_cycle_dm"  item-expression="cycleDimension" 
+			       mode="ignore" cache="10" export-to="cycle_id"> 
+			<id    name="objid"            type="long"             generator-sql="select bck_dimensions_uid.nextval from dual"/> 
+			<field name="cut_date"         type="java.util.Date"   value="cutDate"     key="true"/> 
+			<field name="due_date"         type="java.util.Date"   value="dueDate"     key="true"/> 
+			<field name="cycle_code"       type="java.lang.String" value="cycleCode"/> 
+			<field name="issue_date"       type="java.util.Date"   value="issueDate"/> 
+		</dimension> 
+ */	
+
+	
+	public void testInstanceHashcodes() {
+		
+		ClassDefinition cd = new ClassDefinition( "br.com.auster.TestClass2", null, new String[]{} );
+		cd.addField(new FieldDefinition("cutDate", "java.util.Date", true));
+		cd.addField(new FieldDefinition("dueDate", "java.util.Date", true));
+		cd.addField(new FieldDefinition("issueDate", "java.util.Date", false));
+		cd.addField(new FieldDefinition("cycleCode", "java.lang.String", false));
+		
+		ClassBuilder cb = new ClassBuilder();
+		
+		Calendar cal = Calendar.getInstance();
+		cal.set(Calendar.YEAR, 2006);
+		cal.set(Calendar.MONTH, Calendar.JUNE);
+		cal.set(Calendar.DAY_OF_MONTH, 01);
+		Date cut = cal.getTime();
+		
+		cal.set(Calendar.MONTH, Calendar.JULY);
+		cal.set(Calendar.DAY_OF_MONTH, 13);
+		Date d1 = cal.getTime();
+		
+		cal.set(Calendar.DAY_OF_MONTH, 15);
+		Date d2 = cal.getTime();
+			
+		try {
+			Class klass = cb.buildAndLoadClass(cd);
+			Object o1 = klass.newInstance();
+			cd.getField("cutDate").getFieldAccessor().setValue(o1, cut);
+			cd.getField("dueDate").getFieldAccessor().setValue(o1, d1);
+			
+			Object o2 = klass.newInstance();
+			cd.getField("cutDate").getFieldAccessor().setValue(o2, cut);
+			cd.getField("dueDate").getFieldAccessor().setValue(o2, d2);
+			
+			System.out.println(o1);
+			System.out.println(o1.hashCode());
+			System.out.println(o2);
+			System.out.println(o2.hashCode());
+			
+			System.out.println(o1.equals(o2));
+			
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/InstancesHashcodedTest.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/JeneratorTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/JeneratorTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/factmodel/JeneratorTest.java	2008-04-23 04:32:45 UTC (rev 19693)
@@ -0,0 +1,74 @@
+package org.drools.factmodel;
+
+import java.io.ByteArrayInputStream;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import junit.framework.TestCase;
+
+
+/**
+ * This mostly shows how to go to a jar and back, if needed.
+ * Probably can be partly ignored eventually.
+ *
+ * @author Michael Neale
+ */
+public class JeneratorTest extends TestCase {
+
+
+	public void testRoundTrip() throws Exception {
+		Fact f = new Fact();
+		f.name = "Foobar";
+		Field f1 = new Field();
+		f1.name = "name";
+		f1.type = "java.lang.String";
+		f.fields.add(f1);
+
+		Field f2 = new Field();
+		f2.name = "age";
+		f2.type = "java.lang.Integer";
+		f.fields.add(f2);
+
+		Fact f_  = new Fact();
+		f_.name = "Baz";
+
+		Field f1_ = new Field();
+		f1_.name = "name";
+		f1_.type = "java.lang.String";
+		f_.fields.add(f1_);
+
+
+		Jenerator jen = new Jenerator();
+		byte[] data = jen.createJar(new Fact[] {f, f_}, "whee.waa");
+		JarInputStream jis = new JarInputStream(new ByteArrayInputStream(data));
+		JarEntry je = jis.getNextJarEntry();
+
+		assertNotNull(je);
+		System.err.println(je.getName());
+		assertEquals("factmodel.xml", je.getName());
+
+
+		je = jis.getNextJarEntry();
+
+		assertNotNull(je);
+		System.err.println(je.getName());
+		assertEquals("whee/waa/Foobar.class", je.getName());
+
+
+		je = jis.getNextJarEntry();
+
+		assertNotNull(je);
+		System.err.println(je.getName());
+		assertEquals("whee/waa/Baz.class", je.getName());
+
+
+
+		Fact[] facts = jen.loadMetaModel(new JarInputStream(new ByteArrayInputStream(data)));
+		assertEquals(2, facts.length);
+		assertEquals("Foobar", facts[0].name);
+		assertEquals("Baz", facts[1].name);
+
+
+	}
+
+}


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




More information about the jboss-svn-commits mailing list