001: package org.mvel;
002:
003: import org.mvel.ast.Function;
004: import org.mvel.ast.LineLabel;
005: import org.mvel.integration.Interceptor;
006: import org.mvel.util.MethodStub;
007: import static org.mvel.util.ParseTools.getSimpleClassName;
008:
009: import java.io.Serializable;
010: import java.lang.reflect.Method;
011: import java.util.*;
012:
013: /**
014: * The ParserContext is the main enviroment object used for sharing state throughout the entire
015: * parser/compile process.
016: */
017: public class ParserContext implements Serializable {
018: private String sourceFile;
019:
020: private int lineCount = 1;
021: private int lineOffset;
022:
023: private ParserConfiguration parserConfiguration = new ParserConfiguration();
024:
025: private ArrayList<String> indexedVariables;
026: private Map<String, Class> variables;
027: private Map<String, Class> inputs;
028: private Map<String, Function> globalFunctions;
029:
030: private List<ErrorDetail> errorList;
031:
032: private Map<String, Set<Integer>> sourceMap;
033: private LineLabel lastLineLabel;
034:
035: private Object rootParser;
036:
037: private boolean compiled = false;
038: private boolean strictTypeEnforcement = false;
039: private boolean fatalError = false;
040: private boolean retainParserState = false;
041: private boolean debugSymbols = false;
042: private boolean blockSymbols = false;
043: private boolean executableCodeReached = false;
044: private boolean indexAllocation = false;
045:
046: public ParserContext() {
047: }
048:
049: public ParserContext(boolean debugSymbols) {
050: this .debugSymbols = debugSymbols;
051: }
052:
053: public ParserContext(Object rootParser) {
054: this .rootParser = rootParser;
055: }
056:
057: public ParserContext(ParserConfiguration parserConfiguration) {
058: this .parserConfiguration = parserConfiguration;
059: }
060:
061: public ParserContext(Map<String, Object> imports,
062: Map<String, Interceptor> interceptors, String sourceFile) {
063: this .sourceFile = sourceFile;
064: this .parserConfiguration = new ParserConfiguration(imports,
065: interceptors);
066: }
067:
068: public boolean hasVarOrInput(String name) {
069: return (variables != null && variables.containsKey(name))
070: || (inputs != null && inputs.containsKey(name));
071: }
072:
073: public Class getVarOrInputType(String name) {
074: if (variables != null && variables.containsKey(name)) {
075: return variables.get(name);
076: } else if (inputs != null && inputs.containsKey(name)) {
077: return inputs.get(name);
078: }
079: return Object.class;
080: }
081:
082: public int getLineCount() {
083: return lineCount;
084: }
085:
086: public int setLineCount(int lineCount) {
087: return this .lineCount = (short) lineCount;
088: }
089:
090: public int getLineOffset() {
091: return lineOffset;
092: }
093:
094: public void setLineOffset(short lineOffset) {
095: this .lineOffset = lineOffset;
096: }
097:
098: public void setLineAndOffset(int lineCount, int lineOffset) {
099: addKnownLine(this .lineCount = lineCount);
100: this .lineOffset = lineOffset;
101: }
102:
103: public Class getImport(String name) {
104: // return (imports != null && imports.containsKey(name) ? (Class) imports.get(name) : (Class) AbstractParser.LITERALS.get(name));
105: return parserConfiguration.getImport(name);
106: }
107:
108: public MethodStub getStaticImport(String name) {
109: //return imports != null ? (MethodStub) imports.get(name) : null;
110: return parserConfiguration.getStaticImport(name);
111: }
112:
113: public Object getStaticOrClassImport(String name) {
114: return parserConfiguration.getStaticOrClassImport(name);
115: }
116:
117: public void addPackageImport(String packageName) {
118: parserConfiguration.addPackageImport(packageName);
119: }
120:
121: public boolean hasImport(String name) {
122: return parserConfiguration.hasImport(name);
123: }
124:
125: public void addImport(Class cls) {
126: addImport(getSimpleClassName(cls), cls);
127: }
128:
129: public void addImport(String name, Class cls) {
130: parserConfiguration.addImport(name, cls);
131: }
132:
133: public void addImport(String name, Method method) {
134: addImport(name, new MethodStub(method));
135: }
136:
137: public void addImport(String name, MethodStub method) {
138: parserConfiguration.addImport(name, method);
139: }
140:
141: public void initializeTables() {
142: if (variables == null)
143: variables = new LinkedHashMap<String, Class>();
144: if (inputs == null)
145: inputs = new LinkedHashMap<String, Class>();
146: }
147:
148: public void addVariable(String name, Class type,
149: boolean failIfNewAssignment) {
150: initializeTables();
151: if (variables.containsKey(name) && failIfNewAssignment)
152: throw new CompileException(
153: "statically-typed variable already defined in scope: "
154: + name);
155: if (type == null)
156: type = Object.class;
157: variables.put(name, type);
158: }
159:
160: public void addVariable(String name, Class type) {
161: initializeTables();
162: if (variables.containsKey(name))
163: return;
164: if (type == null)
165: type = Object.class;
166: variables.put(name, type);
167: }
168:
169: public void addVariables(Map<String, Class> variables) {
170: if (variables == null)
171: return;
172: initializeTables();
173: for (String name : variables.keySet()) {
174: addVariable(name, variables.get(name));
175: }
176: }
177:
178: public void addInput(String name, Class type) {
179: if (inputs == null)
180: inputs = new LinkedHashMap<String, Class>();
181: if (inputs.containsKey(name))
182: return;
183: if (type == null)
184: type = Object.class;
185: inputs.put(name, type);
186: }
187:
188: public void addInputs(Map<String, Class> inputs) {
189: if (inputs == null)
190: return;
191: if (inputs == null)
192: inputs = new LinkedHashMap<String, Class>();
193: for (String name : inputs.keySet()) {
194: addInput(name, inputs.get(name));
195: }
196: }
197:
198: public void processTables() {
199: for (String name : variables.keySet()) {
200: inputs.remove(name);
201: }
202: }
203:
204: // accessors -- start here
205:
206: public Map<String, Class> getInputs() {
207: return inputs;
208: }
209:
210: public void setInputs(Map<String, Class> inputs) {
211: this .inputs = inputs;
212: }
213:
214: public List<ErrorDetail> getErrorList() {
215: return errorList;
216: }
217:
218: public void setErrorList(List<ErrorDetail> errorList) {
219: this .errorList = errorList;
220: }
221:
222: public void addError(ErrorDetail errorDetail) {
223: if (errorList == null)
224: errorList = new ArrayList<ErrorDetail>();
225: if (errorDetail.isCritical())
226: fatalError = true;
227: errorList.add(errorDetail);
228: }
229:
230: public boolean isFatalError() {
231: return fatalError;
232: }
233:
234: public void setFatalError(boolean fatalError) {
235: this .fatalError = fatalError;
236: }
237:
238: public boolean isStrictTypeEnforcement() {
239: return strictTypeEnforcement;
240: }
241:
242: public void setStrictTypeEnforcement(boolean strictTypeEnforcement) {
243: this .strictTypeEnforcement = strictTypeEnforcement;
244: }
245:
246: public boolean isRetainParserState() {
247: return retainParserState;
248: }
249:
250: public void setRetainParserState(boolean retainParserState) {
251: this .retainParserState = retainParserState;
252: }
253:
254: public Object getRootParser() {
255: return rootParser;
256: }
257:
258: public void setRootParser(Object rootParser) {
259: this .rootParser = rootParser;
260: }
261:
262: public String getSourceFile() {
263: return sourceFile;
264: }
265:
266: public void setSourceFile(String sourceFile) {
267: if (sourceFile != null)
268: this .sourceFile = sourceFile;
269: }
270:
271: public Map<String, Interceptor> getInterceptors() {
272: return this .parserConfiguration.getInterceptors();
273: }
274:
275: public void setInterceptors(Map<String, Interceptor> interceptors) {
276: this .parserConfiguration.setInterceptors(interceptors);
277: }
278:
279: public Map<String, Object> getImports() {
280: return this .parserConfiguration.getImports();
281: }
282:
283: public void setImports(Map<String, Object> imports) {
284: if (imports == null)
285: return;
286:
287: Object val;
288: for (String name : imports.keySet()) {
289: if ((val = imports.get(name)) instanceof Class) {
290: addImport(name, (Class) val);
291: } else if (val instanceof Method) {
292: addImport(name, (Method) val);
293: } else if (val instanceof MethodStub) {
294: addImport(name, (MethodStub) val);
295: } else {
296: throw new RuntimeException(
297: "invalid element in imports map: " + name
298: + " (" + val + ")");
299: }
300: }
301: }
302:
303: public Map<String, Class> getVariables() {
304: return variables;
305: }
306:
307: public void setVariables(Map<String, Class> variables) {
308: this .variables = variables;
309: }
310:
311: public boolean isCompiled() {
312: return compiled;
313: }
314:
315: public void setCompiled(boolean compiled) {
316: this .compiled = compiled;
317: }
318:
319: public boolean isDebugSymbols() {
320: return debugSymbols;
321: }
322:
323: public void setDebugSymbols(boolean debugSymbols) {
324: this .debugSymbols = debugSymbols;
325: }
326:
327: public boolean isKnownLine(String sourceName, int lineNumber) {
328: return sourceMap != null && sourceMap.containsKey(sourceName)
329: && sourceMap.get(sourceName).contains(lineNumber);
330: }
331:
332: public void addKnownLine(String sourceName, int lineNumber) {
333: if (sourceMap == null)
334: sourceMap = new LinkedHashMap<String, Set<Integer>>();
335: if (!sourceMap.containsKey(sourceName))
336: sourceMap.put(sourceName, new HashSet<Integer>());
337: sourceMap.get(sourceName).add(lineNumber);
338: }
339:
340: public void addKnownLine(int lineNumber) {
341: addKnownLine(sourceFile, lineNumber);
342: }
343:
344: public LineLabel getLastLineLabel() {
345: return lastLineLabel;
346: }
347:
348: public LineLabel setLastLineLabel(LineLabel lastLineLabel) {
349: return this .lastLineLabel = lastLineLabel;
350: }
351:
352: public boolean hasImports() {
353: return parserConfiguration.hasImports();
354: }
355:
356: public void declareFunction(Function function) {
357: if (globalFunctions == null)
358: globalFunctions = new LinkedHashMap<String, Function>();
359: globalFunctions.put(function.getName(), function);
360: }
361:
362: public Function getFunction(String name) {
363: if (globalFunctions == null)
364: return null;
365: return globalFunctions.get(name);
366: }
367:
368: public Map getFunctions() {
369: return globalFunctions;
370: }
371:
372: public boolean hasFunction(String name) {
373: return globalFunctions != null
374: && globalFunctions.containsKey(name);
375: }
376:
377: public boolean hasFunction() {
378: return globalFunctions != null && globalFunctions.size() != 0;
379: }
380:
381: public boolean isBlockSymbols() {
382: return blockSymbols;
383: }
384:
385: public void setBlockSymbols(boolean blockSymbols) {
386: this .blockSymbols = blockSymbols;
387: }
388:
389: public boolean isExecutableCodeReached() {
390: return executableCodeReached;
391: }
392:
393: public void setExecutableCodeReached(boolean executableCodeReached) {
394: this .executableCodeReached = executableCodeReached;
395: }
396:
397: private void initIndexedVariables() {
398: if (indexedVariables == null)
399: indexedVariables = new ArrayList<String>();
400: }
401:
402: public ArrayList<String> getIndexedVariables() {
403: initIndexedVariables();
404: return indexedVariables;
405: }
406:
407: public void addIndexedVariables(String[] variables) {
408: initIndexedVariables();
409: for (String s : variables) {
410: if (!indexedVariables.contains(s))
411: indexedVariables.add(s);
412: }
413: }
414:
415: public void addIndexedVariable(String variable) {
416: initIndexedVariables();
417: if (!indexedVariables.contains(variable))
418: indexedVariables.add(variable);
419: }
420:
421: public void addIndexedVariables(Collection<String> variables) {
422: initIndexedVariables();
423: for (String s : variables) {
424: if (!indexedVariables.contains(s))
425: indexedVariables.add(s);
426: }
427: }
428:
429: public int variableIndexOf(String name) {
430: return indexedVariables != null ? indexedVariables
431: .indexOf(name) : -1;
432: }
433:
434: public boolean hasIndexedVariables() {
435: return indexedVariables != null && indexedVariables.size() != 0;
436: }
437:
438: public boolean isIndexAllocation() {
439: return indexAllocation;
440: }
441:
442: public void setIndexAllocation(boolean indexAllocation) {
443: this .indexAllocation = indexAllocation;
444: }
445:
446: public ParserConfiguration getParserConfiguration() {
447: return parserConfiguration;
448: }
449: }
|