[jboss-svn-commits] JBL Code SVN: r8181 - in labs/jbossrules/contrib: . dynamic dynamic/.externalToolBuilders dynamic/.settings dynamic/libs dynamic/src dynamic/src/java dynamic/src/java/com dynamic/src/java/com/sample dynamic/src/rules
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sun Dec 10 14:26:05 EST 2006
Author: tirelli
Date: 2006-12-10 14:25:46 -0500 (Sun, 10 Dec 2006)
New Revision: 8181
Added:
labs/jbossrules/contrib/dynamic/
labs/jbossrules/contrib/dynamic/.classpath
labs/jbossrules/contrib/dynamic/.externalToolBuilders/
labs/jbossrules/contrib/dynamic/.externalToolBuilders/org.drools.ide.droolsbuilder.launch
labs/jbossrules/contrib/dynamic/.project
labs/jbossrules/contrib/dynamic/.settings/
labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.core.prefs
labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.ui.prefs
labs/jbossrules/contrib/dynamic/.settings/org.eclipse.ltk.core.refactoring.prefs
labs/jbossrules/contrib/dynamic/libs/
labs/jbossrules/contrib/dynamic/libs/asm-all-3.0.jar
labs/jbossrules/contrib/dynamic/src/
labs/jbossrules/contrib/dynamic/src/java/
labs/jbossrules/contrib/dynamic/src/java/com/
labs/jbossrules/contrib/dynamic/src/java/com/sample/
labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassBuilder.java
labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassDefinition.java
labs/jbossrules/contrib/dynamic/src/java/com/sample/Customer.java
labs/jbossrules/contrib/dynamic/src/java/com/sample/DroolsTest.java
labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessor.java
labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessorBuilder.java
labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldDefinition.java
labs/jbossrules/contrib/dynamic/src/rules/
labs/jbossrules/contrib/dynamic/src/rules/Shipper.drl
Log:
Adding sample project using dynamically generated classes
Added: labs/jbossrules/contrib/dynamic/.classpath
===================================================================
--- labs/jbossrules/contrib/dynamic/.classpath 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/.classpath 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src/java"/>
+ <classpathentry kind="src" path="src/rules"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="DROOLS/JBoss Rules"/>
+ <classpathentry kind="lib" path="libs/asm-all-3.0.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
Property changes on: labs/jbossrules/contrib/dynamic/.classpath
___________________________________________________________________
Name: svn:executable
+ *
Added: labs/jbossrules/contrib/dynamic/.externalToolBuilders/org.drools.ide.droolsbuilder.launch
===================================================================
--- labs/jbossrules/contrib/dynamic/.externalToolBuilders/org.drools.ide.droolsbuilder.launch 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/.externalToolBuilders/org.drools.ide.droolsbuilder.launch 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
+<mapAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_DISABLED_BUILDER" value="org.drools.ide.droolsbuilder"/>
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
+</launchConfiguration>
Property changes on: labs/jbossrules/contrib/dynamic/.externalToolBuilders/org.drools.ide.droolsbuilder.launch
___________________________________________________________________
Name: svn:executable
+ *
Added: labs/jbossrules/contrib/dynamic/.project
===================================================================
--- labs/jbossrules/contrib/dynamic/.project 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/.project 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>DynamicBeans</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+ <triggers>full,incremental,</triggers>
+ <arguments>
+ <dictionary>
+ <key>LaunchConfigHandle</key>
+ <value><project>/.externalToolBuilders/org.drools.ide.droolsbuilder.launch</value>
+ </dictionary>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
Property changes on: labs/jbossrules/contrib/dynamic/.project
___________________________________________________________________
Name: svn:executable
+ *
Added: labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.core.prefs 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.core.prefs 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,12 @@
+#Thu Oct 19 22:42:03 GMT-03:00 2006
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
Property changes on: labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.core.prefs
___________________________________________________________________
Name: svn:executable
+ *
Added: labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.ui.prefs
===================================================================
--- labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.ui.prefs 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.ui.prefs 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,3 @@
+#Thu Oct 19 22:42:03 GMT-03:00 2006
+eclipse.preferences.version=1
+internal.default.compliance=default
Property changes on: labs/jbossrules/contrib/dynamic/.settings/org.eclipse.jdt.ui.prefs
___________________________________________________________________
Name: svn:executable
+ *
Added: labs/jbossrules/contrib/dynamic/.settings/org.eclipse.ltk.core.refactoring.prefs
===================================================================
--- labs/jbossrules/contrib/dynamic/.settings/org.eclipse.ltk.core.refactoring.prefs 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/.settings/org.eclipse.ltk.core.refactoring.prefs 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,3 @@
+#Sun Dec 10 16:13:10 GMT-03:00 2006
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
Property changes on: labs/jbossrules/contrib/dynamic/.settings/org.eclipse.ltk.core.refactoring.prefs
___________________________________________________________________
Name: svn:executable
+ *
Added: labs/jbossrules/contrib/dynamic/libs/asm-all-3.0.jar
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/contrib/dynamic/libs/asm-all-3.0.jar
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassBuilder.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassBuilder.java 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassBuilder.java 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,844 @@
+package com.sample;
+
+import java.beans.IntrospectionException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.drools.RuntimeDroolsException;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A builder to dinamically build simple JavaBean classes
+ *
+ * @author <mailto:etirelli at redhat.com>Edson Tirelli</mailto>
+ *
+ */
+public class ClassBuilder {
+ private boolean debug = false;
+
+ private PackageClassLoader classLoader = new PackageClassLoader( ClassBuilder.class.getClassLoader() );
+
+ public ClassBuilder() {
+ this.debug = "false".equalsIgnoreCase( System.getProperty( "com.sample.debug" ) );
+ }
+
+ /**
+ * Dinamically builds, defines and loads a class based on the given class definition
+ *
+ * @param classDef the class definition object structure
+ *
+ * @return the Class instance for the given class definition
+ *
+ * @throws IOException
+ * @throws IntrospectionException
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
+ * @throws NoSuchMethodException
+ * @throws ClassNotFoundException
+ * @throws IllegalArgumentException
+ * @throws SecurityException
+ * @throws NoSuchFieldException
+ * @throws InstantiationException
+ */
+ public Class buildAndLoadClass(ClassDefinition classDef) throws IOException,
+ IntrospectionException,
+ SecurityException,
+ IllegalArgumentException,
+ ClassNotFoundException,
+ NoSuchMethodException,
+ IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException,
+ NoSuchFieldException {
+ try {
+ Class clazz = Class.forName( classDef.getClassName() );
+
+ classDef.setDefinedClass( clazz );
+
+ return clazz;
+
+ } catch ( ClassNotFoundException e ) {
+ // class not loaded, so create and load it
+ byte[] serializedClazz = this.buildClass( classDef );
+
+ Class clazz = this.loadClass( classDef.getClassName(),
+ serializedClazz );
+ classDef.setDefinedClass( clazz );
+
+ return clazz;
+ }
+ }
+
+ /**
+ * Dinamically builds, defines and loads a class based on the given class definition
+ *
+ * @param classDef the class definition object structure
+ *
+ * @return the Class instance for the given class definition
+ *
+ * @throws IOException
+ * @throws IntrospectionException
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
+ * @throws NoSuchMethodException
+ * @throws ClassNotFoundException
+ * @throws IllegalArgumentException
+ * @throws SecurityException
+ * @throws NoSuchFieldException
+ * @throws InstantiationException
+ */
+ public byte[] buildClass(ClassDefinition classDef) throws IOException,
+ IntrospectionException,
+ SecurityException,
+ IllegalArgumentException,
+ ClassNotFoundException,
+ NoSuchMethodException,
+ IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException,
+ NoSuchFieldException {
+
+ ClassWriter cw = new ClassWriter( ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES );
+
+ this.buildClassHeader( cw,
+ classDef );
+
+ // Building fields
+ for ( FieldDefinition fieldDef : classDef.getFields() ) {
+ this.buildField( cw,
+ fieldDef );
+ }
+
+ // Building default constructor
+ this.buildDefaultConstructor( cw,
+ classDef );
+
+ // Building methods
+ for ( FieldDefinition fieldDef : classDef.getFields() ) {
+ this.buildGetMethod( cw,
+ classDef,
+ fieldDef );
+ this.buildSetMethod( cw,
+ classDef,
+ fieldDef );
+ }
+
+ this.buildEquals( cw,
+ classDef );
+ this.buildHashCode( cw,
+ classDef );
+
+ this.buildToString( cw,
+ classDef );
+
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+
+ /**
+ * Defines the class header for the given class definition
+ *
+ * @param cw
+ * @param dimDef
+ */
+ private void buildClassHeader(ClassWriter cw,
+ ClassDefinition classDef) {
+ // Building class header
+ cw.visit( Opcodes.V1_4,
+ Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
+ classDef.getClassNameAsInternal(),
+ null,
+ classDef.getSuperClassAsInternal(),
+ classDef.getInterfacesAsInternal() );
+
+ cw.visitSource( classDef.getClassName() + ".java",
+ null );
+ }
+
+ /**
+ * Creates the field defined by the given FieldDefinition
+ *
+ * @param cw
+ * @param fieldDef
+ */
+ private void buildField(ClassWriter cw,
+ FieldDefinition fieldDef) {
+ FieldVisitor fv;
+ fv = cw.visitField( Opcodes.ACC_PRIVATE,
+ fieldDef.getName(),
+ fieldDef.getInternalType(),
+ null,
+ null );
+ fv.visitEnd();
+ }
+
+ /**
+ * Creates a default constructor for the class
+ *
+ * @param cw
+ */
+ private void buildDefaultConstructor(ClassWriter cw,
+ ClassDefinition classDef) {
+ MethodVisitor mv;
+ // Building default constructor
+ {
+ mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+ "<init>",
+ Type.getMethodDescriptor( Type.VOID_TYPE,
+ new Type[]{} ),
+ null,
+ null );
+ mv.visitCode();
+ Label l0 = null;
+ if ( this.debug ) {
+ l0 = new Label();
+ mv.visitLabel( l0 );
+ }
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitMethodInsn( Opcodes.INVOKESPECIAL,
+ Type.getInternalName( Object.class ),
+ "<init>",
+ Type.getMethodDescriptor( Type.VOID_TYPE,
+ new Type[]{} ) );
+ mv.visitInsn( Opcodes.RETURN );
+ Label l1 = null;
+ if ( this.debug ) {
+ l1 = new Label();
+ mv.visitLabel( l1 );
+ mv.visitLocalVariable( "this",
+ classDef.getInternalName(),
+ null,
+ l0,
+ l1,
+ 0 );
+ }
+ mv.visitMaxs( 0,
+ 0 );
+ mv.visitEnd();
+ }
+ }
+
+ /**
+ * Creates the set method for the given field definition
+ *
+ * @param cw
+ * @param classDef
+ * @param fieldDef
+ */
+ private void buildSetMethod(ClassWriter cw,
+ ClassDefinition classDef,
+ FieldDefinition fieldDef) {
+ MethodVisitor mv;
+ // set method
+ {
+ mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+ fieldDef.getWriteMethod(),
+ Type.getMethodDescriptor( Type.VOID_TYPE,
+ new Type[]{Type.getType( fieldDef.getInternalType() )} ),
+ null,
+ null );
+ mv.visitCode();
+ Label l0 = null;
+ if ( this.debug ) {
+ l0 = new Label();
+ mv.visitLabel( l0 );
+ }
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitVarInsn( Type.getType( fieldDef.getInternalType() ).getOpcode( Opcodes.ILOAD ),
+ 1 );
+ mv.visitFieldInsn( Opcodes.PUTFIELD,
+ classDef.getClassNameAsInternal(),
+ fieldDef.getName(),
+ fieldDef.getInternalType() );
+
+ mv.visitInsn( Opcodes.RETURN );
+ Label l1 = null;
+ if ( this.debug ) {
+ l1 = new Label();
+ mv.visitLabel( l1 );
+ mv.visitLocalVariable( "this",
+ classDef.getInternalName(),
+ null,
+ l0,
+ l1,
+ 0 );
+ }
+ mv.visitMaxs( 0,
+ 0 );
+ mv.visitEnd();
+ }
+ }
+
+ /**
+ * Creates the get method for the given field definition
+ *
+ * @param cw
+ * @param classDef
+ * @param fieldDef
+ */
+ private void buildGetMethod(ClassWriter cw,
+ ClassDefinition classDef,
+ FieldDefinition fieldDef) {
+ MethodVisitor mv;
+ // Get method
+ {
+ mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+ fieldDef.getReadMethod(),
+ Type.getMethodDescriptor( Type.getType( fieldDef.getInternalType() ),
+ new Type[]{} ),
+ null,
+ null );
+ mv.visitCode();
+ Label l0 = null;
+ if ( this.debug ) {
+ l0 = new Label();
+ mv.visitLabel( l0 );
+ }
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ classDef.getClassNameAsInternal(),
+ fieldDef.getName(),
+ fieldDef.getInternalType() );
+ mv.visitInsn( Type.getType( fieldDef.getInternalType() ).getOpcode( Opcodes.IRETURN ) );
+ Label l1 = null;
+ if ( this.debug ) {
+ l1 = new Label();
+ mv.visitLabel( l1 );
+ mv.visitLocalVariable( "this",
+ classDef.getInternalName(),
+ null,
+ l0,
+ l1,
+ 0 );
+ }
+ mv.visitMaxs( 0,
+ 0 );
+ mv.visitEnd();
+ }
+ }
+
+ private void buildEquals(ClassWriter cw,
+ ClassDefinition classDef) {
+ MethodVisitor mv;
+ // Building equals method
+ {
+ mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+ "equals",
+ "(Ljava/lang/Object;)Z",
+ null,
+ null );
+ mv.visitCode();
+ Label l0 = null;
+ if ( this.debug ) {
+ l0 = new Label();
+ mv.visitLabel( l0 );
+ }
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 1 );
+ Label l1 = new Label();
+ mv.visitJumpInsn( Opcodes.IF_ACMPNE,
+ l1 );
+ mv.visitInsn( Opcodes.ICONST_1 );
+ mv.visitInsn( Opcodes.IRETURN );
+ mv.visitLabel( l1 );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 1 );
+ Label l3 = new Label();
+ mv.visitJumpInsn( Opcodes.IFNULL,
+ l3 );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 1 );
+ mv.visitTypeInsn( Opcodes.INSTANCEOF,
+ classDef.getClassNameAsInternal() );
+ Label l4 = new Label();
+ mv.visitJumpInsn( Opcodes.IFNE,
+ l4 );
+ mv.visitLabel( l3 );
+ mv.visitInsn( Opcodes.ICONST_0 );
+ mv.visitInsn( Opcodes.IRETURN );
+ mv.visitLabel( l4 );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 1 );
+ mv.visitTypeInsn( Opcodes.CHECKCAST,
+ classDef.getClassNameAsInternal() );
+ mv.visitVarInsn( Opcodes.ASTORE,
+ 2 );
+
+ int count = 0;
+ for ( FieldDefinition field : classDef.getFields() ) {
+ if ( field.isKey() ) {
+ count++;
+ Label goNext = new Label();
+ if ( field.isPrimitive() ) {
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ classDef.getClassNameAsInternal(),
+ field.getName(),
+ field.getInternalType() );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 2 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ classDef.getClassNameAsInternal(),
+ field.getName(),
+ field.getInternalType() );
+ if ( field.getType().equals( "long" ) ) {
+ mv.visitInsn( Opcodes.LCMP );
+ mv.visitJumpInsn( Opcodes.IFEQ,
+ goNext );
+ } else if ( field.getType().equals( "double" ) ) {
+ mv.visitInsn( Opcodes.DCMPL );
+ mv.visitJumpInsn( Opcodes.IFEQ,
+ goNext );
+ } else if ( field.getType().equals( "float" ) ) {
+ mv.visitInsn( Opcodes.FCMPL );
+ mv.visitJumpInsn( Opcodes.IFEQ,
+ goNext );
+ } else {
+ mv.visitJumpInsn( Opcodes.IF_ICMPEQ,
+ goNext );
+ }
+ mv.visitInsn( Opcodes.ICONST_0 );
+ mv.visitInsn( Opcodes.IRETURN );
+ } else {
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ classDef.getClassNameAsInternal(),
+ field.getName(),
+ field.getInternalType() );
+ Label secondIfPart = new Label();
+ mv.visitJumpInsn( Opcodes.IFNONNULL,
+ secondIfPart );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 2 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ classDef.getClassNameAsInternal(),
+ field.getName(),
+ field.getInternalType() );
+ Label returnFalse = new Label();
+ mv.visitJumpInsn( Opcodes.IFNONNULL,
+ returnFalse );
+ mv.visitLabel( secondIfPart );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ classDef.getClassNameAsInternal(),
+ field.getName(),
+ field.getInternalType() );
+ mv.visitJumpInsn( Opcodes.IFNULL,
+ goNext );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ classDef.getClassNameAsInternal(),
+ field.getName(),
+ field.getInternalType() );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 2 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ classDef.getClassNameAsInternal(),
+ field.getName(),
+ field.getInternalType() );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ field.getBoxTypeName(),
+ "equals",
+ "(Ljava/lang/Object;)Z" );
+ mv.visitJumpInsn( Opcodes.IFNE,
+ goNext );
+ mv.visitLabel( returnFalse );
+ mv.visitInsn( Opcodes.ICONST_0 );
+ mv.visitInsn( Opcodes.IRETURN );
+ }
+ mv.visitLabel( goNext );
+ }
+ }
+ if ( count > 0 ) {
+ mv.visitInsn( Opcodes.ICONST_1 );
+ } else {
+ mv.visitInsn( Opcodes.ICONST_0 );
+ }
+ mv.visitInsn( Opcodes.IRETURN );
+ Label lastLabel = null;
+ if ( this.debug ) {
+ lastLabel = new Label();
+ mv.visitLabel( lastLabel );
+ mv.visitLocalVariable( "this",
+ classDef.getInternalName(),
+ null,
+ l0,
+ lastLabel,
+ 0 );
+ mv.visitLocalVariable( "obj",
+ Type.getDescriptor( Object.class ),
+ null,
+ l0,
+ lastLabel,
+ 1 );
+ mv.visitLocalVariable( "other",
+ classDef.getInternalName(),
+ null,
+ l0,
+ lastLabel,
+ 2 );
+ }
+ mv.visitMaxs( 0,
+ 0 );
+ mv.visitEnd();
+ }
+ }
+
+ private void buildHashCode(ClassWriter cw,
+ ClassDefinition classDef) {
+
+ MethodVisitor mv;
+ // Building hashCode() method
+ {
+ mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+ "hashCode",
+ "()I",
+ null,
+ null );
+ mv.visitCode();
+ Label l0 = null;
+ if ( this.debug ) {
+ l0 = new Label();
+ mv.visitLabel( l0 );
+ }
+ mv.visitInsn( Opcodes.ICONST_0 );
+ mv.visitVarInsn( Opcodes.ISTORE,
+ 1 );
+
+ for ( FieldDefinition field : classDef.getFields() ) {
+ if ( field.isKey() ) {
+ mv.visitVarInsn( Opcodes.ILOAD,
+ 1 );
+ if ( field.isPrimitive() ) {
+ mv.visitTypeInsn( Opcodes.NEW,
+ field.getBoxTypeName() );
+ mv.visitInsn( Opcodes.DUP );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ classDef.getClassNameAsInternal(),
+ field.getName(),
+ field.getInternalType() );
+ mv.visitMethodInsn( Opcodes.INVOKESPECIAL,
+ field.getBoxTypeName(),
+ "<init>",
+ Type.getMethodDescriptor( Type.VOID_TYPE,
+ new Type[]{Type.getType( field.getInternalType() )} ) );
+ } else {
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ classDef.getClassNameAsInternal(),
+ field.getName(),
+ field.getInternalType() );
+
+ }
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ field.getBoxTypeName(),
+ "hashCode",
+ "()I" );
+ mv.visitInsn( Opcodes.IADD );
+ mv.visitVarInsn( Opcodes.ISTORE,
+ 1 );
+ }
+ }
+ mv.visitVarInsn( Opcodes.ILOAD,
+ 1 );
+ mv.visitIntInsn( Opcodes.SIPUSH,
+ 9653 );
+ mv.visitInsn( Opcodes.IREM );
+ mv.visitInsn( Opcodes.IRETURN );
+
+ Label lastLabel = null;
+ if ( this.debug ) {
+ lastLabel = new Label();
+ mv.visitLabel( lastLabel );
+ mv.visitLocalVariable( "this",
+ classDef.getInternalName(),
+ null,
+ l0,
+ lastLabel,
+ 0 );
+ mv.visitLocalVariable( "hash",
+ Type.getDescriptor( int.class ),
+ null,
+ l0,
+ lastLabel,
+ 1 );
+ }
+ mv.visitMaxs( 0,
+ 0 );
+ mv.visitEnd();
+ }
+ }
+
+ private void buildToString(ClassWriter cw,
+ ClassDefinition classDef) {
+ MethodVisitor mv;
+ {
+ mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+ "toString",
+ "()Ljava/lang/String;",
+ null,
+ null );
+ mv.visitCode();
+
+ Label l0 = null;
+ if ( this.debug ) {
+ l0 = new Label();
+ mv.visitLabel( l0 );
+ }
+
+ // StringBuffer buf = new StringBuffer();
+ mv.visitTypeInsn( Opcodes.NEW,
+ "java/lang/StringBuffer" );
+ mv.visitInsn( Opcodes.DUP );
+ mv.visitMethodInsn( Opcodes.INVOKESPECIAL,
+ "java/lang/StringBuffer",
+ "<init>",
+ "()V" );
+ mv.visitVarInsn( Opcodes.ASTORE,
+ 1 );
+
+ // buf.append(this.getClass().getSimpleName())
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 1 );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ classDef.getClassNameAsInternal(),
+ "getClass",
+ "()Ljava/lang/Class;" );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ "java/lang/Class",
+ "getSimpleName",
+ "()Ljava/lang/String;" );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ "java/lang/StringBuffer",
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
+
+ // buf.append("( ");
+ mv.visitLdcInsn( "( " );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ "java/lang/StringBuffer",
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
+
+ boolean previous = false;
+ for ( FieldDefinition field : classDef.getFields() ) {
+ if ( previous ) {
+ // buf.append(", ");
+ mv.visitLdcInsn( ", " );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ "java/lang/StringBuffer",
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
+ }
+ // buf.append(attrName)
+ mv.visitLdcInsn( field.getName() );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ "java/lang/StringBuffer",
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
+
+ // buf.append("=");
+ mv.visitLdcInsn( "=" );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ "java/lang/StringBuffer",
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
+
+ // buf.append(attrValue)
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ classDef.getClassNameAsInternal(),
+ field.getName(),
+ field.getInternalType() );
+
+ if ( field.isPrimitive() ) {
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ "java/lang/StringBuffer",
+ "append",
+ Type.getMethodDescriptor( Type.getType( StringBuffer.class ),
+ new Type[]{Type.getType( field.getInternalType() )} ) );
+ } else {
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ "java/lang/StringBuffer",
+ "append",
+ Type.getMethodDescriptor( Type.getType( StringBuffer.class ),
+ new Type[]{Type.getType( Object.class )} ) );
+ }
+ previous = true;
+ }
+
+ mv.visitLdcInsn( " )" );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ "java/lang/StringBuffer",
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ "java/lang/StringBuffer",
+ "toString",
+ "()Ljava/lang/String;" );
+ mv.visitInsn( Opcodes.ARETURN );
+
+ Label lastLabel = null;
+ if ( this.debug ) {
+ lastLabel = new Label();
+ mv.visitLabel( lastLabel );
+ mv.visitLocalVariable( "this",
+ classDef.getInternalName(),
+ null,
+ l0,
+ lastLabel,
+ 0 );
+ mv.visitLocalVariable( "buf",
+ Type.getDescriptor( StringBuffer.class ),
+ null,
+ l0,
+ lastLabel,
+ 1 );
+ }
+ mv.visitMaxs( 0,
+ 0 );
+ mv.visitEnd();
+ }
+ }
+
+ private Class loadClass(String classname,
+ byte[] b) throws ClassNotFoundException,
+ SecurityException,
+ NoSuchMethodException,
+ IllegalArgumentException,
+ IllegalAccessException,
+ InvocationTargetException {
+ this.classLoader.write( classname,
+ b );
+
+ return this.classLoader.loadClass( classname );
+ }
+
+ public ClassLoader getDynamicClassesClassLoader() {
+ return this.classLoader;
+ }
+
+ public class PackageClassLoader extends ClassLoader {
+ private Map store = new HashMap();
+
+ public PackageClassLoader(final ClassLoader parentClassLoader) {
+ super( parentClassLoader );
+ }
+
+ public Class fastFindClass(final String name) {
+ Class clazz = findLoadedClass( name );
+
+ if ( clazz == null ) {
+ final byte[] clazzBytes = read( name );
+ if ( clazzBytes != null ) {
+ java.lang.reflect.Method method = null;
+
+ try {
+ Class cls = Class.forName( "java.lang.ClassLoader" );
+ method = cls.getDeclaredMethod( "defineClass",
+ new Class[]{String.class, byte[].class, int.class, int.class} );
+
+ // protected method invocaton
+ method.setAccessible( true );
+ Object[] args = new Object[]{name, clazzBytes, new Integer( 0 ), new Integer( clazzBytes.length )};
+ clazz = (Class) method.invoke( this.getParent(),
+ args );
+ } catch( Exception e ) {
+ // not possible to load the class
+ } finally {
+ method.setAccessible( false );
+ }
+ }
+ }
+
+ return clazz;
+ }
+
+ /**
+ * Javadocs recommend that this method not be overloaded. We overload this so that we can prioritise the fastFindClass
+ * over method calls to parent.loadClass(name, false); and c = findBootstrapClass0(name); which the default implementation
+ * would first - hence why we call it "fastFindClass" instead of standard findClass, this indicates that we give it a
+ * higher priority than normal.
+ *
+ */
+ protected synchronized Class loadClass(final String name,
+ final boolean resolve) throws ClassNotFoundException {
+ Class clazz = fastFindClass( name );
+
+ if ( clazz == null ) {
+ final ClassLoader parent = getParent();
+ if ( parent != null ) {
+ clazz = parent.loadClass( name );
+ } else {
+ throw new ClassNotFoundException( name );
+ }
+ }
+
+ if ( resolve ) {
+ resolveClass( clazz );
+ }
+
+ return clazz;
+ }
+
+ protected Class findClass(final String name) throws ClassNotFoundException {
+ final Class clazz = fastFindClass( name );
+ if ( clazz == null ) {
+ throw new ClassNotFoundException( name );
+ }
+ return clazz;
+ }
+
+ public InputStream getResourceAsStream(final String name) {
+ final byte[] bytes = (byte[]) store.get( name );
+ if ( bytes != null ) {
+ return new ByteArrayInputStream( bytes );
+ } else {
+ return super.getResourceAsStream( name );
+ }
+ }
+
+ public byte[] read(final String resourceName) {
+ final byte[] bytes = null;
+
+ if ( this.store != null ) {
+ return (byte[]) this.store.get( resourceName.replace( '.',
+ '/' ) + ".class" );
+ }
+ return bytes;
+ }
+
+ public void write(final String resourceName,
+ final byte[] clazzData) throws RuntimeDroolsException {
+ this.store.put( resourceName.replace( '.',
+ '/' ) + ".class",
+ clazzData );
+ }
+ }
+
+}
Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassBuilder.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassDefinition.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassDefinition.java 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassDefinition.java 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,228 @@
+package com.sample;
+
+import java.beans.IntrospectionException;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Defines a class attributes and structure that will
+ * later be dynamically generated.
+ *
+ * @author <mailto:etirelli at redhat.com>Edson Tirelli</mailto>
+ *
+ */
+public class ClassDefinition {
+ private String className;
+ private String superClass;
+ private String[] interfaces;
+ private Class definedClass;
+
+ private Map<String, FieldDefinition> fields = new LinkedHashMap<String, FieldDefinition>();
+
+ public ClassDefinition(String className) {
+ this( className,
+ null,
+ null );
+ }
+
+ public ClassDefinition(String className,
+ String superClass) {
+ this( className,
+ superClass,
+ null );
+ }
+
+ public ClassDefinition(String className,
+ String[] interfaces) {
+ this( className,
+ null,
+ interfaces );
+ }
+
+ public ClassDefinition(String className,
+ String superClass,
+ String[] interfaces) {
+ this.setClassName( className );
+ this.setSuperClass( superClass );
+ this.setInterfaces( interfaces );
+ }
+
+ /**
+ * @return Returns the name.
+ */
+ public final String getClassName() {
+ return this.className;
+ }
+
+ /**
+ * @param name The name to set.
+ */
+ public final void setClassName(final String className) {
+ this.className = className;
+ }
+
+ /**
+ * @return the class name replacing '.' by '/'
+ */
+ final String getClassNameAsInternal() {
+ return this.getClassName().replace( '.',
+ '/' );
+ }
+
+ /**
+ * @return Returns the name.
+ */
+ public final String getInternalName() {
+ return "L" + this.getClassNameAsInternal() + ";";
+ }
+
+ /**
+ * @return Returns the className.
+ */
+ public final Class getDefinedClass() {
+ return definedClass;
+ }
+
+ /**
+ * @param className The className to set.
+ * @throws IntrospectionException
+ * @throws NoSuchFieldException
+ * @throws InvocationTargetException
+ * @throws NoSuchMethodException
+ * @throws ClassNotFoundException
+ * @throws IOException
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ * @throws IllegalArgumentException
+ * @throws SecurityException
+ */
+ final void setDefinedClass(final Class definedClass) throws IntrospectionException,
+ SecurityException,
+ IllegalArgumentException,
+ InstantiationException,
+ IllegalAccessException,
+ IOException,
+ ClassNotFoundException,
+ NoSuchMethodException,
+ InvocationTargetException,
+ NoSuchFieldException {
+
+ this.definedClass = definedClass;
+
+ if ( this.definedClass != null ) {
+ this.buildFieldAccessors();
+ }
+ }
+
+ /**
+ * Adds a field definition to this class
+ * @param attr
+ */
+ public final void addField(FieldDefinition attr) {
+ this.fields.put( attr.getName(),
+ attr );
+ }
+
+ /**
+ * @return Returns an unmodifiable collection of field definitions
+ */
+ public final Collection<FieldDefinition> getFields() {
+ return Collections.unmodifiableCollection( this.fields.values() );
+ }
+
+ /**
+ * Returns the field definition object for the given field name
+ *
+ * @param fieldName
+ * @return
+ */
+ public final FieldDefinition getField(final String fieldName) {
+ return this.fields.get( fieldName );
+ }
+
+ /**
+ * @param beanInfo The beanInfo to set.
+ * @throws NoSuchFieldException
+ * @throws InvocationTargetException
+ * @throws NoSuchMethodException
+ * @throws ClassNotFoundException
+ * @throws IntrospectionException
+ * @throws IOException
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ * @throws IllegalArgumentException
+ * @throws SecurityException
+ * @throws IntrospectionException
+ */
+ public final void buildFieldAccessors() throws SecurityException,
+ IllegalArgumentException,
+ InstantiationException,
+ IllegalAccessException,
+ IOException,
+ IntrospectionException,
+ ClassNotFoundException,
+ NoSuchMethodException,
+ InvocationTargetException,
+ NoSuchFieldException {
+ FieldAccessorBuilder builder = new FieldAccessorBuilder();
+
+ for ( FieldDefinition attrDef : this.fields.values() ) {
+ FieldAccessor accessor = (FieldAccessor) builder.buildAndLoadFieldAccessor( this.getDefinedClass(),
+ attrDef.getName() ).newInstance();
+ attrDef.setFieldAccessor( accessor );
+ }
+ }
+
+ /**
+ * @return Returns the interfaces.
+ */
+ public final String[] getInterfaces() {
+ return interfaces;
+ }
+
+ /**
+ * @param interfaces The interfaces to set.
+ */
+ public final void setInterfaces(String[] interfaces) {
+ this.interfaces = (interfaces != null) ? interfaces : new String[0];
+ }
+
+ /**
+ * @return
+ */
+ final String[] getInterfacesAsInternal() {
+ String[] interfaces = new String[this.interfaces.length];
+ for ( int i = 0; i < interfaces.length; i++ ) {
+ interfaces[i] = this.interfaces[i].replace( '.',
+ '/' );
+ }
+ return interfaces;
+ }
+
+ /**
+ * @return Returns the superClass.
+ */
+ public final String getSuperClass() {
+ return superClass;
+ }
+
+ /**
+ * @param superClass The superClass to set.
+ */
+ public final void setSuperClass(final String superClass) {
+ this.superClass = (superClass != null) ? superClass : "java/lang/Object";
+ }
+
+ /**
+ * @return Returns superclass name in the internal String representation
+ */
+ final String getSuperClassAsInternal() {
+ return this.superClass.replace( '.',
+ '/' );
+ }
+
+}
\ No newline at end of file
Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/ClassDefinition.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/Customer.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/Customer.java 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/Customer.java 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package com.sample;
+
+import java.io.Serializable;
+
+
+public class Customer
+ implements Serializable
+{
+
+ private static final long serialVersionUID = 1L;
+
+ long id;
+
+ String name;
+ Integer region;
+ Integer age;
+ Long income;
+
+ public Customer() {
+ }
+
+ public Customer(int id, String name, Integer region, Integer age, Long income) {
+ this.id = id;
+ this.name = name;
+ this.region = region;
+ this.age = age;
+ this.income = income;
+ }
+
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getRegion() {
+ return region;
+ }
+ public void setRegion(Integer region) {
+ this.region = region;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public Long getIncome() {
+ return income;
+ }
+ public void setIncome(Long income) {
+ this.income = income;
+ }
+
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + (int) (id ^ (id >>> 32));
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( getClass() != obj.getClass() ) return false;
+ final Customer other = (Customer) obj;
+ if ( id != other.id ) return false;
+ return true;
+ }
+
+}
Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/Customer.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/DroolsTest.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/DroolsTest.java 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/DroolsTest.java 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,162 @@
+package com.sample;
+
+import java.beans.IntrospectionException;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.WorkingMemory;
+import org.drools.compiler.PackageBuilder;
+import org.drools.reteoo.ReteooRuleBase;
+import org.drools.rule.Package;
+
+/**
+ * This is a sample file to launch a rule package from a rule source file.
+ */
+public class DroolsTest {
+
+ public static final void main(String[] args) {
+ try {
+ ClassBuilder builder = new ClassBuilder();
+ Thread.currentThread().setContextClassLoader( builder.getDynamicClassesClassLoader() );
+ Package pkg = new Package( "com.jbpm.action" );
+ PackageBuilder pkgBuilder = new PackageBuilder( pkg );
+ // Defining OrderLine
+ ClassDefinition lineitemClassDef = new ClassDefinition( "com.sample.LineItem" );
+ FieldDefinition lineId = new FieldDefinition( "lineId",
+ "int" );
+ lineId.setKey( true );
+ FieldDefinition product = new FieldDefinition( "product",
+ "java.lang.String" );
+ FieldDefinition amount = new FieldDefinition( "amount",
+ "double" );
+ FieldDefinition processed = new FieldDefinition( "processed",
+ "boolean" );
+ lineitemClassDef.addField( lineId );
+ lineitemClassDef.addField( product );
+ lineitemClassDef.addField( amount );
+ lineitemClassDef.addField( processed );
+ Class lineItemClass = defineAndLoadClass( pkgBuilder,
+ lineitemClassDef,
+ builder );
+ // Defining the class
+ ClassDefinition classdef = new ClassDefinition( "com.sample.Order" );
+ FieldDefinition orderId = new FieldDefinition( "orderId",
+ "int" );
+ orderId.setKey( true );
+ FieldDefinition customer = new FieldDefinition( "customer",
+ "com.sample.Customer" );
+ FieldDefinition lineItems = new FieldDefinition( "lineItems",
+ "java.util.List" );
+ FieldDefinition totalAmount = new FieldDefinition( "totalAmount",
+ "double" );
+ classdef.addField( orderId );
+ classdef.addField( customer );
+ classdef.addField( lineItems );
+ classdef.addField( totalAmount );
+ Class orderClass = defineAndLoadClass( pkgBuilder,
+ classdef,
+ builder );
+ //load up the rulebase
+ ReteooRuleBase ruleBase = (ReteooRuleBase) readRule( pkgBuilder );
+ WorkingMemory workingMemory = ruleBase.newWorkingMemory();
+ Object line1 = lineItemClass.newInstance();
+ lineId.setValue( line1,
+ 1 );
+ product.setValue( line1,
+ "cheese" );
+ amount.setValue( line1,
+ 25.10 );
+ Object line2 = lineItemClass.newInstance();
+ lineId.setValue( line2,
+ 2 );
+ product.setValue( line2,
+ "chocolate" );
+ amount.setValue( line2,
+ 12.50 );
+ List items = new ArrayList();
+ items.add( line1 );
+ items.add( line2 );
+ Customer cust = new Customer( 1,
+ "Fred",
+ new Integer( 5 ),
+ new Integer( 25 ),
+ new Long( 100000 ) );
+ // Instantiating the class
+ Object order = orderClass.newInstance();
+ orderId.setValue( order,
+ 10 );
+ customer.setValue( order,
+ cust );
+ lineItems.setValue( order,
+ items );
+ workingMemory.assertObject( order );
+ workingMemory.assertObject( cust );
+ workingMemory.assertObject( line1 );
+ workingMemory.assertObject( line2 );
+ workingMemory.fireAllRules();
+ } catch ( Exception e ) {
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * @param classdef
+ * @param builder
+ * @return
+ * @throws IOException
+ * @throws IntrospectionException
+ * @throws ClassNotFoundException
+ * @throws NoSuchMethodException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ * @throws InstantiationException
+ * @throws NoSuchFieldException
+ * @throws FileNotFoundException
+ */
+ private static Class defineAndLoadClass(PackageBuilder pkgBuilder,
+ ClassDefinition classdef,
+ ClassBuilder builder) throws IOException,
+ IntrospectionException,
+ ClassNotFoundException,
+ NoSuchMethodException,
+ IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException,
+ NoSuchFieldException,
+ FileNotFoundException {
+ // FileOutputStream fos = new FileOutputStream( "generated/"+ classdef.getClassNameAsInternal()+".class" );
+ // fos.write( generatedClass );
+ // fos.close();
+
+ // loading the class
+ Class orderClass = builder.buildAndLoadClass( classdef );
+ orderClass.getMethods();
+ return orderClass;
+ }
+
+ /**
+ * Please note that this is the "low level" rule assembly API.
+ */
+ private static RuleBase readRule(PackageBuilder builder) throws Exception {
+ //read in the source
+ Reader source = new InputStreamReader( DroolsTest.class.getResourceAsStream( "/Shipper.drl" ) );
+
+ builder.addPackageFromDrl( source );
+
+ Package pkg = builder.getPackage();
+
+ //add the package to a rulebase (deploy the rule package).
+ RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ ruleBase.addPackage( pkg );
+ return ruleBase;
+ }
+
+}
Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/DroolsTest.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessor.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessor.java 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessor.java 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,26 @@
+package com.sample;
+
+/**
+ * An interface for dynamically generated FieldAccessor classes </p>
+ *
+ * @author etirelli
+ */
+public interface FieldAccessor {
+
+ /**
+ * Sets the attribute value in the given instance
+ *
+ * @param instance
+ * @param value
+ */
+ public void setValue(Object instance, Object value);
+
+ /**
+ * Gets the attribute value in the given instance
+ *
+ * @param instance
+ * @return
+ */
+ public Object getValue(Object instance);
+
+}
Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessor.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessorBuilder.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessorBuilder.java 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessorBuilder.java 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,406 @@
+package com.sample;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A builder for FieldAccessor instances
+ *
+ * @author <mailto:etirelli at redhat.com>Edson Tirelli</mailto>
+ *
+ */
+public class FieldAccessorBuilder {
+ private Map typeMap = null;
+
+ public FieldAccessorBuilder() {
+ typeMap = new HashMap();
+ typeMap.put( Boolean.TYPE,
+ Boolean.class );
+ typeMap.put( Byte.TYPE,
+ Byte.class );
+ typeMap.put( Character.TYPE,
+ Character.class );
+ typeMap.put( Double.TYPE,
+ Double.class );
+ typeMap.put( Float.TYPE,
+ Float.class );
+ typeMap.put( Integer.TYPE,
+ Integer.class );
+ typeMap.put( Long.TYPE,
+ Long.class );
+ typeMap.put( Short.TYPE,
+ Short.class );
+ typeMap.put( Void.TYPE,
+ Void.class );
+ }
+
+ public Class buildAndLoadFieldAccessor(Class clazz,
+ String fieldName) throws SecurityException,
+ IllegalArgumentException,
+ IOException,
+ IntrospectionException,
+ ClassNotFoundException,
+ NoSuchMethodException,
+ IllegalAccessException,
+ InvocationTargetException,
+ NoSuchFieldException {
+
+ ClassDefinition accClass = new ClassDefinition( clazz.getName() + fieldName.substring( 0,
+ 1 ).toUpperCase() + fieldName.substring( 1 ) + "FA" );
+ try {
+ return Class.forName( accClass.getClassName() );
+ } catch ( ClassNotFoundException e ) {
+ byte[] serializedClazz = this.buildFieldAccessor( clazz,
+ fieldName );
+ Class newClazz = this.loadClass( accClass.getClassName(),
+ serializedClazz );
+ return newClazz;
+ }
+ }
+
+ /**
+ * Dinamically builds, defines and loads a field accessor class for the given field
+ *
+ * @param class the class to build the field accessor for
+ * @param fieldName the name of the field to build the field accessor for
+ *
+ * @return the Class instance for the given class definition
+ *
+ * @throws IOException
+ * @throws IntrospectionException
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
+ * @throws NoSuchMethodException
+ * @throws ClassNotFoundException
+ * @throws IllegalArgumentException
+ * @throws SecurityException
+ * @throws NoSuchFieldException
+ */
+ public byte[] buildFieldAccessor(Class clazz,
+ String fieldName) throws IOException,
+ IntrospectionException,
+ SecurityException,
+ IllegalArgumentException,
+ ClassNotFoundException,
+ NoSuchMethodException,
+ IllegalAccessException,
+ InvocationTargetException,
+ NoSuchFieldException {
+
+ ClassDefinition accClass = new ClassDefinition( clazz.getName() + fieldName.substring( 0,
+ 1 ).toUpperCase() + fieldName.substring( 1 ) + "FA" );
+ accClass.setInterfaces( new String[]{FieldAccessor.class.getName()} );
+ accClass.setSuperClass( Object.class.getName() );
+
+ PropertyDescriptor field = getPropertyDescriptor( clazz,
+ fieldName );
+
+ ClassWriter cw = new ClassWriter( ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES );
+
+ this.buildClassHeader( cw,
+ accClass );
+
+ // Building default constructor
+ this.buildDefaultConstructor( cw );
+
+ // Building methods
+ this.buildGetMethod( cw,
+ accClass,
+ clazz,
+ field );
+ this.buildSetMethod( cw,
+ accClass,
+ clazz,
+ field );
+
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+
+ /**
+ * @param clazz
+ * @param fieldName
+ * @param field
+ * @return
+ * @throws IntrospectionException
+ * @throws NoSuchFieldException
+ */
+ private PropertyDescriptor getPropertyDescriptor(Class clazz,
+ String fieldName) throws IntrospectionException,
+ NoSuchFieldException {
+ PropertyDescriptor field = null;
+ PropertyDescriptor[] propDescr = Introspector.getBeanInfo( clazz ).getPropertyDescriptors();
+ for ( int i = 0; i < propDescr.length; i++ ) {
+ if ( fieldName.equals( propDescr[i].getName() ) ) {
+ field = propDescr[i];
+ break;
+ }
+ }
+ if ( field == null ) {
+ throw new NoSuchFieldException( "Field [" + fieldName + "] not found in class [" + clazz.getName() + "]" );
+ }
+ return field;
+ }
+
+ /**
+ * Defines the class header for the given class definition
+ *
+ * @param cw
+ * @param dimDef
+ */
+ private void buildClassHeader(ClassWriter cw,
+ ClassDefinition classDef) {
+ // Building class header
+ cw.visit( Opcodes.V1_4,
+ Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
+ classDef.getClassNameAsInternal(),
+ null,
+ classDef.getSuperClassAsInternal(),
+ classDef.getInterfacesAsInternal() );
+
+ cw.visitSource( classDef.getClassName() + ".java",
+ null );
+ }
+
+ /**
+ * Creates the get method for the given field definition
+ *
+ * @param cw
+ * @param classDef
+ * @param fieldDef
+ */
+ private void buildGetMethod(ClassWriter cw,
+ ClassDefinition classDef,
+ Class clazz,
+ PropertyDescriptor field) {
+ MethodVisitor mv;
+ // Get method
+ {
+ mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+ "getValue",
+ Type.getMethodDescriptor( Type.getType( Object.class ),
+ new Type[]{Type.getType( Object.class )} ),
+ null,
+ null );
+ mv.visitCode();
+ if ( field.getPropertyType().isPrimitive() ) {
+ mv.visitTypeInsn( Opcodes.NEW,
+ Type.getInternalName( (Class) typeMap.get( field.getPropertyType() ) ) );
+ mv.visitInsn( Opcodes.DUP );
+ }
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 1 );
+ mv.visitTypeInsn( Opcodes.CHECKCAST,
+ Type.getInternalName( clazz ) );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ Type.getInternalName( clazz ),
+ field.getReadMethod().getName(),
+ Type.getMethodDescriptor( Type.getType( field.getPropertyType() ),
+ new Type[]{} ) );
+
+ if ( field.getPropertyType().isPrimitive() ) {
+ mv.visitMethodInsn( Opcodes.INVOKESPECIAL,
+ Type.getInternalName( (Class) typeMap.get( field.getPropertyType() ) ),
+ "<init>",
+ Type.getMethodDescriptor( Type.VOID_TYPE,
+ new Type[]{Type.getType( field.getPropertyType() )} ) );
+ }
+ mv.visitInsn( Opcodes.ARETURN );
+ mv.visitMaxs( 0,
+ 0 ); // automatically calculated
+ mv.visitEnd();
+ }
+ }
+
+ /**
+ * Creates the set method for the given field definition
+ *
+ * @param cw
+ * @param classDef
+ * @param fieldDef
+ */
+ private void buildSetMethod(ClassWriter cw,
+ ClassDefinition classDef,
+ Class clazz,
+ PropertyDescriptor field) {
+ MethodVisitor mv;
+ // set method
+ {
+ mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+ "setValue",
+ Type.getMethodDescriptor( Type.VOID_TYPE,
+ new Type[]{Type.getType( Object.class ), Type.getType( Object.class )} ),
+ null,
+ null );
+
+ mv.visitCode();
+
+ if ( field.getPropertyType().isPrimitive() ) {
+ // value != null ?
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 2 );
+
+ Label ifnull = new Label();
+ mv.visitJumpInsn( Opcodes.IFNULL,
+ ifnull );
+
+ // ((PrimitiveWrapper)value).xxxValue() :
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 2 );
+ mv.visitTypeInsn( Opcodes.CHECKCAST,
+ Type.getInternalName( (Class) typeMap.get( field.getPropertyType() ) ) );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ Type.getInternalName( (Class) typeMap.get( field.getPropertyType() ) ),
+ field.getPropertyType().getName() + "Value",
+ Type.getMethodDescriptor( Type.getType( field.getPropertyType() ),
+ new Type[]{} ) );
+
+ Label afterif = new Label();
+ mv.visitJumpInsn( Opcodes.GOTO,
+ afterif );
+
+ // 0
+ mv.visitLabel( ifnull );
+ if ( field.getPropertyType().isAssignableFrom( long.class ) ) {
+ mv.visitInsn( Opcodes.LCONST_0 );
+ } else if ( field.getPropertyType().isAssignableFrom( double.class ) ) {
+ mv.visitInsn( Opcodes.DCONST_0 );
+ } else if ( field.getPropertyType().isAssignableFrom( float.class ) ) {
+ mv.visitInsn( Opcodes.FCONST_0 );
+ } else {
+ mv.visitInsn( Opcodes.ICONST_0 );
+ }
+
+ // localVar = pop()
+ mv.visitLabel( afterif );
+ mv.visitVarInsn( Type.getType( field.getPropertyType() ).getOpcode( Opcodes.ISTORE ),
+ 3 );
+ } else {
+ // localVar = (xxxClass) value
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 2 );
+ mv.visitTypeInsn( Opcodes.CHECKCAST,
+ Type.getInternalName( field.getPropertyType() ) );
+ mv.visitVarInsn( Opcodes.ASTORE,
+ 3 );
+ }
+
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 1 );
+ mv.visitTypeInsn( Opcodes.CHECKCAST,
+ Type.getInternalName( clazz ) );
+ mv.visitVarInsn( Type.getType( field.getPropertyType() ).getOpcode( Opcodes.ILOAD ),
+ 3 );
+
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ Type.getInternalName( clazz ),
+ field.getWriteMethod().getName(),
+ Type.getMethodDescriptor( Type.VOID_TYPE,
+ new Type[]{Type.getType( field.getPropertyType() )} ) );
+
+ mv.visitInsn( Opcodes.RETURN );
+ mv.visitMaxs( 0,
+ 0 ); // auto calculated
+ mv.visitEnd();
+ }
+ }
+
+ /**
+ * Creates a default constructor for the class
+ *
+ * @param cw
+ */
+ private void buildDefaultConstructor(ClassWriter cw) {
+ MethodVisitor mv;
+ // Building default constructor
+ {
+ mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+ "<init>",
+ Type.getMethodDescriptor( Type.VOID_TYPE,
+ new Type[]{} ),
+ null,
+ null );
+ mv.visitCode();
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitMethodInsn( Opcodes.INVOKESPECIAL,
+ Type.getInternalName( Object.class ),
+ "<init>",
+ Type.getMethodDescriptor( Type.VOID_TYPE,
+ new Type[]{} ) );
+ mv.visitInsn( Opcodes.RETURN );
+ mv.visitMaxs( 0,
+ 0 );
+ mv.visitEnd();
+ }
+ }
+
+ private Class loadClass(String classname,
+ byte[] b) throws ClassNotFoundException,
+ SecurityException,
+ NoSuchMethodException,
+ IllegalArgumentException,
+ IllegalAccessException,
+ InvocationTargetException {
+ //override classDefine (as it is protected) and define the class.
+ Class clazz = null;
+ ClassLoader loader = FieldAccessorBuilder.class.getClassLoader();
+ Class cls = Class.forName( "java.lang.ClassLoader" );
+ java.lang.reflect.Method method = cls.getDeclaredMethod( "defineClass",
+ new Class[]{String.class, byte[].class, int.class, int.class} );
+
+ // protected method invocaton
+ method.setAccessible( true );
+ try {
+ Object[] args = new Object[]{classname, b, new Integer( 0 ), new Integer( b.length )};
+ clazz = (Class) method.invoke( loader,
+ args );
+ } finally {
+ method.setAccessible( false );
+ }
+ return clazz;
+ }
+
+ /**
+ * Creates the String name for the get method for a field with the given name and type
+ * @param name
+ * @param type
+ * @return
+ */
+ public String getReadMethod(Field field) {
+ String prefix = null;
+ if ( Boolean.TYPE.equals( field.getType() ) ) {
+ prefix = "is";
+ } else {
+ prefix = "get";
+ }
+ return prefix + field.getName().substring( 0,
+ 1 ).toUpperCase() + field.getName().substring( 1 );
+ }
+
+ /**
+ * Creates the String name for the set method for a field with the given name and type
+ *
+ * @param name
+ * @param type
+ * @return
+ */
+ public String getWriteMethod(Field field) {
+ return "set" + field.getName().substring( 0,
+ 1 ).toUpperCase() + field.getName().substring( 1 );
+ }
+
+}
Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldAccessorBuilder.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldDefinition.java
===================================================================
--- labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldDefinition.java 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldDefinition.java 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,279 @@
+package com.sample;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Declares a field that will later be added to a dynamically
+ * generated class.
+ *
+ * @author <mailto:etirelli at redhat.com>Edson Tirelli</mailto>
+ *
+ */
+public class FieldDefinition {
+ private String name = null;
+ private String type = null;
+ private boolean key = false;
+
+ private String internalType = null;
+ private String boxTypeName = null;
+ private boolean primitive = false;
+ private String unboxMethod = null;
+ private FieldAccessor accessor = null;
+
+ /**
+ * Default constructor
+ *
+ * @param name the field's name
+ * @param type the fully qualified fields type
+ */
+ public FieldDefinition(String name,
+ String type) {
+ this(name, type, false);
+ }
+
+ /**
+ * Default constructor
+ *
+ * @param name the field's name
+ * @param type the fully qualified fields type
+ */
+ public FieldDefinition(String name,
+ String type,
+ boolean key) {
+ this.name = name;
+ this.type = type;
+ this.key = key;
+ this.setInternals();
+ }
+
+ /**
+ * @return Returns the name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the name of the field
+ * @param name The name to be set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return Returns the fully qualified type.
+ */
+ public String getType() {
+ return this.type;
+ }
+
+ /**
+ * @param type The fully qualified type to set.
+ */
+ public void setType(String type) {
+ this.type = type;
+ this.setInternals();
+ }
+
+ /**
+ * @return Returns the fully qualified internal type representation
+ */
+ String getInternalType() {
+ return this.internalType;
+ }
+
+ String getBoxTypeName() {
+ return this.boxTypeName;
+ }
+
+ /**
+ * @return Returns the primitive.
+ */
+ boolean isPrimitive() {
+ return primitive;
+ }
+
+ /**
+ * @return Returns the unboxMethod.
+ */
+ String getUnboxMethod() {
+ return unboxMethod;
+ }
+
+ /**
+ * @return Returns the key.
+ */
+ public boolean isKey() {
+ return key;
+ }
+
+ /**
+ * If set to true, this field will be used as part of the
+ * primary key for the created class. It means, it will
+ * be included in the equals()/hashcode() verification
+ *
+ * @param key The key to set.
+ */
+ public void setKey(boolean key) {
+ this.key = key;
+ }
+
+ /**
+ * Creates the String name for the get method for a field with the given name and type
+ * @param name
+ * @param type
+ * @return
+ */
+ public String getReadMethod() {
+ String prefix = null;
+ if ( "boolean".equals( this.type ) ) {
+ prefix = "is";
+ } else {
+ prefix = "get";
+ }
+ return prefix + this.name.substring( 0,
+ 1 ).toUpperCase() + this.name.substring( 1 );
+ }
+
+ /**
+ * Creates the String name for the set method for a field with the given name and type
+ *
+ * @param name
+ * @param type
+ * @return
+ */
+ public String getWriteMethod() {
+ return "set" + this.name.substring( 0,
+ 1 ).toUpperCase() + this.name.substring( 1 );
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public boolean equals(Object o) {
+ return this.getName().equals( ((FieldDefinition) o).getName() );
+ }
+
+ /**
+ * @return Returns the field accessor
+ */
+ FieldAccessor getFieldAccessor() {
+ return this.accessor;
+ }
+
+ /**
+ * @param property The property descriptor to set.
+ */
+ void setFieldAccessor(FieldAccessor accessor) {
+ this.accessor = accessor;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public int hashCode() {
+ return this.getName().hashCode();
+ }
+
+ /**
+ * Sets the value of this attribute in the target
+ * bean instance
+ *
+ * @param bean the target bean instance where the attribute shall be set
+ * @param value the value to set the attribute to
+ *
+ * @throws IllegalArgumentException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+ public void setValue(Object bean,
+ Object value) throws IllegalArgumentException,
+ IllegalAccessException,
+ InvocationTargetException {
+ if(this.accessor == null) {
+ System.out.println("ACCESSOR NULL");
+ }
+ this.accessor.setValue( bean, value );
+ }
+
+ /**
+ * Returns the value of this attribute in the target bean instance
+ *
+ * @param bean the target bean instance
+ *
+ * @return target bean instance attribute value
+ *
+ * @throws IllegalArgumentException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+ public Object getValue(Object bean) throws IllegalArgumentException,
+ IllegalAccessException,
+ InvocationTargetException {
+ return this.accessor.getValue( bean );
+ }
+
+ /**
+ * Creates the internal string representation of this attribute's type
+ *
+ * @param type
+ * @return
+ */
+ private void setInternals() {
+ if ( "byte".equals( this.type ) ) {
+ this.internalType = "B";
+ this.boxTypeName = "java/lang/Byte";
+ this.primitive = true;
+ this.unboxMethod = "byteValue";
+ } else if ( "char".equals( type ) ) {
+ this.internalType = "C";
+ this.boxTypeName = "java/lang/Character";
+ this.primitive = true;
+ this.unboxMethod = "charValue";
+ } else if ( "double".equals( type ) ) {
+ this.internalType = "D";
+ this.boxTypeName = "java/lang/Double";
+ this.primitive = true;
+ this.unboxMethod = "doubleValue";
+ } else if ( "float".equals( type ) ) {
+ this.internalType = "F";
+ this.boxTypeName = "java/lang/Float";
+ this.primitive = true;
+ this.unboxMethod = "floatValue";
+ } else if ( "int".equals( type ) ) {
+ this.internalType = "I";
+ this.boxTypeName = "java/lang/Integer";
+ this.primitive = true;
+ this.unboxMethod = "intValue";
+ } else if ( "long".equals( type ) ) {
+ this.internalType = "J";
+ this.boxTypeName = "java/lang/Long";
+ this.primitive = true;
+ this.unboxMethod = "longValue";
+ } else if ( "short".equals( type ) ) {
+ this.internalType = "S";
+ this.boxTypeName = "java/lang/Short";
+ this.primitive = true;
+ this.unboxMethod = "shortValue";
+ } else if ( "boolean".equals( type ) ) {
+ this.internalType = "Z";
+ this.boxTypeName = "java/lang/Boolean";
+ this.primitive = true;
+ this.unboxMethod = "booleanValue";
+ } else if ( "void".equals( type ) ) {
+ this.internalType = "V";
+ this.boxTypeName = "java/lang/Void";
+ this.primitive = true;
+ this.unboxMethod = null;
+ } else if ( type != null ) {
+ this.internalType = "L" + type.replace( '.',
+ '/' ) + ";";
+ this.boxTypeName = type.replace( '.',
+ '/' );
+ this.primitive = false;
+ this.unboxMethod = null;
+ }
+ }
+
+}
\ No newline at end of file
Property changes on: labs/jbossrules/contrib/dynamic/src/java/com/sample/FieldDefinition.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/contrib/dynamic/src/rules/Shipper.drl
===================================================================
--- labs/jbossrules/contrib/dynamic/src/rules/Shipper.drl 2006-12-10 17:55:44 UTC (rev 8180)
+++ labs/jbossrules/contrib/dynamic/src/rules/Shipper.drl 2006-12-10 19:25:46 UTC (rev 8181)
@@ -0,0 +1,45 @@
+package com.jbpm.action
+
+import com.sample.Customer;
+import com.sample.Order;
+import com.sample.LineItem;
+
+rule "Total order"
+ salience 10
+ when
+ $item : LineItem( $amount : amount, processed == false );
+ $order: Order( lineItems contains $item )
+ then
+ System.out.println("Adding "+$item.getAmount()+" to the total amount");
+ $order.setTotalAmount( $order.getTotalAmount() + $item.getAmount() );
+ $item.setProcessed( true );
+ modify( $order );
+ modify( $item );
+end
+
+rule "Show total"
+ salience 5
+ when
+ $order: Order( )
+ then
+ System.out.println("Total: "+$order.getTotalAmount());
+end
+
+
+rule "Shipper FEDX"
+ when
+ $cust : Customer( region >= 1 )
+ $order : Order( customer == $cust, totalAmount > 30 )
+ then
+ System.out.println("TotalAmount: "+$order.getTotalAmount()+" -> ship via FEDX " );
+
+end
+
+rule "Shipper USPS"
+ when
+ $cust : Customer( region >= 1 )
+ $order : Order( customer == $cust, totalAmount <= 30 )
+ then
+ System.out.println("TotalAmount: "+$order.getTotalAmount()+" -> ship via USPS" );
+
+end
Property changes on: labs/jbossrules/contrib/dynamic/src/rules/Shipper.drl
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:eol-style
+ native
More information about the jboss-svn-commits
mailing list