001: /*
002: * Copyright (C) 2004 TiongHiang Lee
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * Email: thlee@onemindsoft.org
019: */
020:
021: package org.onemind.jxp;
022:
023: import java.io.Writer;
024: import java.util.*;
025: import java.util.logging.Level;
026: import java.util.logging.Logger;
027: import org.onemind.commons.java.datastructure.NametableStack;
028: import org.onemind.commons.java.lang.reflect.ClassLookupCache;
029: import org.onemind.jxp.util.StaticImport;
030:
031: /**
032: * An processing context contains everything specific to a specific execution of an JxpPage so that there's only one parser needed
033: * for all the processings
034: * @author TiongHiang Lee (thlee@onemindsoft.org)
035: *
036: */
037: class JxpProcessingContext {
038:
039: /** the logger * */
040: private static final Logger _logger = Logger
041: .getLogger(JxpProcessingContext.class.getName());
042:
043: /** default imports * */
044: private static final ClassLookupCache _default_imports = new ClassLookupCache();
045: static {
046: _default_imports.addImport("*");
047: _default_imports.addImport("java.lang.*");
048: _default_imports.addImport("java.util.*");
049: }
050:
051: private static final String KEY_SCRIPT_NAME = "jxp_script_name";
052:
053: private static final String KEY_WRITER = "jxp_writer";
054:
055: private static final String KEY_CONTEXT = "jxp_context";
056:
057: /** the imports * */
058: private ClassLookupCache _imports = new ClassLookupCache();
059:
060: /** the writer * */
061: private Writer _writer;
062:
063: /** the stack of pages in current processing context * */
064: private Stack _pageStack = new Stack();
065:
066: /** the nametable scope stack **/
067: private Stack _ntStack = new Stack();
068:
069: /** the current page **/
070: private JxpPage _currentPage;
071:
072: /** the name tables * */
073: private NametableStack _nametableStack;
074:
075: /** the functions map **/
076: private Map _userDefinedFunctions = new HashMap();
077:
078: /** the static imports **/
079: private List _staticImports = new ArrayList();
080:
081: /**
082: * {@inheritDoc}
083: */
084: public JxpProcessingContext(Writer writer, Map env) {
085: _writer = writer;
086: env.put(KEY_WRITER, _writer);
087: env.put(KEY_CONTEXT, this );
088: _nametableStack = new NametableStack(env);
089: };
090:
091: /**
092: * Push current page to the page stack
093: * @param page the page
094: */
095: public final void pushPage(JxpPage page) {
096: _currentPage = page;
097: _pageStack.push(page);
098: if (_nametableStack.containsName(KEY_SCRIPT_NAME)) {
099: _nametableStack.assign(KEY_SCRIPT_NAME, page.getName());
100: } else {
101: _nametableStack.declare(KEY_SCRIPT_NAME, page.getName());
102: }
103: }
104:
105: /**
106: * Get the current page
107: * @return the current page
108: */
109: public final JxpPage getCurrentPage() {
110: return _currentPage;
111: }
112:
113: /**
114: * Pop the current page
115: * @param page the current page
116: * @throws IllegalStateException if the page is not current page
117: */
118: public final void popPage(JxpPage page)
119: throws IllegalStateException {
120: if (_pageStack.peek() != page) {
121: throw new IllegalStateException("Popping wrong page "
122: + page);
123: } else {
124: _pageStack.pop();
125: if (_pageStack.size() != 0) {
126: _currentPage = (JxpPage) _pageStack.peek();
127: } else {
128: _currentPage = null;
129: }
130: if (_currentPage != null) {
131: _nametableStack.assign(KEY_SCRIPT_NAME, _currentPage
132: .getName());
133: }
134: }
135: }
136:
137: /**
138: * Resolve a class
139: * @param className the class name
140: * @return the class
141: */
142: protected final Class resolveClass(String className) {
143: if (_logger.isLoggable(Level.FINEST)) {
144: _logger.finest("Resolving " + className);
145: }
146: Class c = _default_imports.getClass(className);
147: if (c == null) {
148: if (_logger.isLoggable(Level.FINEST)) {
149: _logger.finest("Resolving " + className + " package "
150: + _imports.getPackages());
151: }
152: c = _imports.getClass(className);
153: }
154: return c;
155: }
156:
157: /**
158: * Return the name table stack
159: * @return the name table stack
160: */
161: public final NametableStack getNametableStack() {
162: return _nametableStack;
163: }
164:
165: /**
166: * Return the imports
167: * @return the imports
168: */
169: public final ClassLookupCache getImports() {
170: return _imports;
171: }
172:
173: /**
174: * Get the writer
175: * @return the writer
176: */
177: public final Writer getWriter() {
178: return _writer;
179: }
180:
181: /**
182: * Return the functions
183: * @return the functions.
184: */
185: public final Map getUserDefinedFunctions() {
186: return _userDefinedFunctions;
187: }
188:
189: /**
190: * Add static import
191: * @param sImport the static import to add
192: */
193: public void addStaticImport(StaticImport sImport) {
194: _staticImports.add(sImport);
195: }
196:
197: /**
198: * Get static imports
199: * @return the static imports
200: */
201: public final List getStaticImports() {
202: return _staticImports;
203: }
204: }
|