Hi,

I've been using Jython in cocoon for some time by using my own 
JythonGenerator. And I feel it's simplicity and speed that I can test 
things is very nice.

ScriptGenerator have several shortcomings regarding using Jythons Lib 
modules and I tried to fix them, but they messed ScriptGenerator too 
much ,so I decided to move all those modifications to JythonGenerator.

I'm using JythonGenerator like this:
<map:generate src="tests/test.py" type="python">
   <parameter name="databasepool" value="valkeus"/>
   <parameter name="python.path" value="c:/prog/jython/lib"/>
   <parameter name="classpath" value="c:/prog/jython/jython.jar"/>

Not sure are those settings best to be there or somewhere else?

I can also import all .py files that are in python.path or in the same 
directory as my test.py.

Example script using database:
test.py
-----
import com.ziclix.python.sql as sql
import mymodule

#connection is pooled connection from sitemap
con = sql.PyConnection(connection)
cur = con.cursor(1);

user = request.getParameter("user")
data = mymodule.getdata()

output.append("<db>")

cur.execute("select * from users where name=? and data=?",(user,data))
for users in cur.fetchall():
    output.append("<user>%s</user>"%users[0])

output.append("</db>")
-----

I feel quite good on using Jython with Cocoon, it let me escape from XSP 
verbosity. The question of speed arises though. Now script is loaded 
everytime request comes. Any advise on that?

In attachment you can find the JythonGenerator.

Thanks,
  Lassi Immonen
/*

 ============================================================================
                   The Apache Software License, Version 1.1
 ============================================================================

 Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.

 Redistribution and use in source and binary forms, with or without modifica-
 tion, are permitted provided that the following conditions are met:

 1. Redistributions of  source code must  retain the above copyright  notice,
    this list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

 3. The end-user documentation included with the redistribution, if any, must
    include  the following  acknowledgment:  "This product includes  software
    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
    Alternately, this  acknowledgment may  appear in the software itself,  if
    and wherever such third-party acknowledgments normally appear.

 4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
    used to  endorse or promote  products derived from  this software without
    prior written permission. For written permission, please contact
    [EMAIL PROTECTED]

 5. Products  derived from this software may not  be called "Apache", nor may
    "Apache" appear  in their name,  without prior written permission  of the
    Apache Software Foundation.

 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
 APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
 INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
 DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
 OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
 ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
 (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 This software  consists of voluntary contributions made  by many individuals
 on  behalf of the Apache Software  Foundation and was  originally created by
 Stefano Mazzocchi  <[EMAIL PROTECTED]>. For more  information on the Apache
 Software Foundation, please see <http://www.apache.org/>.

*/
package org.apache.cocoon.generation;

import org.apache.avalon.excalibur.xml.Parser;
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.context.Contextualizable;
//import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;

//import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.*;
import org.apache.avalon.excalibur.datasource.DataSourceComponent;


import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.ResourceNotFoundException;
import org.apache.cocoon.environment.Source;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Response;
import org.apache.cocoon.environment.Context;
import org.apache.cocoon.Constants;
import org.xml.sax.InputSource;

import java.io.FileNotFoundException;
import java.io.Reader;
import java.io.StringReader;
import java.io.File;

import org.python.util.PythonInterpreter; 
import org.python.core.*; 

import java.sql.Connection;
import java.util.Properties;
/**
 * The JythonGenerator executes arbitarily python scripts
 *
 */
