blob: 75660d4dbf13af47dde1bc6105b04e8e997dc582 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.cocoon.components.language.markup.xsp;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.SourceResolver;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Scriptable;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Collection;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
/**
* Class representing interpreted XSP-generated
* <code>ServerPagesGenerator</code> programs
* written in Javascript language
*
* @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
* @version CVS $Id$
*/
public class JSGenerator extends XSPGenerator
implements Configurable, Initializable {
/**
* Javascript source file
*/
private File file;
private Scriptable global;
// FIXME: Use Store to cache compiled scripts
private Script script;
private Exception compileError;
public void configure(Configuration configuration) throws ConfigurationException {
this.file = new File(configuration.getChild("file").getValue());
Configuration[] dependencies = configuration.getChildren("dependency");
this.dependencies = new File[dependencies.length];
for (int i = 0; i < dependencies.length; i ++) {
this.dependencies[i] = new File(dependencies[i].getValue());
}
}
/**
* Determines whether this generator's source files have changed
*
* @return Whether any of the files this generator depends on has changed
* since it was created
*/
public boolean modifiedSince(long date) {
if (this.file.lastModified() < date) {
return true;
}
for (int i = 0; i < dependencies.length; i++) {
if (this.file.lastModified() < dependencies[i].lastModified()) {
return true;
}
}
return false;
}
public void initialize() throws Exception {
Context context = Context.enter();
try {
global = new ImporterTopLevel(context);
global.put("page", global, Context.toObject(this, global));
global.put("logger", global, Context.toObject(getLogger(), global));
global.put("xspAttr", global, Context.toObject(new AttributesImpl(), global));
context.setOptimizationLevel(-1);
if (getLogger().isDebugEnabled()) {
getLogger().debug("Compiling script " + file);
}
script = context.compileReader(global, new FileReader(file), file.toString(), 1, null);
} catch (Exception e) {
compileError = e;
} finally {
Context.exit();
}
}
public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
throws ProcessingException, SAXException, IOException {
super.setup(resolver, objectModel, src, par);
if (compileError != null) {
throw new ProcessingException("Failed to compile script", compileError);
}
// add enter/exit here, too
Context.enter();
try {
global.put("objectModel", global, Context.toObject(this.objectModel, global));
global.put("request", global, Context.toObject(this.request, global));
global.put("response", global, Context.toObject(this.response, global));
global.put("context", global, Context.toObject(this.context, global));
global.put("resolver", global, Context.toObject(this.resolver, global));
global.put("parameters", global, Context.toObject(this.parameters, global));
} catch (Exception e) {
throw new ProcessingException("setup: Got exception", e);
} finally {
Context.exit();
}
}
public void generate() throws IOException, ProcessingException {
Context context = Context.enter();
try {
global.put("contentHandler", global, Context.toObject(this.contentHandler, global));
context.setOptimizationLevel(-1);
if (getLogger().isDebugEnabled()) {
getLogger().debug("Executing script " + file);
}
script.exec(context, global);
} catch (JavaScriptException e) {
throw new ProcessingException("generate: Got Javascript exception", e);
} finally {
Context.exit();
}
}
public void recycle() {
global.delete("contentHandler");
global.delete("objectModel");
global.delete("request");
global.delete("response");
global.delete("context");
global.delete("resolver");
global.delete("parameters");
super.recycle();
}
public void dispose() {
global.delete("page");
global.delete("logger");
global.delete("xspAttr");
this.global = null;
this.script = null;
this.compileError = null;
super.dispose();
}
// XSPRequestHelper
public void getLocale() throws SAXException {
XSPRequestHelper.getLocale(this.objectModel, this.contentHandler);
}
public Locale[] getLocalesAsArray() {
return XSPRequestHelper.getLocales(this.objectModel);
}
public void getLocalesAsXML() throws SAXException {
XSPRequestHelper.getLocale(this.objectModel, this.contentHandler);
}
public String getParameter(String name, String defaultValue) {
return XSPRequestHelper.getParameter(this.objectModel, name, defaultValue);
}
public String getParameter(String name, String defaultValue,
String form_encoding, String container_encoding) {
return XSPRequestHelper.getParameter(this.objectModel, name, defaultValue,
form_encoding, container_encoding);
}
public void getParameterAsXML(String name, String defaultValue,
String form_encoding, String container_encoding)
throws SAXException {
XSPRequestHelper.getParameter(this.objectModel, this.contentHandler, name, defaultValue,
form_encoding, container_encoding);
}
public void getParameterValuesAsXML(String name, String form_encoding,
String container_encoding)
throws SAXException {
XSPRequestHelper.getParameterValues(this.objectModel, this.contentHandler,
name, form_encoding, container_encoding);
}
public String[] getParameterValues(String name,
String form_encoding,
String container_encoding) {
return XSPRequestHelper.getParameterValues(this.objectModel,
name, form_encoding, container_encoding);
}
public String[] getParameterNames() {
return XSPRequestHelper.getParameterNames(this.objectModel);
}
public void getParameterNamesAsXML() throws SAXException {
XSPRequestHelper.getParameterNames(this.objectModel, this.contentHandler);
}
public void getHeaderNamesAsXML() throws SAXException {
XSPRequestHelper.getHeaderNames(this.objectModel, this.contentHandler);
}
public String[] getHeaderNames() {
return XSPRequestHelper.getHeaderNames(this.objectModel);
}
public String[] getHeaders(String name) {
return XSPRequestHelper.getHeaders(this.objectModel, name);
}
public void getHeadersAsXML(String name)
throws SAXException {
XSPRequestHelper.getHeaders(this.objectModel, name, this.contentHandler);
}
public Date getDateHeader(String name) {
return XSPRequestHelper.getDateHeader(this.objectModel, name);
}
public String getDateHeader(String name, String format) {
return XSPRequestHelper.getDateHeader(this.objectModel, name, format);
}
public void getAttributeNames(ContentHandler contentHandler)
throws SAXException {
XSPRequestHelper.getAttributeNames(this.objectModel, contentHandler);
}
public String[] getAttributeNames() {
return XSPRequestHelper.getAttributeNames(this.objectModel);
}
public String getRequestedURL() {
return XSPRequestHelper.getRequestedURL(this.objectModel);
}
// XSPResponseHelper
public void responseGetLocale()
throws SAXException {
XSPResponseHelper.getLocale(this.response, this.contentHandler);
}
public void addDateHeader(String name, long date) {
XSPResponseHelper.addDateHeader(this.response, name, date);
}
public void addDateHeader(String name, Date date) {
XSPResponseHelper.addDateHeader(this.response, name, date);
}
public void addDateHeader(String name, String date) throws ParseException {
XSPResponseHelper.addDateHeader(this.response, name, date);
}
public void addDateHeader(String name, String date, String format) throws ParseException {
XSPResponseHelper.addDateHeader(this.response, name, date, format);
}
public void addDateHeader(String name, String date, DateFormat format) throws ParseException {
XSPResponseHelper.addDateHeader(this.response, name, date, format);
}
public void setDateHeader(String name, long date) {
XSPResponseHelper.setDateHeader(this.response, name, date);
}
public void setDateHeader(String name, Date date) {
XSPResponseHelper.setDateHeader(this.response, name, date);
}
public void setDateHeader(String name, String date) throws ParseException {
XSPResponseHelper.setDateHeader(this.response, name, date);
}
public void setDateHeader(String name, String date, String format) throws ParseException {
XSPResponseHelper.setDateHeader(this.response, name, date, format);
}
public void setDateHeader(String name, String date, DateFormat format) throws ParseException {
XSPResponseHelper.setDateHeader(this.response, name, date, format);
}
// XSPSessionHelper
public Object getSessionAttribute(Session session, String name, Object defaultValue) {
return XSPSessionHelper.getSessionAttribute(session, name, defaultValue);
}
public String[] getSessionAttributeNames(Session session) {
Collection c = XSPSessionHelper.getSessionAttributeNames(session);
return (String[])c.toArray(new String[c.size()]);
}
}