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 java.io.File;
020: import java.io.FileInputStream;
021: import java.io.IOException;
022: import java.util.Map;
023: import java.util.Properties;
024:
025: import org.apache.avalon.framework.activity.Initializable;
026: import org.apache.avalon.framework.configuration.Configurable;
027: import org.apache.avalon.framework.configuration.Configuration;
028: import org.apache.avalon.framework.configuration.ConfigurationException;
029: import org.apache.avalon.framework.parameters.Parameters;
030:
031: import org.apache.cocoon.Constants;
032: import org.apache.cocoon.ProcessingException;
033: import org.apache.cocoon.environment.SourceResolver;
034:
035: import org.python.core.Py;
036: import org.python.core.PyCode;
037: import org.python.util.PythonInterpreter;
038: import org.xml.sax.SAXException;
039: import org.xml.sax.helpers.AttributesImpl;
040:
041: /**
042: * Class representing interpreted XSP-generated
043: * <code>ServerPagesGenerator</code> programs
044: * written in Python language
045: *
046: * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
047: * @version CVS $Id: PythonGenerator.java 433543 2006-08-22 06:22:54Z crossley $
048: */
049: public class PythonGenerator extends XSPGenerator implements
050: Configurable, Initializable {
051:
052: /**
053: * Python source file
054: */
055: private File file;
056:
057: private PythonInterpreter python;
058:
059: private PyCode code;
060: private Exception compileError;
061:
062: public void configure(Configuration configuration)
063: throws ConfigurationException {
064: this .file = new File(configuration.getChild("file").getValue());
065:
066: Configuration[] dependencies = configuration
067: .getChildren("dependency");
068: this .dependencies = new File[dependencies.length];
069: for (int i = 0; i < dependencies.length; i++) {
070: this .dependencies[i] = new File(dependencies[i].getValue());
071: }
072: }
073:
074: /**
075: * Determines whether this generator's source files have changed
076: *
077: * @return Whether any of the files this generator depends on has changed
078: * since it was created
079: */
080: public boolean modifiedSince(long date) {
081: if (this .file.lastModified() < date) {
082: return true;
083: }
084:
085: for (int i = 0; i < dependencies.length; i++) {
086: if (this .file.lastModified() < dependencies[i]
087: .lastModified()) {
088: return true;
089: }
090: }
091:
092: return false;
093: }
094:
095: public void initialize() throws Exception {
096: try {
097: Properties properties = new Properties();
098: File workDir = (File) avalonContext
099: .get(Constants.CONTEXT_WORK_DIR);
100: properties.setProperty("python.home", workDir.toString());
101: properties.setProperty("python.packages.fakepath",
102: (String) avalonContext
103: .get(Constants.CONTEXT_CLASSPATH));
104: PythonInterpreter.initialize(System.getProperties(),
105: properties, new String[] {});
106:
107: python = new PythonInterpreter();
108: python.set("page", this );
109: python.set("logger", getLogger());
110: python.set("xspAttr", new AttributesImpl());
111:
112: if (getLogger().isDebugEnabled()) {
113: getLogger().debug("Compiling script " + file);
114: }
115:
116: this .code = Py.compile(new FileInputStream(this .file),
117: this .file.toString(), "exec");
118: } catch (Exception e) {
119: this .compileError = e;
120: }
121: }
122:
123: public void setup(SourceResolver resolver, Map objectModel,
124: String src, Parameters par) throws ProcessingException,
125: SAXException, IOException {
126: super .setup(resolver, objectModel, src, par);
127:
128: if (this .compileError != null) {
129: throw new ProcessingException("Failed to compile script",
130: compileError);
131: }
132:
133: python.set("objectModel", this .objectModel);
134: python.set("request", this .request);
135: python.set("response", this .response);
136: python.set("context", this .context);
137: python.set("resolver", this .resolver);
138: python.set("parameters", this .parameters);
139: }
140:
141: public void generate() throws IOException, ProcessingException {
142: try {
143: python.set("contentHandler", this .contentHandler);
144:
145: if (getLogger().isDebugEnabled()) {
146: getLogger().debug("Executing script " + file);
147: }
148: python.exec(code);
149: } catch (Exception e) {
150: throw new ProcessingException(
151: "generate: Got Python exception", e);
152: }
153: }
154:
155: public void recycle() {
156: python.set("contentHandler", null);
157:
158: python.set("objectModel", null);
159: python.set("request", null);
160: python.set("response", null);
161: python.set("context", null);
162: python.set("resolver", null);
163: python.set("parameters", null);
164:
165: super .recycle();
166: }
167:
168: public void dispose() {
169: python.set("page", null);
170: python.set("logger", null);
171: python.set("xspAttr", null);
172:
173: this.python = null;
174: this.compileError = null;
175: this.code = null;
176:
177: super.dispose();
178: }
179: }
|