Package org.apache.cocoon.portal.transformation

Source Code of org.apache.cocoon.portal.transformation.CopletTransformer

/*
* Copyright 1999-2002,2004-2005 The Apache Software Foundation.
*
* Licensed 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.portal.transformation;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.wrapper.RequestParameters;
import org.apache.cocoon.portal.LinkService;
import org.apache.cocoon.portal.coplet.CopletInstanceData;
import org.apache.cocoon.portal.event.impl.ChangeCopletInstanceAspectDataEvent;
import org.apache.cocoon.portal.event.impl.CopletJXPathEvent;
import org.apache.cocoon.portal.event.impl.JXPathEvent;
import org.apache.cocoon.xml.AttributesImpl;
import org.apache.cocoon.xml.XMLUtils;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.excalibur.xml.sax.XMLizable;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

/**
* This transformer offers various functions for developing pipeline based coplets.
*
* Includes coplet instance data by using JXPath expressions.
* The transformer searches for tags <coplet:coplet xmlns:coplet="http://apache.org/cocoon/portal/coplet/1.0">.
* They must have an attribute "select" that contains a valid JXPath expression applying to the coplet instance data.<br><br>
*
* Example:<br><br>
*
* <pre>&lt;maxpageable xmlns:coplet="http://apache.org/cocoon/portal/coplet/1.0"&gt;
*   &lt;coplet:coplet select="copletData.maxpageable"/&gt;
* &lt;/maxpageable&gt;<br></pre>
*
* The transformer will insert the boolean value specifying whether the coplet is
* maxpageable or not.<br>
* Please see also the documentation of superclass AbstractCopletTransformer for how
* the coplet instance data are acquired.
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @author <a href="mailto:bluetkemeier@s-und-n.de">Bj&ouml;rn L&uuml;tkemeier</a>
* @version CVS $Id: CopletTransformer.java 344185 2005-11-14 19:40:03Z cziegeler $
*/
public class CopletTransformer
extends AbstractCopletTransformer {

    /**
     * The namespace URI to listen for.
     */
    public static final String NAMESPACE_URI = "http://apache.org/cocoon/portal/coplet/1.0";

    /**
     * The XML element name to listen for.
     */
    public static final String COPLET_ELEM = "coplet";

    /**
     * The attribute containing the JXPath expression.
     */
    public static final String SELECT_ATTR = "select";


    /**
     * The XML element name to listen for.
     */
    public static final String LINK_ELEM = "link";

    /** Create a link containing several events */
    public static final String LINKS_ELEM = "links";

    /** Create a link containing several events */
    public static final String PARAMETER_ELEM = "parameter";

    /** The content for the links element */
    public static final String CONTENT_ELEM = "content";

    /** Are we inside a links element? */
    protected boolean insideLinks;

    /** The collected list of events */
    protected List collectedEvents = new ArrayList();

    /** The content of the links */
    protected XMLizable content;

    /**
     * Creates new CopletTransformer.
     */
    public CopletTransformer() {
        this.defaultNamespaceURI = NAMESPACE_URI;
    }

    /* (non-Javadoc)
     * @see org.apache.cocoon.transformation.AbstractSAXTransformer#setupTransforming()
     */
    public void setupTransforming()
    throws IOException, ProcessingException, SAXException {
        super.setupTransforming();
        this.insideLinks = false;
        this.content = null;
        this.collectedEvents.clear();
    }

    /**
     * Overridden from superclass.
     */
    public void startTransformingElement(String uri, String name, String raw, Attributes attr)
    throws ProcessingException, IOException, SAXException {
        if (name.equals(COPLET_ELEM)) {
            String expression = attr.getValue(SELECT_ATTR);
            if (expression == null) {
                throw new ProcessingException("Attribute "+SELECT_ATTR+" must be spcified.");
            }

            final CopletInstanceData cid = this.getCopletInstanceData();

            final JXPathContext jxpathContext = JXPathContext.newContext( cid );
            final Object object = jxpathContext.getValue(expression);

            if (object != null) {
                XMLUtils.valueOf(contentHandler, object);
            }

        } else if (name.equals(LINK_ELEM)) {

            final LinkService linkService = this.portalService.getComponentManager().getLinkService();
            final String format = attr.getValue("format");
            AttributesImpl newAttrs = new AttributesImpl();
            newAttrs.setAttributes(attr);
            newAttrs.removeAttribute("format");

            if ( attr.getValue("href") != null ) {
                final CopletInstanceData cid = this.getCopletInstanceData();
                ChangeCopletInstanceAspectDataEvent event = new ChangeCopletInstanceAspectDataEvent(cid, null, null);

                String value = linkService.getLinkURI(event);
                if (value.indexOf('?') == -1) {
                    value = value + '?' + attr.getValue("href");
                } else {
                    value = value + '&' + attr.getValue("href");
                }
                newAttrs.removeAttribute("href");
                this.output(value, format, newAttrs );
            } else {
                final String path = attr.getValue("path");
                final String value = attr.getValue("value");

                newAttrs.removeAttribute("path");
                newAttrs.removeAttribute("value");

                JXPathEvent event = null;
                if ( attr.getValue("layout") != null ) {
                    newAttrs.removeAttribute("layout");
                    final String layoutId = attr.getValue("layout");
                    Object layout = this.portalService.getComponentManager().getProfileManager().getPortalLayout(null, layoutId);
                    if ( layout != null ) {
                        event = new JXPathEvent(layout, path, value);
                    }
                } else {
                    String copletId = attr.getValue("coplet");
                    newAttrs.removeAttribute("coplet");
                    final CopletInstanceData cid = this.getCopletInstanceData(copletId);
                    if ( cid != null ) {
                        event = new CopletJXPathEvent(cid, path, value);
                    }
                }
                if ( this.insideLinks ) {
                    if ( event != null ) {
                        this.collectedEvents.add(event);
                    }
                } else {
                    final String href = linkService.getLinkURI(event);
                    this.output(href, format, newAttrs );
                }
            }
        } else if (name.equals(PARAMETER_ELEM)) {
            if (this.insideLinks) {
                String href = attr.getValue("href");
                if ( href != null ) {
                    final int pos = href.indexOf('?');
                    if ( pos != -1 ) {
                        href = href.substring(pos+1);
                    }
                    this.collectedEvents.add(new LinkService.ParameterDescription(href));
                }
            }
        } else if (name.equals(LINKS_ELEM) ) {
            this.insideLinks = true;
            final AttributesImpl newAttrs = new AttributesImpl();
            newAttrs.setAttributes(attr);
            newAttrs.removeAttribute("format");
            this.stack.push(newAttrs);

            String format = attr.getValue("format");
            if ( format == null ) {
                format = "html-link";
            }
            this.stack.push(format);
        } else if ( name.equals(CONTENT_ELEM) && this.insideLinks ) {
            this.startSAXRecording();
        } else {
            super.startTransformingElement(uri, name, raw, attr);
        }
    }

    /**
     * Overridden from superclass.
     */
    public void endTransformingElement(String uri, String name, String raw)
    throws ProcessingException, IOException, SAXException {
        if ( name.equals(LINK_ELEM) ) {
            if ( !this.insideLinks ) {
                String elem = (String)this.stack.pop();
                if ( elem.length() > 0 ) {
                    this.sendEndElementEvent(elem);
                }
            }
        } else if ( name.equals(LINKS_ELEM) ) {
            this.insideLinks = false;
            final String format = (String)this.stack.pop();
            final LinkService linkService = this.portalService.getComponentManager().getLinkService();
            String href = linkService.getLinkURI(this.collectedEvents);

            AttributesImpl newAttrs = (AttributesImpl)this.stack.pop();
            // test for alternate base url
            final String baseURL = newAttrs.getValue("base-url");
            if ( baseURL != null ) {
                newAttrs.removeAttribute("base-url");
                int pos = href.indexOf('?') + 1;
                final char separator;
                if ( baseURL.indexOf('?') == -1 ) {
                    separator = '?';
                } else {
                    separator = '&';
                }
                href = baseURL + separator + href.substring(pos);

            }
            this.output(href, format, newAttrs );

            this.collectedEvents.clear();
            if ( this.content != null ) {
                this.content.toSAX(this.contentHandler);
                this.content = null;
            }
            String elem = (String)this.stack.pop();
            if ( elem.length() > 0 ) {
                this.sendEndElementEvent(elem);
            }
        } else if ( name.equals(CONTENT_ELEM) && this.insideLinks ) {
            this.content = this.endSAXRecording();
        } else if (!name.equals(COPLET_ELEM) && !name.equals(PARAMETER_ELEM)) {
            super.endTransformingElement(uri, name, raw);
        }
    }

    /**
     * Output the link
     */
    protected void output(String uri, String format, AttributesImpl newAttrs)
    throws SAXException {
        if ( format == null ) {
            // default
            format = "html-link";
        }

        if ( "html-link".equals(format) ) {
            newAttrs.addCDATAAttribute("href", uri);
            this.sendStartElementEvent("a", newAttrs);
            this.stack.push("a");

        } else if ( "html-form".equals(format) ) {
            boolean addParametersAsHiddenFields = false;
            String parameters = null;
            final String enctype = newAttrs.getValue("enctype");
            if ( enctype== null
                || "application/x-www-form-urlencoded".equalsIgnoreCase(enctype)
                || "multipart/form-data".equalsIgnoreCase(enctype) )  {
                final int pos = uri.indexOf('?');
                if ( pos != -1 ) {
                    parameters = uri.substring(pos+1);
                    uri = uri.substring(0, pos);
                    addParametersAsHiddenFields = true;
                }
            }
            newAttrs.addCDATAAttribute("action", uri);
            this.sendStartElementEvent("form", newAttrs);
            this.stack.push("form");
            if ( addParametersAsHiddenFields ) {
                // create hidden input fields
                RequestParameters pars = new RequestParameters(parameters);
                Enumeration enumeration = pars.getParameterNames();
                while ( enumeration.hasMoreElements() ) {
                    final String pName = (String)enumeration.nextElement();
                    final String[] pValues = pars.getParameterValues(pName);
                    for(int k=0; k<pValues.length; k++) {
                        final String pValue = pValues[k];
                        AttributesImpl hiddenAttrs = new AttributesImpl();
                        hiddenAttrs.addCDATAAttribute("type", "hidden");
                        hiddenAttrs.addCDATAAttribute("name", pName);
                        hiddenAttrs.addCDATAAttribute("value", pValue);
                        this.startElement("", "input", "input", hiddenAttrs);
                        this.endElement("", "input", "input");
                    }
                }

            }
        } else if ( "text".equals(format) ) {
            this.sendTextEvent(uri);
            this.stack.push("");
        } else if ( "parameters".equals(format) ) {
            final String value = uri.substring(uri.indexOf('?')+1);
            this.sendTextEvent(value);
            this.stack.push("");
        } else {
            // own format
            newAttrs.addCDATAAttribute("href", uri);
            this.sendStartElementEvent("link", newAttrs);
            this.stack.push("link");
        }
    }
}
TOP

Related Classes of org.apache.cocoon.portal.transformation.CopletTransformer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.