You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cocoon.apache.org by "Lyall, Keith" <Ke...@NewellandBudge.com> on 2003/03/12 14:16:05 UTC

Problem writing a BetwixtTransformer

Hi,

I am trying to write a BetwixtTransformer based on CastorTransformer but
have run into a problem.

Everything appears to be working Ok according to my logging messages until
the XML is serialized when I get this error:

java.lang.RuntimeException: java.lang.NullPointerException
	at
org.apache.xalan.transformer.TransformerImpl.run(TransformerImpl.java:3231)
	at java.lang.Thread.run(Thread.java:536)

To get the BetwixtTransformer up and running do the following:

1. Create an XML file to be read in via a generator:

<?xml version="1.0"?>
<document
xmlns:betwixt="http://jakarta.apache.org/commons/betwixt/betwixttransfomer">
    <betwixt:InsertBean name="form" scope="request"/>
</document>

2. Add the following to your sitemap.xmap:

<map:components>

    <map:transformers   default="xslt">
        <map:transformer logger="sitemap.transformer.betwixt" name="betwixt"
src="org.apache.cocoon.transformation.BetwixtTransformer"/>
    </map:transformers>

    <map:actions>
        <map:action
            name    ="DisplayFormAction"
            src     ="test.DisplayFormAction"
            logger  ="sitemap.action"/>
    </map:actions>

</map:components>

<map:pipelines>

    <map:pipeline>

        <map:match pattern="form*.xml">
            <map:act type="DisplayFormAction">
                <map:parameter name="form-pk" value="{1}"/>
            </map:act>

            <map:generate src="content/betwixt/form.xml"/>
            <map:transform type="betwixt"/>

            <map:transform type="log">
                <map:parameter name="logfile" value="c:/temp/logfile.log"/>
                <map:parameter name="append" value="no"/>
            </map:transform>

            <map:serialize type="xml"/>
        </map:match>


    </map:pipeline>

</map:pipelines>

3. Add the following two classes to your cocoon.war

/ ------------------ /
/ BetwixtTransformer /
/ ------------------ /


package org.apache.cocoon.transformation;

import org.apache.avalon.framework.parameters.Parameters;

import org.apache.cocoon.environment.Context;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.commons.betwixt.io.SAXBeanWriter;
import org.apache.commons.logging.impl.SimpleLog;

import org.xml.sax.Attributes;

import java.util.Map;

public class BetwixtTransformer extends AbstractTransformer
{
    private static final String BETWIXT_URI =
        "http://jakarta.apache.org/commons/betwixt/betwixttransfomer";
    private static final String CMD_INSERT_BEAN = "InsertBean";

    private static final String ATTRIB_NAME = "name";
    private static final String ATTRIB_SCOPE = "scope";
    private static final String VALUE_SITEMAP = "sitemap";
    private static final String VALUE_SESSION = "session";
    private static final String VALUE_REQUEST = "request";
    private static final String VALUE_CONTEXT = "context";

    private boolean in_betwixt_element = false;

    private Map objectModel;
    private SourceResolver resolver;

    /**
     * Default constructor
     */
    public BetwixtTransformer()
    {
    }

    /**
     * @see
org.apache.cocoon.sitemap.SitemapModelComponent#setup(SourceResolver, Map,
String, Parameters)
     */
    public void setup(
        SourceResolver resolver,
        Map objectModel,
        String source,
        Parameters params)
        throws
            org.apache.cocoon.ProcessingException,
            org.xml.sax.SAXException,
            java.io.IOException
    {
        this.objectModel = objectModel;
        this.resolver = resolver;
    }

    /**
     * @see org.xml.sax.ContentHandler#endElement(String, String, String)
     */
    public void endElement(String uri, String name, String raw)
        throws org.xml.sax.SAXException
    {
        getLogger().debug("endElement: " + name);

        // Check that we are currently in the Betwixt
        if (BETWIXT_URI.equals(uri))
        {
            in_betwixt_element = false;
            return;

        }

        super.endElement(uri, name, raw);
    }