public class JythonGenerator extends ComposerGenerator implements 
Composable,Contextualizable {

        /**The database selector */
        protected ComponentSelector dbSelector;

        /** The source */
        private Source inputSource;

        protected org.apache.avalon.framework.context.Context avalonContext = null;

        /**
         * Composable
         */
        public void compose(ComponentManager manager) throws ComponentException {
                super.compose(manager); 
                if (this.dbSelector == null) {
                        try {           
                                this.dbSelector = (ComponentSelector) manager.lookup( 
DataSourceComponent.ROLE + "Selector");
                        } catch ( ComponentException cme ) {
                                this.getLogger().error( "Could not get the DataSource 
Selector", cme );
                        }
                }
        }

        /** Contextualize this class */
        public void contextualize(org.apache.avalon.framework.context.Context context) 
throws ContextException  {
                this.avalonContext = context;
        }


        public void recycle() {
                super.recycle();
                if (this.inputSource != null) {
                        this.inputSource.recycle();
                        this.inputSource = null;
                }
        }

        public void generate() throws ProcessingException {
                Parser parser = null;
                try {
                        // Figure out what file to open and do so
                        getLogger().debug("processing file [" + super.source + "]");
                        this.inputSource = this.resolver.resolve(super.source);

                        getLogger().debug("file resolved to [" + 
this.inputSource.getSystemId() + "]");


                        // TODO: why doesn't this work?
                        // Reader in = src.getCharacterStream();
                        Reader in = new 
java.io.InputStreamReader(this.inputSource.getInputStream());

                        StringBuffer output = new StringBuffer();

                        getLogger().debug("JythonGenerator execution begining");

                        String poolName = 
this.parameters.getParameter("databasepool",null);
                        String pythonpath = 
this.parameters.getParameter("python.path","");
                        String scriptDir = this.inputSource.getSystemId();
                        if (scriptDir.startsWith("file:") )
                                scriptDir = scriptDir.substring(5);

                        String pythonSrc = scriptDir;

                        //Better ways to do this?
                        int li = scriptDir.lastIndexOf('/');
                        if (li < scriptDir.length()-1)
                                scriptDir = scriptDir.substring(0, li);

                        pythonpath += File.pathSeparatorChar + scriptDir;       

                        File workDir = 
(File)avalonContext.get(Constants.CONTEXT_WORK_DIR);
                        getLogger().debug("avalon workdir:" + workDir.toString());
                        String fcp = 
(String)avalonContext.get(Constants.CONTEXT_CLASSPATH);
                        //getLogger().debug("context classpath :" + fcp);       
                
                        // adding classpath also
                        String classpath = 
this.parameters.getParameter("classpath","");
                        Properties properties = new Properties();
                        properties.setProperty("java.class.path",classpath);
                        properties.setProperty("python.path",pythonpath);
                        properties.setProperty("python.home", workDir.toString());
                        properties.setProperty("python.packages.fakepath", fcp);

                        PythonInterpreter.initialize(System.getProperties(), 
properties, new String[]{});
                        PythonInterpreter pyi = new PythonInterpreter();

                        // Declaring these instead of registering for these to be 
always avail
                        pyi.set("resolver", this.resolver);
                        pyi.set("source", super.source);
                        pyi.set("parameters", this.parameters);
                        pyi.set("output", output);
                        pyi.set("logger", getLogger());
                        Request req = ObjectModelHelper.getRequest(this.objectModel);
                        Response res = ObjectModelHelper.getResponse(this.objectModel);
                        Context con = ObjectModelHelper.getContext(this.objectModel);
                        pyi.set("request",req);
                        pyi.set("response",res);
                        pyi.set("context",con);
                        // Giving connection to script if it want's one
                        if (poolName != null) {
                                try {
                                        getLogger().debug("Getting databasepool named: 
"+poolName);
                                        DataSourceComponent datasource = 
(DataSourceComponent)dbSelector.select(poolName);
                                        Connection connection = 
datasource.getConnection();
                                        pyi.set("connection", connection);
                                }catch( Exception e) {
                                        getLogger().error("Could not get the 
datasource",e);
                                        throw new RuntimeException("Could not get the 
datasource "+e);
                                }
                        } 

                        // Execute the script
                        getLogger().debug("Running python script [" +pythonSrc+ "]");

                        pyi.execfile(pythonSrc);

                        getLogger().debug("output = [" + output.toString() + "]");

                        // Extract the XML string from the BSFManager and parse it

                        InputSource xmlInput =

                        parser = (Parser)(this.manager.lookup(Parser.ROLE));
                        parser.parse(xmlInput, this.xmlConsumer);
                } catch (ProcessingException e) {
                        throw e;
                } catch (FileNotFoundException e) {
                        throw new ResourceNotFoundException(
                                        "Could not load script " + 
this.inputSource.getSystemId(), e);
                } catch (PyException e) { 
                        throw new ProcessingException("PythonException in 
JythonGenerator.generate()", e);
                }catch (Exception e) {
                        throw new ProcessingException(
                                        "Exception in JythonGenerator.generate()", e);
                } finally {
                        this.manager.release(parser);
                }
        }
}

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to