[jboss-svn-commits] JBL Code SVN: r10086 - in labs/jbossrules/trunk: drools-jbrms/src/main/java/org/drools/brms/client/modeldriven and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Mar 8 19:25:07 EST 2007


Author: tirelli
Date: 2007-03-08 19:25:07 -0500 (Thu, 08 Mar 2007)
New Revision: 10086

Added:
   labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/resource/util/ByteArrayClassLoader.java
Modified:
   labs/jbossrules/trunk/drools-jbrms/pom.xml
   labs/jbossrules/trunk/drools-jbrms/src/main/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngine.java
   labs/jbossrules/trunk/drools-jbrms/src/main/java/org/drools/brms/server/rules/SuggestionCompletionLoader.java
Log:
JBRULES-629, JBRULES-728: populating SuggestionCompletionEngine with globals, DSL sentences and Classes from the models.



Modified: labs/jbossrules/trunk/drools-jbrms/pom.xml
===================================================================
--- labs/jbossrules/trunk/drools-jbrms/pom.xml	2007-03-08 21:38:17 UTC (rev 10085)
+++ labs/jbossrules/trunk/drools-jbrms/pom.xml	2007-03-09 00:25:07 UTC (rev 10086)
@@ -50,7 +50,7 @@
     </dependency>
     <dependency>
       <groupId>org.drools</groupId>
-      <artifactId>drools-core</artifactId>
+      <artifactId>drools-compiler</artifactId>
     </dependency>    
 
     <!-- External dependencies -->

Modified: labs/jbossrules/trunk/drools-jbrms/src/main/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngine.java
===================================================================
--- labs/jbossrules/trunk/drools-jbrms/src/main/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngine.java	2007-03-08 21:38:17 UTC (rev 10085)
+++ labs/jbossrules/trunk/drools-jbrms/src/main/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngine.java	2007-03-09 00:25:07 UTC (rev 10086)
@@ -198,6 +198,12 @@
         return this.globalTypes.containsKey( variable );
     }
     
+    public String[] getFieldCompletionsForGlobalVariable(String varName) {
+        String type = (String) this.globalTypes.get( varName );        
+        return (String[]) this.fieldsForType.get( type );
+    }
+
+
     private String[] toStringArray(Set set) {
         String[] f = new String[set.size()];
         int i = 0;
@@ -208,13 +214,6 @@
         return f;                
     }
 
-
-    public String[] getFieldCompletionsForGlobalVariable(String varName) {
-        String type = (String) this.globalTypes.get( varName );        
-        return (String[]) this.fieldsForType.get( type );
-    }
-
-
     public String[] getGlobalVariables() {         
         return toStringArray( this.globalTypes.keySet() );
     }

Modified: labs/jbossrules/trunk/drools-jbrms/src/main/java/org/drools/brms/server/rules/SuggestionCompletionLoader.java
===================================================================
--- labs/jbossrules/trunk/drools-jbrms/src/main/java/org/drools/brms/server/rules/SuggestionCompletionLoader.java	2007-03-08 21:38:17 UTC (rev 10085)
+++ labs/jbossrules/trunk/drools-jbrms/src/main/java/org/drools/brms/server/rules/SuggestionCompletionLoader.java	2007-03-09 00:25:07 UTC (rev 10086)
@@ -1,13 +1,30 @@
 package org.drools.brms.server.rules;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.StringReader;
 import java.util.Collection;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.Iterator;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
 
+import org.drools.RuntimeDroolsException;
+import org.drools.brms.client.common.AssetFormats;
 import org.drools.brms.client.modeldriven.SuggestionCompletionEngine;
 import org.drools.brms.server.util.SuggestionCompletionEngineBuilder;
+import org.drools.compiler.DrlParser;
+import org.drools.compiler.DroolsParserException;
+import org.drools.lang.descr.GlobalDescr;
+import org.drools.lang.descr.ImportDescr;
+import org.drools.lang.descr.PackageDescr;
+import org.drools.lang.dsl.DSLMapping;
+import org.drools.lang.dsl.DSLMappingEntry;
+import org.drools.lang.dsl.DSLMappingFile;
+import org.drools.repository.AssetItem;
+import org.drools.repository.AssetItemIterator;
 import org.drools.repository.PackageItem;