    /**
     * @see org.xml.sax.ContentHandler#startElement(String, String, String,
Attributes)
     */
    public void startElement(
        String uri,
        String name,
        String raw,
        Attributes attr)
        throws org.xml.sax.SAXException
    {
        getLogger().debug("startElement: " + name);

        if (BETWIXT_URI.equals(uri))
        {
            in_betwixt_element = true;

            process(name, attr);
            return;
        }

        super.startElement(uri, name, raw, attr);
    }

    /**
     * @see org.xml.sax.ContentHandler#characters(char[], int, int)
     */
    public void characters(char[] ch, int start, int len)
        throws org.xml.sax.SAXException
    {
        if (in_betwixt_element)
        {
            return;
        }

        super.characters(ch, start, len);
    }

    /**
     * Method process.
     * @param command
     * @param attr
     */
    private void process(String command, Attributes attr)
    {
        if (command.equals(CMD_INSERT_BEAN))
        {
            String sourcemap = attr.getValue(ATTRIB_SCOPE);
            String name = attr.getValue(ATTRIB_NAME);

            Object toInsert;

            Request request = ObjectModelHelper.getRequest(objectModel);

            if (name == null)
            {
                getLogger().error("attribut to insert not set");
            }
            /*
              searcl all maps for the given bean
            */
            else
            {
                if (sourcemap == null || VALUE_SITEMAP.equals(sourcemap))
                {
                    getLogger().debug(
                        "Searching bean '" + name + "' in " +
VALUE_SITEMAP);

                    toInsert = objectModel.get(name);

                    if (toInsert != null)
                    {
                        insertBean(toInsert);

                        return;
                    }
                }

                if (sourcemap == null || VALUE_REQUEST.equals(sourcemap))
                {
                    getLogger().debug(
                        "Searching bean '" + name + "' in " +
VALUE_REQUEST);

                    toInsert = request.getAttribute(name);

                    if (toInsert != null)
                    {
                        insertBean(toInsert);

                        return;
                    }
                }

                if (sourcemap == null || VALUE_SESSION.equals(sourcemap))
                {
                    getLogger().debug(
                        "Searching bean '" + name + "' in " +
VALUE_SESSION);

                    Session session = request.getSession(false);

                    if (session != null)
                    {
                        toInsert = session.getAttribute(name);

                        if (toInsert != null)
                        {
                            insertBean(toInsert);

                            return;
                        }
                    }
                }

                if (sourcemap == null || VALUE_CONTEXT.equals(sourcemap))
                {
                    getLogger().debug(
                        "Searching bean '" + name + "' in " +
VALUE_CONTEXT);

                    Context context =
ObjectModelHelper.getContext(objectModel);

                    if (context != null)
                    {
                        toInsert = context.getAttribute(name);

                        if (toInsert != null)
                        {
                            insertBean(toInsert);

                            return;
                        }
                    }
                }
            }

            getLogger().debug("Bean " + name + " could not be found");

            return;
        } // end CMD_INSERT_BEAN

        getLogger().error("Unknown command: " + command);
    }

