/**
* Copyright 2010 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.base.mvel;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.drools.WorkingMemory;
import org.mvel2.integration.VariableResolver;
import org.mvel2.integration.impl.BaseVariableResolverFactory;
import org.mvel2.integration.impl.LocalVariableResolverFactory;
import org.mvel2.integration.impl.StaticMethodImportResolverFactory;
public class DroolsProcessMVELFactory extends BaseVariableResolverFactory
implements
LocalVariableResolverFactory,
DroolsGlobalVariableMVELFactory,
DroolsLocalVariableMVELFactory,
Externalizable,
Cloneable {
private static final long serialVersionUID = 510l;
/**
* Holds the instance of the variables.
*/
private Map globals;
private WorkingMemory workingMemory;
private Map localVariables;
public DroolsProcessMVELFactory() {
}
public DroolsProcessMVELFactory(final Map globals) {
this( globals,
null );
}
public DroolsProcessMVELFactory(final Map globals,
final List[] externals) {
this.globals = globals;
if ( externals != null && MVELDebugHandler.isDebugMode() ) {
for ( int i = 0; i < externals.length; i++ ) {
for ( Iterator it = externals[i].iterator(); it.hasNext(); ) {
String identifier = (String) it.next();
isResolveable( identifier );
}
}
}
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
globals = (Map) in.readObject();
workingMemory = (WorkingMemory) in.readObject();
localVariables = (Map) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject( globals );
out.writeObject( workingMemory );
out.writeObject( localVariables );
}
public static void addStaticImport(StaticMethodImportResolverFactory factory,
String staticImportEntry,
ClassLoader classLoader) {
int index = staticImportEntry.lastIndexOf( '.' );
String className = staticImportEntry.substring( 0,
index );
String methodName = staticImportEntry.substring( index + 1 );
try {
Class cls = classLoader.loadClass( className );
Method[] methods = cls.getDeclaredMethods();
for ( int i = 0; i < methods.length; i++ ) {
if ( methods[i].getName().equals( methodName ) ) {
factory.createVariable( methodName,
methods[i] );
break;
}
}
} catch ( ClassNotFoundException e ) {
throw new RuntimeException( "Unable to dynamically load method '" + staticImportEntry + "'" );
}
}
public Map getVariableResolvers() {
return this.variableResolvers;
}
public WorkingMemory getWorkingMemory() {
return this.workingMemory;
}
public void setContext(final WorkingMemory workingMemory) {
this.workingMemory = workingMemory;
}
public Object getValue(final String identifier) {
return this.workingMemory.getGlobal( identifier );
}
public Object getLocalValue(final String identifier) {
return this.localVariables.get( identifier );
}
public void setLocalValue(final String identifier,
final Object value) {
if ( this.localVariables == null ) {
this.localVariables = new HashMap();
}
this.localVariables.put( identifier,
value );
}
public VariableResolver createVariable(String name,
Object value) {
VariableResolver vr = getVariableResolver( name );
if ( vr == null ) {
addResolver( name,
vr = new LocalVariableResolver( this,
name ) );
}
vr.setValue( value );
return vr;
}
public VariableResolver createVariable(String name,
Object value,
Class type) {
VariableResolver vr = getVariableResolver( name );
if ( vr == null ) {
addResolver( name,
vr = new LocalVariableResolver( this,
name,
type ) );
}
vr.setValue( value );
return vr;
}
public boolean isResolveable(String name) {
if ( this.variableResolvers != null && this.variableResolvers.containsKey( name ) ) {
return true;
} else if ( this.workingMemory.getGlobal( name ) != null ) {
addResolver( name,
new DroolsMVELGlobalVariable( name,
(Class) this.globals.get( name ),
this ) );
return true;
} else if ( nextFactory != null ) {
return nextFactory.isResolveable( name );
}
return false;
}
private void addResolver(String name,
VariableResolver vr) {
if ( this.variableResolvers == null ) {
this.variableResolvers = new HashMap();
}
this.variableResolvers.put( name,
vr );
}
public boolean isTarget(String name) {
if ( this.variableResolvers != null ) {
return this.variableResolvers.containsKey( name );
} else {
return false;
}
}
public Object clone() {
return new DroolsProcessMVELFactory( this.globals );
}
/**
* @return the globals
*/
protected Map getGlobals() {
return globals;
}
/**
* @return the localVariables
*/
protected Map getLocalVariables() {
return localVariables;
}
}