[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