/* * 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 java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Map; import java.util.Properties; 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.Constants; import org.apache.cocoon.ProcessingException; import org.apache.cocoon.environment.SourceResolver; import org.python.core.Py; import org.python.core.PyCode; import org.python.util.PythonInterpreter; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; /** * Class representing interpreted XSP-generated * <code>ServerPagesGenerator</code> programs * written in Python language * * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a> * @version CVS $Id$ */ public class PythonGenerator extends XSPGenerator implements Configurable, Initializable { /** * Python source file */ private File file; private PythonInterpreter python; private PyCode code; 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 { try { Properties properties = new Properties(); File workDir = (File)avalonContext.get(Constants.CONTEXT_WORK_DIR); properties.setProperty("python.home", workDir.toString()); properties.setProperty("python.packages.fakepath", (String)avalonContext.get(Constants.CONTEXT_CLASSPATH)); PythonInterpreter.initialize(System.getProperties(), properties, new String[]{}); python = new PythonInterpreter(); python.set("page", this); python.set("logger", getLogger()); python.set("xspAttr", new AttributesImpl()); if (getLogger().isDebugEnabled()) { getLogger().debug("Compiling script " + file); } this.code = Py.compile(new FileInputStream(this.file), this.file.toString(), "exec"); } catch (Exception e) { this.compileError = e; } } public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException { super.setup(resolver, objectModel, src, par); if (this.compileError != null) { throw new ProcessingException("Failed to compile script", compileError); } python.set("objectModel", this.objectModel); python.set("request", this.request); python.set("response", this.response); python.set("context", this.context); python.set("resolver", this.resolver); python.set("parameters", this.parameters); } public void generate() throws IOException, ProcessingException { try { python.set("contentHandler", this.contentHandler); if (getLogger().isDebugEnabled()) { getLogger().debug("Executing script " + file); } python.exec(code); } catch (Exception e) { throw new ProcessingException("generate: Got Python exception", e); } } public void recycle() { python.set("contentHandler", null); python.set("objectModel", null); python.set("request", null); python.set("response", null); python.set("context", null); python.set("resolver", null); python.set("parameters", null); super.recycle(); } public void dispose() { python.set("page", null); python.set("logger", null); python.set("xspAttr", null); this.python = null; this.compileError = null; this.code = null; super.dispose(); } }