001: package org.drools.base.mvel;
002:
003: import java.io.Serializable;
004: import java.util.HashMap;
005: import java.util.Iterator;
006: import java.util.List;
007: import java.util.Map;
008:
009: import org.drools.WorkingMemory;
010: import org.drools.reteoo.ReteTuple;
011: import org.drools.rule.Declaration;
012: import org.drools.spi.KnowledgeHelper;
013: import org.drools.spi.Tuple;
014: import org.mvel.CompileException;
015: import org.mvel.integration.VariableResolver;
016: import org.mvel.integration.impl.BaseVariableResolverFactory;
017: import org.mvel.integration.impl.LocalVariableResolverFactory;
018:
019: public class DroolsMVELFactory extends BaseVariableResolverFactory
020: implements LocalVariableResolverFactory, Serializable,
021: Cloneable {
022:
023: private static final long serialVersionUID = 400L;
024:
025: /**
026: * Holds the instance of the variables.
027: */
028: private Object[] tupleObjects;
029: private KnowledgeHelper knowledgeHelper;
030: private Object object;
031: private Map localDeclarations;
032: private Map previousDeclarations;
033: private Map globals;
034:
035: private WorkingMemory workingMemory;
036:
037: private Map localVariables;
038:
039: public DroolsMVELFactory(final Map previousDeclarations,
040: final Map localDeclarations, final Map globals) {
041: this (previousDeclarations, localDeclarations, globals, null);
042: }
043:
044: public DroolsMVELFactory(final Map previousDeclarations,
045: final Map localDeclarations, final Map globals,
046: final List[] externals) {
047: this .previousDeclarations = previousDeclarations;
048: this .localDeclarations = localDeclarations;
049: this .globals = globals;
050:
051: if (externals != null && MVELDebugHandler.isDebugMode()) {
052: for (int i = 0; i < externals.length; i++) {
053: for (Iterator it = externals[i].iterator(); it
054: .hasNext();) {
055: String identifier = (String) it.next();
056: isResolveable(identifier);
057: }
058: }
059: }
060: }
061:
062: public Map getVariableResolvers() {
063: return this .variableResolvers;
064: }
065:
066: public Object getObject() {
067: return this .object;
068: }
069:
070: public WorkingMemory getWorkingMemory() {
071: return this .workingMemory;
072: }
073:
074: public void setContext(final Tuple tuple,
075: final KnowledgeHelper knowledgeHelper, final Object object,
076: final WorkingMemory workingMemory, final Map variables) {
077: if (tuple != null) {
078: this .tupleObjects = ((ReteTuple) tuple).toObjectArray();
079: }
080: this .knowledgeHelper = knowledgeHelper;
081: this .object = object;
082: this .workingMemory = workingMemory;
083: this .localVariables = variables;
084: }
085:
086: public KnowledgeHelper getKnowledgeHelper() {
087: return this .knowledgeHelper;
088: }
089:
090: public Object getValue(final Declaration declaration) {
091: int i = declaration.getPattern().getOffset();
092: return this .tupleObjects[i];
093: }
094:
095: public Object getValue(final String identifier) {
096: return this .workingMemory.getGlobal(identifier);
097: }
098:
099: public Object getLocalValue(final String identifier) {
100: return this .localVariables.get(identifier);
101: }
102:
103: public void setLocalValue(final String identifier,
104: final Object value) {
105: this .localVariables.put(identifier, value);
106: }
107:
108: public VariableResolver createVariable(String name, Object value) {
109: VariableResolver vr = getVariableResolver(name);
110: if (vr != null) {
111: if (this .localVariables == null) {
112: this .localVariables = new HashMap();
113: }
114: vr.setValue(value);
115: return vr;
116: } else {
117: if (this .localVariables == null) {
118: this .localVariables = new HashMap();
119: }
120: addResolver(name,
121: vr = new LocalVariableResolver(this , name));
122: vr.setValue(value);
123: return vr;
124: }
125: }
126:
127: public VariableResolver createVariable(String name, Object value,
128: Class type) {
129: VariableResolver vr = getVariableResolver(name);
130: if (vr != null && vr.getType() != null) {
131: throw new CompileException(
132: "variable already defined within scope: "
133: + vr.getType() + " " + name);
134: } else {
135: if (this .localVariables == null) {
136: this .localVariables = new HashMap();
137: }
138: addResolver(name, vr = new LocalVariableResolver(this ,
139: name, type));
140: vr.setValue(value);
141: return vr;
142: }
143: }
144:
145: public boolean isResolveable(String name) {
146: if (DroolsMVELKnowledgeHelper.DROOLS.equals(name)) {
147: addResolver(DroolsMVELKnowledgeHelper.DROOLS,
148: new DroolsMVELKnowledgeHelper(this ));
149: return true;
150:
151: } else if (this .variableResolvers != null
152: && this .variableResolvers.containsKey(name)) {
153: return true;
154: } else if (this .previousDeclarations != null
155: && this .previousDeclarations.containsKey(name)) {
156: addResolver(name,
157: new DroolsMVELPreviousDeclarationVariable(
158: (Declaration) this .previousDeclarations
159: .get(name), this ));
160: return true;
161: } else if (this .localDeclarations != null
162: && this .localDeclarations.containsKey(name)) {
163: addResolver(name, new DroolsMVELLocalDeclarationVariable(
164: (Declaration) this .localDeclarations.get(name),
165: this ));
166: return true;
167: } else if (this .globals.containsKey(name)) {
168: addResolver(name, new DroolsMVELGlobalVariable(name,
169: (Class) this .globals.get(name), this ));
170: return true;
171: } else if (this .variableResolvers != null
172: && this .variableResolvers.containsKey(name)) {
173: addResolver(name, new LocalVariableResolver(this , name));
174: return true;
175: } else if (nextFactory != null) {
176: return nextFactory.isResolveable(name);
177: }
178:
179: return false;
180: }
181:
182: private void addResolver(String name, VariableResolver vr) {
183: if (this .variableResolvers == null) {
184: this .variableResolvers = new HashMap();
185: }
186: this .variableResolvers.put(name, vr);
187: }
188:
189: public boolean isTarget(String name) {
190: if (this .variableResolvers != null) {
191: return this .variableResolvers.containsKey(name);
192: } else {
193: return false;
194: }
195: }
196:
197: public Object clone() {
198: return new DroolsMVELFactory(this.previousDeclarations,
199: this.localDeclarations, this.globals);
200: }
201: }
|