    /**
     * Method insertBean.
     * @param bean
     * @param mappingpath
     */
    //??    private void insertBean(Object bean, String mappingpath)
    private void insertBean(Object bean)
    {
        // If there is a bean then marshal it into XML
        if (bean != null)
        {
            getLogger().debug("Bean found");

            try
            {
                SAXBeanWriter writer =
                    new SAXBeanWriter(
                        new BetwixtSAXEventHandler(
                            contentHandler,
                            getLogger()));

                writer.setLog(new SimpleLog("Betwixt"));
 
writer.getXMLIntrospector().setAttributesForPrimitives(false);
                writer.setWriteIDs(false);

                writer.write(bean);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        else
        {
            getLogger().debug("No bean found");
        }

    }
}

/ ---------------------- /
/ BetwixtSAXEventHandler /
/ ---------------------- /

package org.apache.cocoon.transformation;

import org.apache.avalon.framework.logger.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class BetwixtSAXEventHandler extends DefaultHandler
{
    private ContentHandler contentHandler;
    private Logger logger;

    /**
     * Constructor for BetwixtSAXEventHandler.
     */
    public BetwixtSAXEventHandler(ContentHandler contentHandler, Logger
logger)
    {
        super();

        this.contentHandler = contentHandler;
        this.logger = logger;

        logger.debug("BetwixtSAXEventHandler initialised.");
    }

    /**
     * @see org.xml.sax.ContentHandler#characters(char[], int, int)
     */
    public void characters(char[] chars, int offset, int length)
        throws SAXException
    {
        logger.debug("characters: " + new String(chars));

        contentHandler.characters(chars, offset, length);
    }

    /**
     * @see org.xml.sax.ContentHandler#endElement(String, String, String)
     */
    public void endElement(String namespaceURI, String localName, String
qName)
        throws SAXException
    {
        logger.debug("endElement: " + localName + ":" + qName);

        contentHandler.endElement(namespaceURI, localName, qName);
    }

    /**
     * @see org.xml.sax.ContentHandler#startElement(String, String, String,
Attributes)
     */
    public void startElement(
        String namespaceURI,
        String localName,
        String qName,
        Attributes atts)
        throws SAXException
    {
        logger.debug("startElement: " + localName + ":" + qName);

        contentHandler.startElement(namespaceURI, localName, qName, atts);
    }
}

4. For Betwixt to work the following jar files will need to be added to the
cocoon.war:

commons-betwixt-1.0-alpha-1.jar
commons-collections.jar
commons-digester.jar

5. Finally an Action needs to be written to stick a bean object in to the
request.

Just in case you are asking 'why don't you just use the CastorTransformer?'
the answer is that Castor was falling over with the bean I was using (the
bean was a value object created using XDoclet). This happened inside and
outside of Cocoon. A quick test using Betwixt standalone worked with any
problem. Therefore I thought it might be useful to write a Betwixt
transformer for cocoon.

Any help is much appreciated.

Keith.

********************************************************************************
  This electronic mail system is used for information purposes and is
  not intended to form any legal contract or binding agreement.
  The content is confidential and may be legally privileged. Access
  by anyone other than the addressee(s) is unauthorised and any
  disclosure, copying, distribution or any other action taken in
  reliance on it is prohibited and maybe unlawful

  All incoming and outgoing e-mail communications and attachments
  are scanned automatically by software designed to detect and remove
  any material containing viruses or other unauthorised content.  While
  we undertake best endeavours to ensure that this content checking
  software is up to date, recipients should take steps to assure themselves
  that e-mails received are secure.
********************************************************************************

AW: Problem writing a BetwixtTransformer

Posted by Marco Rolappe <m_...@web.de>.
Problem writing a BetwixtTransformerhi keith,

I didn't analyze the code and can't tell you directly where the bug is
but...

I also got a similar exception which seemed to be an XSLT/xalan exception
but actually was an exception thrown from within a custom transformer.
somehow the stack trace seems to have been lost.

you might want to debug your trasformer to find the actual bug.
  -----Ursprüngliche Nachricht-----
  Von: cocoon-users-return-47662-m_rolappe=web.de@xml.apache.org
[mailto:cocoon-users-return-47662-m_rolappe=web.de@xml.apache.org]Im Auftrag
von Lyall, Keith
  Gesendet: Mittwoch, 12. März 2003 14:16
  An: 'cocoon-users@xml.apache.org'
  Betreff: Problem writing a BetwixtTransformer


  Hi,

  I am trying to write a BetwixtTransformer based on CastorTransformer but
have run into a problem.

  Everything appears to be working Ok according to my logging messages until
the XML is serialized when I get this error:

  java.lang.RuntimeException: java.lang.NullPointerException
          at
org.apache.xalan.transformer.TransformerImpl.run(TransformerImpl.java:3231)
          at java.lang.Thread.run(Thread.java:536)