Package org.apache.cocoon.portal.transformation

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

/*
* 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 org.apache.cocoon.portal.coplet.CopletInstanceData;
import org.apache.cocoon.portal.event.impl.CopletLinkEvent;
import org.apache.cocoon.xml.AttributesImpl;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

/**
* This transformer is used to replace links (URIs) from elements
* like <a href="URI"> or <form action="URI"> with portal
* event uris. Therefore the transformer searches for <eventlink>
* elements replaces the URI form the attribute which is specified within
* an attribute called "attribute" and renames the element as specified
* within an attribute called "element".
*
* Example:<br><br>
*
* <pre>
* &lt;root xmlns:ev="http://apache.org/cocoon/portal/eventlink/1.0"&gt;
*   &lt;ev:eventlink href="http://eventlinkexample" element="a" attribute="href"&gt;linktext&lt;/ev:eventlink&gt;
* &lt;/root&gt;<br></pre>
*
* will be replaced with something like:<br><br>
*
* <pre>
* &lt;root&gt;
*   &lt;a href="portal?cocoon-portal-event=8"&gt;linktext&lt;/a&gt;
* &lt;/root&gt;<br></pre>
*
* The transformer will create two CopletLinkEvents and insert corresponding links
* to them to the XML instead of "http://eventlinkexample". If such a link is pressed
* the corresponding CopletLinkEvent is sent to the Subscribers to be handled.<br>
* Please see also the documentation of superclass AbstractCopletTransformer for how
* the coplet instance data are acquired.
*
* @author <a href="mailto:gernot.koller@rizit.at">Gernot Koller</a>
*
* @version CVS $Id: NewEventLinkTransformer.java 344185 2005-11-14 19:40:03Z cziegeler $
*/
public class NewEventLinkTransformer extends AbstractCopletTransformer {

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

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

    /**
     * An attribute's name of EVENT_ELEMENT.
     */
    public static final String ATTRIBUTE_ATTR = "attribute";

    /**
     * An attribute's name of EVENT_ELEMENT.
     */
    public static final String ELEMENT_ATTR = "element";

    /**
     * @see java.lang.Object#Object()
     */
    public NewEventLinkTransformer() {
        this.defaultNamespaceURI = NAMESPACE_URI;
    }

    /**
     * @throws SAXException when the eventlink element does not contain the necessary attributes
     *       "element" and "attribute", retrieving the LinkURI from the LinkService fails,
     *          or an unknown element within the namespaces in encountered.
     * @see org.apache.cocoon.transformation.AbstractSAXTransformer#startTransformingElement(String, String, String, Attributes)
     */
    public void startTransformingElement(String uri,
                                         String name,
                                         String raw,
                                         Attributes attributes)
    throws SAXException {
        if (!EVENT_ELEM.equals(name)) {
            throw new SAXException("Unknown element encountered: " + name);
        }

        String attributeName = attributes.getValue(ATTRIBUTE_ATTR);
        String elementName = attributes.getValue(ELEMENT_ATTR);

        if (attributeName == null) {
            throw new SAXException(
                "Element "
                    + EVENT_ELEM
                    + " must have an attribute "
                    + ATTRIBUTE_ATTR
                    + ".");
        }

        if (elementName == null) {
            throw new SAXException(
                "Element "
                    + EVENT_ELEM
                    + " must have an attribute "
                    + ELEMENT_ATTR
                    + ".");
        }

        // remove ATTRIBUTE_ATTR, "coplet" and ELEMENT_ATTR from attributes
        AttributesImpl newAttributes = this.getMutableAttributes(attributes);
        newAttributes.removeAttribute(ELEMENT_ATTR);
        newAttributes.removeAttribute(ATTRIBUTE_ATTR);
        newAttributes.removeAttribute("coplet");

        int index = newAttributes.getIndex(attributeName);
        String link = newAttributes.getValue(index);

        boolean formSpecialTreatment = false;
        if ("form".equals(elementName)) {
            //cut all query parameters from actions with method get, as these will be normaly ignored!
            formSpecialTreatment = true;
            if ("GET".equalsIgnoreCase(newAttributes.getValue("method"))
                && link.indexOf('?') > 0) {
                link = link.substring(0, link.indexOf('?'));
            }
        }

        String portalAction = null;
        String portalEvent = null;

        // if attribute found that contains a link
        if (link != null) {
            CopletInstanceData cid = this.getCopletInstanceData(attributes.getValue("coplet"));
            // create event link
            CopletLinkEvent event = new CopletLinkEvent(cid, link);
            String eventLink = this.portalService.getComponentManager().getLinkService().getLinkURI(event);

            //form elements need hidden inputs to change request parameters
            if (formSpecialTreatment) {
                int begin =
                    eventLink.indexOf("cocoon-portal-action=")
                        + "cocoon-portal-action=".length();
                int end = eventLink.indexOf('&', begin);
                if (end == -1) {
                    end = eventLink.length();
                }

                portalAction = eventLink.substring(begin, end);

                begin =
                    eventLink.indexOf("cocoon-portal-event=")
                        + "cocoon-portal-event=".length();
                end = eventLink.indexOf('&', begin);
                if (end == -1) {
                    end = eventLink.length();
                }
                portalEvent = eventLink.substring(begin, end);

                eventLink =
                    eventLink.substring(0, eventLink.indexOf('?'));
            }

            // insert event link
            newAttributes.setValue(index, eventLink);
        }

        this.stack.push(elementName);

        contentHandler.startElement(
            "",
            elementName,
            elementName,
            newAttributes);

        //generate hidden inputs to add request parameters to the form action
        if (formSpecialTreatment) {
            sendHiddenFields(contentHandler, portalAction, portalEvent);
        }
    }

    /**
     * With forms the uri in the action attribute cannot be enhanced with request parameters.
     * Instead hidden input fields must be inserted into the SAX stream to add request parameters.
     * This method sends two hidden inputs adding the "cocoon-portal-action" parameter and
     * the "cocoon-portal-event" parameter.
     * @param contentHandler the content handler recieving the SAX events
     * @param portalAction value of the "cocoon-portal-action" parameter
     * @param portalEvent value of the "cocoon-portal-event" parameter
     * @throws SAXException if sending the SAX events failed
     */
    private void sendHiddenFields(ContentHandler contentHandler,
                                  String portalAction,
                                  String portalEvent)
    throws SAXException {
        AttributesImpl attributes = new AttributesImpl();
        attributes.addAttribute("", "type", "type", "CDATA", "hidden");
        attributes.addAttribute(
            "",
            "name",
            "name",
            "CDATA",
            "cocoon-portal-action");
        attributes.addAttribute("", "value", "value", "CDATA", portalAction);
        contentHandler.startElement("", "input", "input", attributes);
        contentHandler.endElement("", "input", "input");

        attributes = new AttributesImpl();
        attributes.addAttribute("", "type", "type", "CDATA", "hidden");
        attributes.addAttribute(
            "",
            "name",
            "name",
            "CDATA",
            "cocoon-portal-event");
        attributes.addAttribute("", "value", "value", "CDATA", portalEvent);
        contentHandler.startElement("", "input", "input", attributes);
        contentHandler.endElement("", "input", "input");
    }

    /**
     * @see org.apache.cocoon.transformation.AbstractSAXTransformer#endTransformingElement(String, String, String)
     */
    public void endTransformingElement(String uri, String name, String raw)
    throws SAXException {
        String elementName = (String) this.stack.pop();
        contentHandler.endElement("", elementName, elementName);
    }
}
TOP

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

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.