001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.language.markup.xsp;
018:
019: import org.apache.avalon.framework.activity.Initializable;
020: import org.apache.avalon.framework.configuration.Configurable;
021: import org.apache.avalon.framework.configuration.Configuration;
022: import org.apache.avalon.framework.configuration.ConfigurationException;
023: import org.apache.avalon.framework.parameters.Parameters;
024: import org.apache.cocoon.ProcessingException;
025: import org.apache.cocoon.environment.Session;
026: import org.apache.cocoon.environment.SourceResolver;
027: import org.mozilla.javascript.Context;
028: import org.mozilla.javascript.ImporterTopLevel;
029: import org.mozilla.javascript.JavaScriptException;
030: import org.mozilla.javascript.Script;
031: import org.mozilla.javascript.Scriptable;
032: import org.xml.sax.ContentHandler;
033: import org.xml.sax.SAXException;
034: import org.xml.sax.helpers.AttributesImpl;
035:
036: import java.io.File;
037: import java.io.FileReader;
038: import java.io.IOException;
039: import java.text.DateFormat;
040: import java.text.ParseException;
041: import java.util.Collection;
042: import java.util.Date;
043: import java.util.Locale;
044: import java.util.Map;
045:
046: /**
047: * Class representing interpreted XSP-generated
048: * <code>ServerPagesGenerator</code> programs
049: * written in Javascript language
050: *
051: * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
052: * @version CVS $Id: JSGenerator.java 433543 2006-08-22 06:22:54Z crossley $
053: */
054: public class JSGenerator extends XSPGenerator implements Configurable,
055: Initializable {
056:
057: /**
058: * Javascript source file
059: */
060: private File file;
061:
062: private Scriptable global;
063:
064: // FIXME: Use Store to cache compiled scripts
065: private Script script;
066: private Exception compileError;
067:
068: public void configure(Configuration configuration)
069: throws ConfigurationException {
070: this .file = new File(configuration.getChild("file").getValue());
071:
072: Configuration[] dependencies = configuration
073: .getChildren("dependency");
074: this .dependencies = new File[dependencies.length];
075: for (int i = 0; i < dependencies.length; i++) {
076: this .dependencies[i] = new File(dependencies[i].getValue());
077: }
078: }
079:
080: /**
081: * Determines whether this generator's source files have changed
082: *
083: * @return Whether any of the files this generator depends on has changed
084: * since it was created
085: */
086: public boolean modifiedSince(long date) {
087: if (this .file.lastModified() < date) {
088: return true;
089: }
090:
091: for (int i = 0; i < dependencies.length; i++) {
092: if (this .file.lastModified() < dependencies[i]
093: .lastModified()) {
094: return true;
095: }
096: }
097:
098: return false;
099: }
100:
101: public void initialize() throws Exception {
102: Context context = Context.enter();
103: try {
104: global = new ImporterTopLevel(context);
105: global.put("page", global, Context.toObject(this , global));
106: global.put("logger", global, Context.toObject(getLogger(),
107: global));
108: global.put("xspAttr", global, Context.toObject(
109: new AttributesImpl(), global));
110:
111: context.setOptimizationLevel(-1);
112:
113: if (getLogger().isDebugEnabled()) {
114: getLogger().debug("Compiling script " + file);
115: }
116: script = context.compileReader(global,
117: new FileReader(file), file.toString(), 1, null);
118: } catch (Exception e) {
119: compileError = e;
120: } finally {
121: Context.exit();
122: }
123: }
124:
125: public void setup(SourceResolver resolver, Map objectModel,
126: String src, Parameters par) throws ProcessingException,
127: SAXException, IOException {
128: super .setup(resolver, objectModel, src, par);
129:
130: if (compileError != null) {
131: throw new ProcessingException("Failed to compile script",
132: compileError);
133: }
134:
135: // add enter/exit here, too
136: Context.enter();
137: try {
138: global.put("objectModel", global, Context.toObject(
139: this .objectModel, global));
140: global.put("request", global, Context.toObject(
141: this .request, global));
142: global.put("response", global, Context.toObject(
143: this .response, global));
144: global.put("context", global, Context.toObject(
145: this .context, global));
146: global.put("resolver", global, Context.toObject(
147: this .resolver, global));
148: global.put("parameters", global, Context.toObject(
149: this .parameters, global));
150: } catch (Exception e) {
151: throw new ProcessingException("setup: Got exception", e);
152: } finally {
153: Context.exit();
154: }
155: }
156:
157: public void generate() throws IOException, ProcessingException {
158: Context context = Context.enter();
159: try {
160: global.put("contentHandler", global, Context.toObject(
161: this .contentHandler, global));
162:
163: context.setOptimizationLevel(-1);
164:
165: if (getLogger().isDebugEnabled()) {
166: getLogger().debug("Executing script " + file);
167: }
168:
169: script.exec(context, global);
170: } catch (JavaScriptException e) {
171: throw new ProcessingException(
172: "generate: Got Javascript exception", e);
173: } finally {
174: Context.exit();
175: }
176: }
177:
178: public void recycle() {
179: global.delete("contentHandler");
180:
181: global.delete("objectModel");
182: global.delete("request");
183: global.delete("response");
184: global.delete("context");
185: global.delete("resolver");
186: global.delete("parameters");
187:
188: super .recycle();
189: }
190:
191: public void dispose() {
192: global.delete("page");
193: global.delete("logger");
194: global.delete("xspAttr");
195: this .global = null;
196: this .script = null;
197: this .compileError = null;
198:
199: super .dispose();
200: }
201:
202: // XSPRequestHelper
203:
204: public void getLocale() throws SAXException {
205: XSPRequestHelper.getLocale(this .objectModel,
206: this .contentHandler);
207: }
208:
209: public Locale[] getLocalesAsArray() {
210: return XSPRequestHelper.getLocales(this .objectModel);
211: }
212:
213: public void getLocalesAsXML() throws SAXException {
214: XSPRequestHelper.getLocale(this .objectModel,
215: this .contentHandler);
216: }
217:
218: public String getParameter(String name, String defaultValue) {
219: return XSPRequestHelper.getParameter(this .objectModel, name,
220: defaultValue);
221: }
222:
223: public String getParameter(String name, String defaultValue,
224: String form_encoding, String container_encoding) {
225: return XSPRequestHelper.getParameter(this .objectModel, name,
226: defaultValue, form_encoding, container_encoding);
227: }
228:
229: public void getParameterAsXML(String name, String defaultValue,
230: String form_encoding, String container_encoding)
231: throws SAXException {
232: XSPRequestHelper.getParameter(this .objectModel,
233: this .contentHandler, name, defaultValue, form_encoding,
234: container_encoding);
235: }
236:
237: public void getParameterValuesAsXML(String name,
238: String form_encoding, String container_encoding)
239: throws SAXException {
240: XSPRequestHelper.getParameterValues(this .objectModel,
241: this .contentHandler, name, form_encoding,
242: container_encoding);
243: }
244:
245: public String[] getParameterValues(String name,
246: String form_encoding, String container_encoding) {
247: return XSPRequestHelper.getParameterValues(this .objectModel,
248: name, form_encoding, container_encoding);
249: }
250:
251: public String[] getParameterNames() {
252: return XSPRequestHelper.getParameterNames(this .objectModel);
253: }
254:
255: public void getParameterNamesAsXML() throws SAXException {
256: XSPRequestHelper.getParameterNames(this .objectModel,
257: this .contentHandler);
258: }
259:
260: public void getHeaderNamesAsXML() throws SAXException {
261: XSPRequestHelper.getHeaderNames(this .objectModel,
262: this .contentHandler);
263: }
264:
265: public String[] getHeaderNames() {
266: return XSPRequestHelper.getHeaderNames(this .objectModel);
267: }
268:
269: public String[] getHeaders(String name) {
270: return XSPRequestHelper.getHeaders(this .objectModel, name);
271: }
272:
273: public void getHeadersAsXML(String name) throws SAXException {
274: XSPRequestHelper.getHeaders(this .objectModel, name,
275: this .contentHandler);
276: }
277:
278: public Date getDateHeader(String name) {
279: return XSPRequestHelper.getDateHeader(this .objectModel, name);
280: }
281:
282: public String getDateHeader(String name, String format) {
283: return XSPRequestHelper.getDateHeader(this .objectModel, name,
284: format);
285: }
286:
287: public void getAttributeNames(ContentHandler contentHandler)
288: throws SAXException {
289: XSPRequestHelper.getAttributeNames(this .objectModel,
290: contentHandler);
291: }
292:
293: public String[] getAttributeNames() {
294: return XSPRequestHelper.getAttributeNames(this .objectModel);
295: }
296:
297: public String getRequestedURL() {
298: return XSPRequestHelper.getRequestedURL(this .objectModel);
299: }
300:
301: // XSPResponseHelper
302:
303: public void responseGetLocale() throws SAXException {
304: XSPResponseHelper.getLocale(this .response, this .contentHandler);
305: }
306:
307: public void addDateHeader(String name, long date) {
308: XSPResponseHelper.addDateHeader(this .response, name, date);
309: }
310:
311: public void addDateHeader(String name, Date date) {
312: XSPResponseHelper.addDateHeader(this .response, name, date);
313: }
314:
315: public void addDateHeader(String name, String date)
316: throws ParseException {
317: XSPResponseHelper.addDateHeader(this .response, name, date);
318: }
319:
320: public void addDateHeader(String name, String date, String format)
321: throws ParseException {
322: XSPResponseHelper.addDateHeader(this .response, name, date,
323: format);
324: }
325:
326: public void addDateHeader(String name, String date,
327: DateFormat format) throws ParseException {
328: XSPResponseHelper.addDateHeader(this .response, name, date,
329: format);
330: }
331:
332: public void setDateHeader(String name, long date) {
333: XSPResponseHelper.setDateHeader(this .response, name, date);
334: }
335:
336: public void setDateHeader(String name, Date date) {
337: XSPResponseHelper.setDateHeader(this .response, name, date);
338: }
339:
340: public void setDateHeader(String name, String date)
341: throws ParseException {
342: XSPResponseHelper.setDateHeader(this .response, name, date);
343: }
344:
345: public void setDateHeader(String name, String date, String format)
346: throws ParseException {
347: XSPResponseHelper.setDateHeader(this .response, name, date,
348: format);
349: }
350:
351: public void setDateHeader(String name, String date,
352: DateFormat format) throws ParseException {
353: XSPResponseHelper.setDateHeader(this .response, name, date,
354: format);
355: }
356:
357: // XSPSessionHelper
358: public Object getSessionAttribute(Session session, String name,
359: Object defaultValue) {
360: return XSPSessionHelper.getSessionAttribute(session, name,
361: defaultValue);
362: }
363:
364: public String[] getSessionAttributeNames(Session session) {
365: Collection c = XSPSessionHelper
366: .getSessionAttributeNames(session);
367: return (String[]) c.toArray(new String[c.size()]);
368: }
369: }
|