+import org.drools.repository.RulesRepositoryException;
+import org.drools.resource.util.ByteArrayClassLoader;
 import org.drools.util.asm.ClassFieldInspector;
 
 /**
@@ -22,43 +39,207 @@
 public class SuggestionCompletionLoader {
 
     private SuggestionCompletionEngineBuilder builder = new SuggestionCompletionEngineBuilder();
-    private static final Pattern imports = Pattern.compile( "import\\s*([\\.a-zA-Z0-9_]+)\\s*[;$]?", Pattern.MULTILINE );
-    
-    
-    public SuggestionCompletionEngine getSuggestionEngine( PackageItem pkg ) {
+    private DrlParser                         parser  = new DrlParser();
+
+    public SuggestionCompletionEngine getSuggestionEngine(PackageItem pkg) {
+        StringBuffer errors = new StringBuffer();
         builder.newCompletionEngine();
-        
+
         String header = pkg.getHeader();
-        
+
         // get fact types from imports
-        Matcher m = imports.matcher( header );
-        while( m.find() ) {
-            String classname = m.group( 1 );
+        PackageDescr pkgDescr;
+        try {
+            pkgDescr = parser.parse( header );
+        } catch ( DroolsParserException e1 ) {
+            throw new RuntimeDroolsException( "Error parsing header for package " + pkg.getName(),
+                                              e1 );
+        }
+
+        // populating information for the model itself
+        this.populateModelInfo( errors,
+                                pkgDescr,
+                                pkg );
+
+        // populating globals
+        this.populateGlobalInfo( errors,
+                                 pkgDescr );
+
+        // populating DSL sentences
+        this.populateDSLSentences( pkg,
+                                   errors );
+
+        if ( errors.length() > 0 ) {
+            throw new RuntimeDroolsException( "Error(s) while loading suggestion completion engine: \n" + errors.toString() );
+        }
+        return builder.getInstance();
+    }
+
+    /**
+     * @param pkg
+     * @param errors
+     */
+    private void populateDSLSentences(PackageItem pkg,
+                                      StringBuffer errors) {
+        AssetItemIterator it = pkg.listAssetsByFormat( new String[]{AssetFormats.DSL} );
+        while ( it.hasNext() ) {
+            AssetItem item = (AssetItem) it.next();
+            DSLMappingFile file = new DSLMappingFile();
+            try {
+                if ( file.parseAndLoad( new StringReader( item.getContent() ) ) ) {
+                    DSLMapping mapping = file.getMapping();
+                    for ( Iterator entries = mapping.getEntries().iterator(); entries.hasNext(); ) {
+                        DSLMappingEntry entry = (DSLMappingEntry) entries.next();
+                        builder.addDSLSentence( entry.getMappingKey() );
+                    }
+                } else {
+                    errors.append( file.getErrors().toString() );
+                }
+            } catch ( IOException e ) {
+                errors.append( "\tError while loading DSL mapping " );
+                errors.append( item.getBinaryContentAttachmentFileName() );
+                errors.append( " : " );
+                errors.append( e.getMessage() );
+                errors.append( "\n" );
+            }
+        }
+    }
+
+    /**
+     * @param errors
+     * @param pkgDescr
+     */
+    private void populateGlobalInfo(StringBuffer errors,
+                                    PackageDescr pkgDescr) {
+        // populating information for the globals
+        for ( Iterator it = pkgDescr.getGlobals().iterator(); it.hasNext(); ) {
+            GlobalDescr global = (GlobalDescr) it.next();
+
+            try {
+                Class clazz = Class.forName( global.getType() );
+
+                builder.addGlobalType( global.getIdentifier(),
+                                       this.getFieldType( clazz ) );
+            } catch ( ClassNotFoundException e ) {
+                errors.append( "\tClass " );
+                errors.append( global.getType() );
+                errors.append( " not found for global " );
+                errors.append( global.getIdentifier() );
+                errors.append( "\n" );
+            }
+        }
+    }
+
+    /**
+     * @param errors
+     * @param pkgDescr
+     */
+    private void populateModelInfo(StringBuffer errors,
+                                   PackageDescr pkgDescr,
+                                   PackageItem pkg ) {
+
+        ByteArrayClassLoader loader = new ByteArrayClassLoader( this.getClass().getClassLoader() );
+
+        // iterating over the import list
+        for ( Iterator it = pkgDescr.getImports().iterator(); it.hasNext(); ) {
+            ImportDescr imp = (ImportDescr) it.next();
+            String classname = imp.getTarget();
+
+            Class clazz = loadClass( pkg,
+                                     classname, 
+                                     loader,
+                                     errors );
+            if ( clazz != null ) {
+                try {
+                    String factType = clazz.getName().substring( clazz.getName().lastIndexOf('.')+1 );
+
+                    ClassFieldInspector inspector = new ClassFieldInspector( clazz );
+                    String[] fields = (String[]) inspector.getFieldNames().keySet().toArray( new String[inspector.getFieldNames().size()] );
+
+                    builder.addFactType( factType );
+                    builder.addFieldsForType( factType,
+                                              fields );
+                    for ( int i = 0; i < fields.length; i++ ) {
+                        Class type = (Class) inspector.getFieldTypes().get( fields[i] );
+                        String fieldType = getFieldType( type );
+                        builder.addFieldType( factType + "." + fields[i],
+                                              fieldType );
+                    }
+                } catch ( IOException e ) {
+                    errors.append( "\tError while inspecting class: " );
+                    errors.append( classname );
+                    errors.append( " : " );
+                    errors.append( e.getMessage() );
+                    errors.append( "\n" );
+                }
+            }
+        }
+    }
+
+    /**
+     * @param pkg
+     * @param classname
+     * @param clazz
+     * @return
+     */
+    private Class loadClass(PackageItem pkg,
+                            String classname,
+                            ByteArrayClassLoader loader,
+                            StringBuffer errors ) {
+        Class clazz = null;
+        try {
+            // check if it is already in the classpath
+            clazz = loader.loadClass( classname );
             
+        } catch ( ClassNotFoundException e1 ) {
+            
+            // not found in the classpath, so check if it
+            // is in a package model
             try {
-                Class clazz = Class.forName( classname );
-                String factType = clazz.getName().replace( clazz.getPackage().getName()+".", "" );
-                
-                ClassFieldInspector inspector = new ClassFieldInspector( clazz );
-                String[] fields = (String[]) inspector.getFieldNames().keySet().toArray( new String[inspector.getFieldNames().size()] );
-                
-                builder.addFactType( factType );
-                builder.addFieldsForType( factType, fields );
-                for( int i = 0; i < fields.length; i++ ) {
-                    // need to fix that
-                    String fieldType = getFieldType( inspector,
-                                                     fields[i] );
-                    builder.addFieldType( factType+"."+fields[i], fieldType );
+                // try to load the package model
+                PackageItem importedPkg = null;
+                String pkgName = classname;
+                do {
+                    pkgName = classname.substring( 0,
+                                                   Math.max( classname.lastIndexOf( '.' ),
+                                                             0 ) );
+                    importedPkg = pkg.getRulesRepository().loadPackage( pkgName );
+                } while ( importedPkg == null && pkgName.length() > 0 );
+
+                if ( importedPkg != null ) {
+                    // a package was found, so, try it out
+                    AssetItemIterator ait = importedPkg.listAssetsByFormat( new String[]{AssetFormats.MODEL} );
+                    while ( ait.hasNext() ) {
+                        AssetItem item = (AssetItem) ait.next();
+                        JarInputStream jis = new JarInputStream( item.getBinaryContentAttachment(),
+                                                                 false );
+                        JarEntry entry = null;
+                        byte[] buf = new byte[1024];
+                        int len = 0;
+                        while ( (entry = jis.getNextJarEntry()) != null ) {
+                            if ( !entry.isDirectory() ) {
+                                ByteArrayOutputStream out = new ByteArrayOutputStream();
+                                while( (len = jis.read( buf ) ) >=0 ) {
+                                    out.write( buf, 0, len );
+                                }
+                                loader.addResource( entry.getName(),
+                                                    out.toByteArray() );
+                            }
+                        }
+                    }
                 }
+                clazz = loader.loadClass( classname );
+            } catch ( RulesRepositoryException e ) {
+                // TODO: mic_hat, what do we do here?
+            } catch ( IOException e ) {
+                // TODO: mic_hat, what do we do here?
             } catch ( ClassNotFoundException e ) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            } catch ( IOException e ) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
+                errors.append( "\tImported class not found: " );
+                errors.append( classname );
+                errors.append( "\n" );
             }
         }
