[jboss-svn-commits] JBL Code SVN: r19944 - in labs/jbossrules/trunk/drools-compiler/src: main/java/org/drools/lang/descr and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed May 14 03:46:05 EDT 2008


Author: michael.neale at jboss.com
Date: 2008-05-14 03:46:05 -0400 (Wed, 14 May 2008)
New Revision: 19944

Modified:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/TypeDeclarationDescr.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/TypeFieldDescr.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java
Log:
integrating class generator

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java	2008-05-14 07:36:29 UTC (rev 19943)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java	2008-05-14 07:46:05 UTC (rev 19944)
@@ -2,13 +2,13 @@
 
 /*
  * Copyright 2005 JBoss Inc
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,12 +22,16 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.drools.base.ClassFieldExtractorCache;
 import org.drools.base.ClassTypeResolver;
 import org.drools.base.TypeResolver;
 import org.drools.commons.jci.problems.CompilationProblem;
+import org.drools.factmodel.ClassBuilder;
+import org.drools.factmodel.ClassDefinition;
+import org.drools.factmodel.FieldDefinition;
 import org.drools.facttemplates.FactTemplate;
 import org.drools.facttemplates.FactTemplateImpl;
 import org.drools.facttemplates.FieldTemplate;
@@ -44,9 +48,11 @@
 import org.drools.lang.descr.QueryDescr;
 import org.drools.lang.descr.RuleDescr;
 import org.drools.lang.descr.TypeDeclarationDescr;
+import org.drools.lang.descr.TypeFieldDescr;
 import org.drools.process.core.Process;
+import org.drools.rule.CompositePackageClassLoader;
 import org.drools.rule.ImportDeclaration;
-import org.drools.rule.JavaDialectData;
+import org.drools.rule.MapBackedClassLoader;
 import org.drools.rule.Package;
 import org.drools.rule.Rule;
 import org.drools.rule.TypeDeclaration;
@@ -61,11 +67,11 @@
  * This is the main compiler class for parsing and compiling rules and
  * assembling or merging them into a binary Package instance. This can be done
  * by merging into existing binary packages, or totally from source.
- * 
- * If you are using the Java dialect the JavaDialectConfiguration will attempt to 
- * validate that the specified compiler is in the classpath, using ClassLoader.loasClass(String). 
- * If you intented to just Janino sa the compiler you must either overload the compiler 
- * property before instantiating this class or the PackageBuilder, or make sure Eclipse is in the 
+ *
+ * If you are using the Java dialect the JavaDialectConfiguration will attempt to
+ * validate that the specified compiler is in the classpath, using ClassLoader.loasClass(String).
+ * If you intented to just Janino sa the compiler you must either overload the compiler
+ * property before instantiating this class or the PackageBuilder, or make sure Eclipse is in the
  * classpath, as Eclipse is the default.
  */
 public class PackageBuilder {
@@ -86,6 +92,8 @@
 
     private DialectRegistry             dialectRegistry;
 
+	private MapBackedClassLoader generatedBeanClassLoader;
+
     /**
      * Use this when package is starting from scratch.
      */
@@ -105,11 +113,11 @@
 
     /**
      * Pass a specific configuration for the PackageBuilder
-     * 
-     * PackageBuilderConfiguration is not thread safe and it also contains state. Once it is created and used 
-     * in one or more PackageBuilders it should be considered immutable. Do not modify its 
+     *
+     * PackageBuilderConfiguration is not thread safe and it also contains state. Once it is created and used
+     * in one or more PackageBuilders it should be considered immutable. Do not modify its
      * properties while it is being used by a PackageBuilder.
-     * 
+     *
      * @param configuration
      */
     public PackageBuilder(final PackageBuilderConfiguration configuration) {
@@ -120,7 +128,7 @@
     /**
      * This allows you to pass in a pre existing package, and a configuration
      * (for instance to set the classloader).
-     * 
+     *
      * @param pkg
      *            A pre existing package (can be null if none exists)
      * @param configuration
@@ -138,17 +146,19 @@
         this.classFieldExtractorCache = ClassFieldExtractorCache.getInstance();
 
         if ( this.pkg != null ) {
-            this.typeResolver = new ClassTypeResolver( new HashSet<String>( this.pkg.getImports().keySet() ),
-                                                       this.configuration.getClassLoader() );
+        	ClassLoader cl = this.pkg.getDialectDatas().getClassLoader();
+            this.typeResolver = new ClassTypeResolver( new HashSet<String>( this.pkg.getImports().keySet() ), cl );
             // make an automatic import for the current package
             this.typeResolver.addImport( this.pkg.getName() + ".*" );
         } else {
-            this.typeResolver = new ClassTypeResolver( new HashSet<String>(),
-                                                       this.configuration.getClassLoader() );
+//            this.typeResolver = new ClassTypeResolver( new HashSet<String>(),
+//                                                       this.configuration.getClassLoader() );
         }
 
         this.dialectRegistry = this.configuration.buildDialectRegistry();
 
+
+
         this.dialect = this.dialectRegistry.getDialect( this.configuration.getDefaultDialect() );
 
         if ( this.pkg != null ) {
@@ -159,7 +169,7 @@
 
     /**
      * Load a rule package from DRL source.
-     * 
+     *
      * @param reader
      * @throws DroolsParserException
      * @throws IOException
@@ -174,7 +184,7 @@
 
     /**
      * Load a rule package from XML source.
-     * 
+     *
      * @param reader
      * @throws DroolsParserException
      * @throws IOException
@@ -195,7 +205,7 @@
 
     /**
      * Load a rule package from DRL source using the supplied DSL configuration.
-     * 
+     *
      * @param source
      *            The source of the rules.
      * @param dsl
@@ -360,6 +370,11 @@
         this.pkg = new Package( packageDescr.getName(),
                                 this.configuration.getClassLoader() );
 
+       ClassLoader cl = this.pkg.getDialectDatas().getClassLoader();
+
+
+       this.typeResolver = new ClassTypeResolver( new HashSet<String>(), cl );
+
         this.typeResolver.addImport( this.pkg.getName() + ".*" );
 
         this.dialectRegistry.initAll( this );
@@ -437,12 +452,17 @@
                 type.setFormat( TypeDeclaration.Format.POJO );
                 Class clazz;
                 try {
+                	if (typeDescr.getFields().size() > 0) {
+                		//generate the bean if its needed
+                		generateDeclaredBean(typeDescr);
+                	}
                     clazz = typeResolver.resolveType( className );
                     type.setTypeClass( clazz );
                 } catch ( final ClassNotFoundException e ) {
-                    this.results.add( new TypeDeclarationError( "Class not found '" + className + "' for type '" + type.getTypeName() + "'",
-                                                                typeDescr.getLine() ) );
-                    continue;
+
+	                    this.results.add( new TypeDeclarationError( "Class not found '" + className + "' for type '" + type.getTypeName() + "'",
+	                                                                typeDescr.getLine() ) );
+	                    continue;
                 }
             }
 
@@ -463,7 +483,33 @@
         }
     }
 
-    private void addFunction(final FunctionDescr functionDescr) {
+    /**
+     * Generates a bean, and adds it to the composite class loader that
+     * everything is using.
+     *
+     */
+    private void generateDeclaredBean(TypeDeclarationDescr typeDescr) {
+    	ClassBuilder cb = new ClassBuilder();
+    	String fullName = this.pkg.getName() + "." + typeDescr.getTypeName();
+    	ClassDefinition def = new ClassDefinition(fullName);
+    	Map<String, TypeFieldDescr> flds = typeDescr.getFields();
+    	for (TypeFieldDescr field : flds.values()) {
+			def.addField(new FieldDefinition(field.getFieldName(), field.getPattern().getObjectType()));
+		}
+    	try {
+	    	byte[] d = cb.buildClass(def);
+	    	if (this.generatedBeanClassLoader == null) {
+	    		this.generatedBeanClassLoader = new MapBackedClassLoader(this.configuration.getClassLoader());
+	    		CompositePackageClassLoader ccl = (CompositePackageClassLoader) this.pkg.getDialectDatas().getClassLoader();
+	    		ccl.addClassLoader(this.generatedBeanClassLoader);
+	    	}
+	    	generatedBeanClassLoader.addClass(fullName, d);
+    	} catch (Exception e) {
+    		this.results.add(new TypeDeclarationError("Unable to create a class for declared type " + typeDescr.getTypeName(), typeDescr.getLine()));
+    	}
+	}
+
+	private void addFunction(final FunctionDescr functionDescr) {
         this.dialect.addFunction( functionDescr,
                                   getTypeResolver() );
     }
@@ -536,7 +582,7 @@
      *         can report on by calling getErrors or printErrors. If you try to
      *         add an invalid package (or rule) to a RuleBase, you will get a
      *         runtime exception.
-     * 
+     *
      * Compiled packages are serializable.
      */
     public Package getPackage() {
@@ -624,7 +670,7 @@
      * report a compile error of its type, should it happen. This is needed, as
      * the compiling is done as one hit at the end, and we need to be able to
      * work out what rule/ast element caused the error.
-     * 
+     *
      * An error handler it created for each class task that is queued to be
      * compiled. This doesn't mean an error has occurred, it just means it *may*
      * occur in the future and we need to be able to map it back to the AST
@@ -648,7 +694,7 @@
         }
 
         /**
-         * 
+         *
          * @return A DroolsError object populated as appropriate, should the
          *         unthinkable happen and this need to be reported.
          */

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/TypeDeclarationDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/TypeDeclarationDescr.java	2008-05-14 07:36:29 UTC (rev 19943)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/TypeDeclarationDescr.java	2008-05-14 07:46:05 UTC (rev 19944)
@@ -21,7 +21,7 @@
 import java.util.Map;
 
 public class TypeDeclarationDescr extends BaseDescr {
-    
+
     private static final long   serialVersionUID = 400L;
     private String              typeName;
     private Map<String, String> metaAttributes;
@@ -30,7 +30,7 @@
     public TypeDeclarationDescr() {
         this(null);
     }
-    
+
     public TypeDeclarationDescr(final String typeName) {
         this.typeName = typeName;
         this.metaAttributes = new HashMap<String, String>();
@@ -49,7 +49,7 @@
     public void setTypeName(String typeName) {
         this.typeName = typeName;
     }
-    
+
     /**
      * Adds a new attribute
      * @param attr
@@ -61,7 +61,7 @@
         }
         this.metaAttributes.put( attr, value );
     }
-    
+
     /**
      * Returns an attribute value or null if it is not defined
      * @param attr
@@ -92,7 +92,7 @@
     public void setFields(Map<String, TypeFieldDescr> fields) {
         this.fields = fields;
     }
-    
+
     public void addField( TypeFieldDescr field ) {
         if( this.fields == null ) {
             this.fields = new HashMap<String, TypeFieldDescr>();
@@ -104,4 +104,5 @@
         return "TypeDeclaration[ "+this.getTypeName()+" ]";
     }
 
+
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/TypeFieldDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/TypeFieldDescr.java	2008-05-14 07:36:29 UTC (rev 19943)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/TypeFieldDescr.java	2008-05-14 07:46:05 UTC (rev 19944)
@@ -36,6 +36,11 @@
         this.metaAttributes = new HashMap<String, String>();
     }
 
+    public TypeFieldDescr(final String fieldName, final PatternDescr pat) {
+    	this(fieldName);
+    	this.pattern = pat;
+    }
+
     /**
      * @return the identifier
      */

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java	2008-05-14 07:36:29 UTC (rev 19943)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java	2008-05-14 07:46:05 UTC (rev 19944)
@@ -66,6 +66,7 @@
 import org.drools.lang.descr.RuleDescr;
 import org.drools.lang.descr.SlidingWindowDescr;
 import org.drools.lang.descr.TypeDeclarationDescr;
+import org.drools.lang.descr.TypeFieldDescr;
 import org.drools.lang.descr.VariableRestrictionDescr;
 import org.drools.process.core.Context;
 import org.drools.process.core.Process;
@@ -1043,6 +1044,40 @@
                       type.getTypeClass() );
     }
 
+    public void testTypeDeclarationNewBean() throws Exception {
+        PackageDescr pkgDescr = new PackageDescr( "org.test" );
+        TypeDeclarationDescr typeDescr = new TypeDeclarationDescr( "NewBean" );
+
+        TypeFieldDescr f1 = new TypeFieldDescr("name", new PatternDescr("String"));
+        TypeFieldDescr f2 = new TypeFieldDescr("age", new PatternDescr("int"));
+
+        typeDescr.addField(f1);
+        typeDescr.addField(f2);
+
+        pkgDescr.addTypeDeclaration( typeDescr );
+
+        PackageBuilder builder = new PackageBuilder();
+        builder.addPackage( pkgDescr );
+
+        Package pkg = builder.getPackage();
+        assertEquals( 1,
+                      pkg.getTypeDeclarations().size() );
+
+        TypeDeclaration type = pkg.getTypeDeclaration( "NewBean" );
+        assertEquals( "NewBean",
+                      type.getTypeName() );
+        assertEquals( TypeDeclaration.Role.FACT,
+                      type.getRole() );
+        assertEquals( "org.test.NewBean",
+                      type.getTypeClass().getName() );
+        assertFalse(builder.hasErrors());
+
+        Package bp = builder.getPackage();
+        Class newBean = bp.getDialectDatas().getClassLoader().loadClass("org.test.NewBean");
+        assertNotNull(newBean);
+    }
+
+
     public void testPackageMerge() throws Exception {
         final PackageBuilder builder = new PackageBuilder();
         try {




More information about the jboss-svn-commits mailing list