-        return builder.getInstance();
+        return clazz;
     }
 
     /**
@@ -67,23 +248,20 @@
      * @param i
      * @return
      */
-    private String getFieldType(ClassFieldInspector inspector,
-                                String field ) {
-        Class type = (Class) inspector.getFieldTypes().get( field );
+    private String getFieldType(Class type) {
         String fieldType = null; // if null, will use standard operators
-        if( type.isPrimitive() && ( type != boolean.class ) ) {
+        if ( type.isPrimitive() && (type != boolean.class) ) {
             fieldType = SuggestionCompletionEngine.TYPE_NUMERIC;
-        } else if( Number.class.isAssignableFrom( type ) ) {
+        } else if ( Number.class.isAssignableFrom( type ) ) {
             fieldType = SuggestionCompletionEngine.TYPE_NUMERIC;
-        } else if( String.class.isAssignableFrom( type ) ) {
+        } else if ( String.class.isAssignableFrom( type ) ) {
             fieldType = SuggestionCompletionEngine.TYPE_STRING;
-        } else if( Collection.class.isAssignableFrom( type ) ) {
+        } else if ( Collection.class.isAssignableFrom( type ) ) {
             fieldType = SuggestionCompletionEngine.TYPE_COLLECTION;
-        } else if( Comparable.class.isAssignableFrom( type ) ) {
+        } else if ( Comparable.class.isAssignableFrom( type ) ) {
             fieldType = SuggestionCompletionEngine.TYPE_COMPARABLE;
         }
         return fieldType;
-    }    
+    }
 
-    
 }

Added: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/resource/util/ByteArrayClassLoader.java
===================================================================
--- labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/resource/util/ByteArrayClassLoader.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/resource/util/ByteArrayClassLoader.java	2007-03-09 00:25:07 UTC (rev 10086)
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2006 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.resource.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A class loader for in memory byte[] resources
+ * 
+ * @author etirelli
+ */
+public class ByteArrayClassLoader extends ClassLoader {
+    
+    private final Map resources = new HashMap();
+
+    public ByteArrayClassLoader(final ClassLoader parentClassLoader) {
+        super( parentClassLoader );
+    }
+    
+    public void addResource( String name, byte[] bytecode ) {
+        this.resources.put( name, bytecode );
+    }
+
+    public Class fastFindClass(final String name) {
+        final Class clazz = findLoadedClass( name );
+
+        if ( clazz == null ) {
+            final byte[] clazzBytes = (byte[]) this.resources.get( convertClassToResourcePath(name) );
+            if ( clazzBytes != null ) {
+                return defineClass( name,
+                                    clazzBytes,
+                                    0,
+                                    clazzBytes.length );
+            }
+        }
+
+        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[]) this.resources.get( name );
+        if ( bytes != null ) {
+            return new ByteArrayInputStream( bytes );
+        } else {
+            InputStream input = this.getParent().getResourceAsStream( name );
+            if( input == null ){
+                input = super.getResourceAsStream( name );
+            }
+            return input;
+        }
+    }
+    
+//    /**
+//     * org/my/Class.xxx -> org.my.Class
+//     */
+//    private static String convertResourceToClassName( final String pResourceName ) {
+//        return stripExtension(pResourceName).replace('/', '.');
+//    }
+//
+    /**
+     * org.my.Class -> org/my/Class.class
+     */
+    private static String convertClassToResourcePath( final String pName ) {
+        return pName.replace('.', '/') + ".class";
+    }
+
+//    /**
+//     * org/my/Class.xxx -> org/my/Class
+//     */
+//    private static String stripExtension( final String pResourceName ) {
+//        final int i = pResourceName.lastIndexOf('.');
+//        final String withoutExtension = pResourceName.substring(0, i);
+//        return withoutExtension;
+//    }
+    
+    
+
+}


Property changes on: labs/jbossrules/trunk/drools-repository/src/main/java/org/drools/resource/util/ByteArrayClassLoader.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native




More information about the jboss-svn-commits mailing list