You are viewing a plain text version of this content. The canonical link for it is here.
Posted to svn@forrest.apache.org by th...@apache.org on 2009/12/02 14:58:28 UTC
svn commit: r886147 [6/6] - in /forrest/trunk/whiteboard: ./ FOR-1157/
cocoon-2.2-blocks/dispatcher/ dispatcher/
plugins/org.apache.forrest.plugin.internal.dispatcher/
plugins/org.apache.forrest.plugin.internal.dispatcher/lib/
plugins/org.apache.forres...
Modified: forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java
URL: http://svn.apache.org/viewvc/forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java?rev=886147&r1=886146&r2=886147&view=diff
==============================================================================
--- forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java (original)
+++ forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java Wed Dec 2 13:58:18 2009
@@ -16,982 +16,995 @@
*/
package org.apache.forrest.dispatcher.transformation;
+import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.io.Serializable;
+import java.io.StringReader;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Transformer;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.URIResolver;
-import javax.xml.transform.dom.DOMResult;
-import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.axiom.attachments.utils.IOUtils;
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMException;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.caching.CacheableProcessingComponent;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.transformation.AbstractSAXTransformer;
-import org.apache.cocoon.xml.IncludeXMLConsumer;
+import org.apache.cocoon.util.TraxErrorHandler;
+import org.apache.cocoon.xml.RedundantNamespacesFilter;
import org.apache.cocoon.xml.XMLUtils;
-import org.apache.cocoon.xml.dom.DOMBuilder;
-import org.apache.cocoon.xml.dom.DOMUtil;
+import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceException;
-import org.apache.excalibur.source.SourceNotFoundException;
import org.apache.excalibur.source.SourceValidity;
-import org.apache.excalibur.source.impl.validity.AggregatedValidity;
-import org.apache.excalibur.xml.xpath.XPathProcessor;
-import org.apache.forrest.dispatcher.ContractBean;
-import org.apache.forrest.dispatcher.ContractBeanDOMImpl;
-import org.apache.forrest.dispatcher.DispatcherException;
-import org.apache.forrest.dispatcher.DispatcherHelper;
-import org.apache.forrest.dispatcher.lenya.xml.DocumentHelper;
-import org.apache.forrest.dispatcher.lenya.xml.NamespaceHelper;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
+import org.apache.excalibur.xml.sax.SAXParser;
+import org.apache.forrest.dispatcher.api.Contract;
+import org.apache.forrest.dispatcher.api.Resolver;
+import org.apache.forrest.dispatcher.config.WritableDispatcherBean;
+import org.apache.forrest.dispatcher.exception.ContractException;
+import org.apache.forrest.dispatcher.exception.DispatcherException;
+import org.apache.forrest.dispatcher.factories.ContractFactory;
+import org.apache.forrest.dispatcher.impl.CocoonResolver;
+import org.apache.forrest.dispatcher.impl.helper.AXIOMXPathCreate;
+import org.apache.forrest.dispatcher.impl.helper.Captions;
+import org.apache.forrest.dispatcher.impl.helper.StAX;
+import org.apache.forrest.dispatcher.impl.helper.StreamHelper;
+import org.apache.forrest.dispatcher.impl.helper.XMLProperties;
+import org.jaxen.JaxenException;
import org.xml.sax.Attributes;
+import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
-import org.xml.sax.helpers.AttributesImpl;
+/**
+ * A cocoon transformer class for the dispatcher.
+ *
+ * Unlike the wrapper this class will do the actual work and only reuse the
+ * contract handling from the core. This class is nearly the same as we had
+ * before just switching DOM for StAX/AXIOM.
+ *
+ * @version 1.0
+ *
+ */
public class DispatcherTransformer extends AbstractSAXTransformer implements
Disposable, CacheableProcessingComponent, URIResolver {
- /* Node and attribute names */
- /**
- * <code>forrest:view</code> element is used to structure contracts and
- * hooks into format specific container. It allows to configure x different
- * format for the request.
- *
- * <pre>
- * <<strong>forrest:view</strong> format="html"/>
- * </pre>
- */
- public static final String STRUCTURER_ELEMENT = "view";
+ private static final String PATH_PREFIX = "result";
/**
- * <code>forrest:view</code> element is used to structure contracts and
- * hooks into format specific container. It allows to configure x different
- * format for the request. The attribute which identify a view format is
- * <strong>format</strong>.
- *
- * <pre>
- * <forrest:view <strong>format</strong>="html"/>
- * </pre>
+ * The requested format.
+ * <p>
+ * Used to identify the structure to process
*/
- public static final String STRUCTURER_FORMAT_ATTRIBUTE = "type";
-
- public static final String STRUCTURER_HOOK_XPATH_ATTRIBUTE = "hooksXpath";
-
- protected String requestedFormat;
-
- private boolean includeNodes = true;
+ private String requestedFormat;
/**
- * <code>forrest:hook</code> element is used to structure the elements. It
- * allows to create skeletons that a designer needs to apply a specific layout
- * via e.g. css. In html for example
- *
- * <pre>
- * <forrest:hook name="test"/>
- * </pre>
- *
+ * The requested id.
* <p>
- * will be transformed to
- * </p>
- *
- * <pre>
- * <div id="test"/>
- * </pre>
+ * Used to request the corresponding properties file for the request
*/
- public static final String DISPATCHER_HOOK_ELEMENT = "hook";
+ private String requestId;
/**
- * <code>forrest:css</code> element is used to apply a specific layout via
- * css. In html for example
- *
- * <pre>
- * <forrest:css url="pelt.basic.css" media="screen" theme="Pelt"/>
- * </pre>
- *
- * <p>
- * will be transformed to
- * </p>
- *
- * <pre>
- * <link media="screen" href="../themes/pelt.basic.css" title="Pelt" rel="stylesheet" type="text/css" />
- * </pre>
+ * Caching and validity properties
*/
- public static final String DISPATCHER_CSS_ELEMENT = "css";
+ private String cacheKey, validityFile;
- private String propertyID;
+ private SourceValidity validity;
- private boolean insideProperties = false;
+ private String validityChecking;
/**
- * Convenience object, so we don't need to create an AttributesImpl for every
- * element.
+ * Resolver which will be used for uri resolving
*/
- protected AttributesImpl attributes;
-
- protected String currentFormat;
- protected ContractBean contract;
+ private org.apache.excalibur.source.SourceResolver m_resolver;
/**
- * The namespace used by the transformer for the SAX events filtering. This
- * either equals to the {@link #defaultNamespaceURI} or to the value set by
- * the <code>namespaceURI</code> sitemap parameter for the pipeline. Must
- * never be null.
+ * The caption for the cache parameter
*/
- protected String namespaceURI;
+ public static final String CACHE_PARAMETER = "cacheKey";
/**
- * This is the default namespace used by the transformer. Implementations
- * should set its value in the constructor. Must never be null.
+ * The caption for the validity parameter
*/
- protected String defaultNamespaceURI;
-
- private DOMBuilder builder, dispatcherBuilder;
-
- private Transformer structurerTransformer;
-
- private Element rootNode;
-
- private XPathProcessor processor;
-
- private Document document;
-
- private NamespaceHelper dispatcher;
-
- private Map storedPrefixMap;
-
- private String path = null;
-
- private boolean recording, allowMarkup;
-
- public static final String DISPATCHER_ALLOW_MARKUP = "allowMarkup";
-
- private DispatcherHelper dispatcherHelper;
-
- private boolean insideStructurer = false;
-
- private String hooksXSL, cacheKey, validityFile;
-
- private HashMap hooksPosition;
-
- private HashMap parameterHelper;
-
- private org.apache.excalibur.source.SourceResolver m_resolver;
-
- private String requestId;
-
- private Document defaultProperties;
-
- private AggregatedValidity validity;
-
- private String validityOverride;
+ public static final String VALIDITY_PARAMETER = "validityFile";
- public static final String HOOKS_TRANSFORMER_PARAMETER = "hooksTransformer";
+ /**
+ * The caption for the validity override parameter
+ */
+ public static final String VALIDITY_OVERRIDE_PARAMETER = "dispatcher.caching";
- public static final String PATH_PARAMETER = "path";
+ /**
+ * The caption for the condition that caching is turned off
+ */
+ public static final String CACHING_OFF = "off";
- static public final String DISPATCHER_REQUEST_ATTRIBUTE = "request";
+ /**
+ * The caption for the condition that caching is turned on
+ */
+ public static final String CACHING_ON = "on";
- public static final String CACHE_PARAMETER = "cacheKey";
+ /**
+ * Main configuration bean of the dispatcher.
+ * <p>
+ * This config will control things like
+ * <li>contract prefixes/suffixes
+ * <li>
+ * resolver to use
+ */
+ private WritableDispatcherBean config;
- public static final String VALIDITY_PARAMETER = "validityFile";
+ /**
+ * Cocoon 2.2 compatible method. Allow that the ServiceManager is be set via
+ * e.g. spring
+ *
+ * @param manager
+ * manger to use in the context
+ */
+ public void setManager(ServiceManager manager) {
+ this.manager = manager;
+ }
- private static final String VALIDITY_OVERRIDE_PARAMETER = "dispatcher.caching";
+ /**
+ * The level of xpath support we need.
+ * <p>
+ * If you choose enhanced you can inject/create node with enhanced xpath
+ * expression like e.g. /root/child[id='test']
+ * <p>
+ * Supported values are: basic | enhanced
+ */
+ private String xpathSupport;
- private static final String CACHING_OFF = "off";
+ /**
+ * @param xpathSupport
+ * the xpathSupport to set
+ */
+ public synchronized void setXpathSupport(String xpathSupport) {
+ this.xpathSupport = xpathSupport;
+ }
- private static final String CACHING_ON = "on";
+ /**
+ * The prefix that we need to use to resolve a concrete contract.
+ */
+ private String contractUriPrefix;
/**
- * Constructor Set the namespace
+ * The parameter caption use to pass the requestId from the sitemap to the
+ * contract
*/
- public DispatcherTransformer() {
- this.defaultNamespaceURI = DispatcherHelper.DISPATCHER_NAMESPACE_URI;
- }
+ public static final String DISPATCHER_REQUEST_ATTRIBUTE = "request";
/**
- * Generate the unique key. This key must be unique inside the space of this
- * component.
- *
- * @return The generated key hashes the src
+ * The caption of the key for the default variables
*/
- public Serializable getKey() {
- return this.cacheKey;
- }
+ private static final String DEFAULT_VARIABLES = "defaultVariables";
/**
- * Generate the validity object.
- *
- * @return The generated validity object or <code>null</code> if the
- * component is currently not cacheable.
+ * preparing the parser that will pick up the result and pass it to the
+ * consumer again.
*/
- public SourceValidity getValidity() {
- // You can either request URL?dispatcher.caching=off
- // or add this property to forrest.properties.xml
- // to force a SourceValidity.INVALID
- if (null != validityFile && !(validityOverride.equals(CACHING_OFF))) {
- this.validity = new AggregatedValidity();
- Source resolveSource=null;
- try {
- resolveSource= m_resolver.resolveURI(validityFile);
- this.validity.add(resolveSource.getValidity());
- } catch (Exception e) {
- getLogger().error(e.getMessage());
- }finally{
- release(resolveSource);
- }
- } else
- this.validity = null;
- return this.validity;
- }
+ private SAXParser parser = null;
+ private OMFactory factory;
+ private ContractFactory contractRep;
+ /*
+ * Housekeeping variables to indicate the state of processing. Remember SAX is
+ * a stream.
+ */
/**
- * @see org.apache.excalibur.source.SourceFactory#release(org.apache.excalibur.source.Source)
+ * whether or not we need to process the properties
*/
- public void release(Source source) {
- if(source!=null){
- m_resolver.release(source);
- }
- }
-
+ private boolean insideProperties = false;
/**
- * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ * whether or not we need are in the requested structurer
*/
- public void service(ServiceManager manager) throws ServiceException {
- super.service(manager);
+ private boolean includeNodes = true;
+ private OMElement root;
+
+ private OMElement pathNode;
+
+ private Resolver resolverDispatcher;
+
+ private Contract contract;
+
+ private HashMap<String, Object> map;
+
+ private HashMap<String, Object> localParams;
+
+ private String currentProperty;
+
+ private InputStream dataStream;
+
+ private String prefixString;
+
+ private TransformerFactory tfactory = TransformerFactory.newInstance();
+
+ private EntityResolver entityResolver;
+
+ private boolean multipleRoot;
+
+ /*
+ * @see
+ * org.apache.cocoon.transformation.AbstractSAXTransformer#configure(org.apache
+ * .avalon.framework.configuration.Configuration)
+ */
+ public void configure(Configuration configuration)
+ throws ConfigurationException {
+ // creating a new config and store the general not request specific
+ // parameters here
+ config = new WritableDispatcherBean();
+ config.setStaxHelper(new StAX());
+ // are we allowing xml properties?
+ boolean allowXml = configuration.getChild("allowXml").getValueAsBoolean(
+ false);
+ config.setAllowXmlProperties(allowXml);
+ // set the prefix for the contract resolving
+ contractUriPrefix = configuration.getChild("contractUriPrefix").getValue(
+ "cocoon://resolve.contract.");
+ // set the suffix for the contract
+ config.setContractUriSufix(configuration.getChild("contractUriSufix")
+ .getValue(""));
+ // what level of xpath support do we want to allow?
+ xpathSupport = configuration.getChild("xpathSupport").getValue("basic");
+ // Do we want to shrink xml properties that have only a @value?
+ boolean shrink = configuration.getChild("shrink").getValueAsBoolean(true);
+ config.setShrink(shrink);
+ config.setEntityResolver(this.entityResolver);
+ // request all factories to be created at this point since it is better to
+ // create them only once
+ try {
+ setNewTransformerFactory();
+ } catch (ProcessingException e) {
+ throw new ConfigurationException(e.getLocalizedMessage(), e);
+ } catch (TransformerFactoryConfigurationError e) {
+ throw new ConfigurationException(e.getLocalizedMessage(), e);
+ }
}
/**
- * @see org.apache.avalon.framework.activity.Disposable#dispose()
+ * Cocoon 2.2 compatible method. Allow that the WritableDispatcherBean is be
+ * set via e.g. spring
+ *
+ * @param config
+ * the configuration to use.
+ * @throws TransformerFactoryConfigurationError
+ * @throws ProcessingException
*/
- public void dispose() {
- if (null != this.manager) {
- if (null!=m_resolver)
- this.manager.release(m_resolver);
- this.manager = null;
+ public void setConfig(WritableDispatcherBean config)
+ throws ProcessingException, TransformerFactoryConfigurationError {
+ this.config = config;
+ if (config.getTransFact() == null) {
+ setNewTransformerFactory();
}
- m_resolver = null;
- insideProperties = false;
- super.dispose();
+ contractUriPrefix = config.getContractUriPrefix();
}
/**
- * Recycle the component
+ * Will prepare the factories that we need in further processing
+ *
+ * @throws TransformerFactoryConfigurationError
+ * @throws ProcessingException
*/
- public void recycle() {
- localRecycle();
- this.validity = null;
- super.recycle();
-
+ private void setNewTransformerFactory()
+ throws TransformerFactoryConfigurationError, ProcessingException {
+ // set the uri resolver the same as this class
+ tfactory.setURIResolver(this);
+ // we want to set the error handler here to make sure it is intitialized
+ tfactory.setErrorListener(new TraxErrorHandler(getLogger()));
+ // add the factory to the config
+ config.setTransFact(tfactory);
+ // get the OM factory
+ this.factory = OMAbstractFactory.getOMFactory();
+ // get the contract factory
+ this.contractRep = new ContractFactory(config);
+ try {
+ parser = (SAXParser) manager.lookup(SAXParser.ROLE);
+ } catch (ServiceException e) {
+ String error = "dispatcherError:\n"
+ + "SAXParser could not be setup! Abort";
+ getLogger().error(error);
+ throw new ProcessingException(error);
+ }
}
- // we do all the heavy stuff later and only prepare the basics here,
- // this enhance the response time while caching.
+ /*
+ * @see
+ * org.apache.cocoon.transformation.AbstractSAXTransformer#setup(org.apache
+ * .cocoon.environment.SourceResolver, java.util.Map, java.lang.String,
+ * org.apache.avalon.framework.parameters.Parameters)
+ */
public void setup(SourceResolver resolver, Map objectModel, String src,
Parameters par) throws ProcessingException, SAXException, IOException {
+ /*
+ * we do all the heavy stuff later and only prepare the basics here, this
+ * enhance the response time while caching.
+ */
+ // setup our super class
super.setup(resolver, objectModel, src, par);
-
- storedPrefixMap = new HashMap();
- this.parameterHelper = new HashMap();
-
- this.hooksPosition = new HashMap();
-
- this.allowMarkup = Boolean.getBoolean(parameters.getParameter(
- DISPATCHER_ALLOW_MARKUP, null));
- this.requestId = parameters.getParameter(DISPATCHER_REQUEST_ATTRIBUTE, null);
+
+ // get the id of this request
+ this.requestId = parameters
+ .getParameter(DISPATCHER_REQUEST_ATTRIBUTE, null);
+ // get the external cache key
this.cacheKey = parameters.getParameter(CACHE_PARAMETER, null);
if (null == this.cacheKey)
getLogger().warn(
"Caching not activated! Declare the CACHE_KEY_PARAMETER="
+ CACHE_PARAMETER + " in your sitemap.");
+ /*
+ * which is the file use to watch for changes (normally the structurer of
+ * the request). As long the file does not change we are using the cache
+ * object.
+ */
this.validityFile = parameters.getParameter(VALIDITY_PARAMETER, null);
- this.validityOverride = parameters
- .getParameter(VALIDITY_OVERRIDE_PARAMETER, "");
- this.cacheKey += validityOverride;
-
+ // do we want to force that is caching is turned off?
+ this.validityChecking = parameters.getParameter(
+ VALIDITY_OVERRIDE_PARAMETER, "");
if (requestId == null) {
String error = "dispatcherError:\n"
+ "You have to set the \"request\" parameter in the sitemap!";
getLogger().error(error);
throw new ProcessingException(error);
}
-
- parameterHelper.put(DISPATCHER_REQUEST_ATTRIBUTE, requestId);
- this.requestedFormat = parameters.getParameter(STRUCTURER_FORMAT_ATTRIBUTE,
- null);
+ // which format we want to process?
+ this.requestedFormat = parameters.getParameter(Captions.TYPE_ATT, null);
+ /*
+ * We need to change now the contract uri prefixes since in cocoon we need
+ * to add the current format.
+ */
+ String loacalPrefix = contractUriPrefix + requestedFormat + ".";
+ config.setContractUriPrefix(loacalPrefix);
if (requestedFormat == null) {
String error = "dispatcherError:\n"
+ "You have to set the \"type\" parameter in the sitemap!";
getLogger().error(error);
throw new ProcessingException(error);
}
- parameterHelper.put(STRUCTURER_FORMAT_ATTRIBUTE, requestedFormat);
-
- this.hooksXSL = parameters.getParameter(HOOKS_TRANSFORMER_PARAMETER, null);
- parameterHelper.put(HOOKS_TRANSFORMER_PARAMETER, hooksXSL);
- if (null == m_resolver)
+ multipleRoot = parameters.getParameterAsBoolean("multipleRoot", false);
+ // add the format to the cache key
+ this.cacheKey += requestedFormat;
+ if (null == m_resolver) {
try {
- m_resolver = (org.apache.excalibur.source.SourceResolver) manager.lookup(SourceResolver.ROLE);
+ m_resolver = (org.apache.excalibur.source.SourceResolver) manager
+ .lookup(SourceResolver.ROLE);
+ // add the resolver we use to the dispatcher
+ resolverDispatcher = new CocoonResolver(m_resolver);
+ config.setResolver(resolverDispatcher);
} catch (ServiceException e) {
throw new ProcessingException(e);
}
-
+ }
}
- /**
- * Cleanup the transformer
+ /*
+ * old transformer link @see
+ * http://svn.apache.org/viewvc?view=rev&revision=694101
+ *
+ * @see
+ * org.apache.cocoon.transformation.AbstractSAXTransformer#startElement(String
+ * uri, String name, String raw, Attributes attr)
*/
- private void localRecycle() {
- this.contract = null;
- this.structurerTransformer = null;
- this.insideProperties = false;
- }
-
public void startElement(String uri, String name, String raw, Attributes attr)
throws SAXException {
// Process start element event
// Are we inside of properties? If so we need to record the elements.
if (this.insideProperties && this.includeNodes) {
+ // just start the recording
+ super.startElement(uri, name, raw, attr);
+ // startSerializedXMLRecording(null);
+ } else if (Captions.NS.equals(uri)) {
+ // we are in the dispatcher ns
try {
- this.builder.startElement(uri, name, raw, attr);
- } catch (SAXException e) {
- this.insideProperties = false;
- String error = "dispatcherError: " + DispatcherException.ERROR_500 + "\n"
- + "The contract \"" + contract.getContractName()
- + "\" has thrown in the property with ID \"" + this.propertyID
- + "\" an error.\n\n DispatcherStack:\n " + e;
- getLogger().error(error);
- throw new SAXException(error);
- }
- } else if (DispatcherHelper.DISPATCHER_NAMESPACE_URI.equals(uri)) {
- /*
- * We are in the dispatcher ns.
- */
- if (getLogger().isDebugEnabled()) {
+ // We are in the dispatcher ns.
getLogger().debug("Starting dispatcher element: " + raw);
- }
- if (STRUCTURER_ELEMENT.equals(name))
- structurerProcessingStart(attr);
- else if (DISPATCHER_HOOK_ELEMENT.equals(name) && this.includeNodes)
- hookProcessingStart(name, raw, attr);
- else if (ContractBean.CONTRACT_ELEMENT.equals(name) && this.includeNodes)
- contractProcessingStart(attr);
- else if (ContractBean.PROPERTY_ELEMENT.equals(name) && this.includeNodes) {
- this.insideProperties = true;
- propertyProcessingStart(uri, name, raw, attr);
+ if (Captions.STRUCTURE_ELEMENT.equals(name)) {
+ // we are in a structurer definition
+ structurerProcessingStart(attr);
+ }
+ if (this.includeNodes) {
+ if (Captions.HOOK_ELEMENT.equals(name)) {
+ // we are inside a hook element
+ hookProcessingStart(name, raw, attr);
+ } else if (Captions.CONTRACT_ELEMENT.equals(name)) {
+ // we are inside a contract element
+ contractProcessingStart(attr);
+ } else if (Captions.PROPERTY_ELEMENT.equals(name)) {
+ // we are inside a property element
+ // this.insideProperties = true;
+ propertyProcessingStart(uri, name, raw, attr);
+ }
+ }
+ } catch (Exception e) {
+ throw new SAXException(e);
}
} else {
- if (!this.insideProperties && this.includeNodes && this.insideStructurer
- && this.allowMarkup)
- super.startElement(uri, name, raw, attr);
- if (!this.insideProperties && this.includeNodes && !this.insideStructurer)
- super.startElement(uri, name, raw, attr);
+ // Do we want to allow to have structurer definitions as nested elements?
+ if (!this.insideProperties && this.includeNodes) {
+ // super.startElement(uri, name, raw, attr);
+ }
}
+
}
- /**
- * @param name
- * @param raw
- * @param attr
- * @throws DOMException
- * @throws SAXException
+ /*
+ * @see
+ * org.apache.cocoon.transformation.AbstractSAXTransformer#endElement(java
+ * .lang.String, java.lang.String, java.lang.String)
*/
- private void hookProcessingStart(String name, String raw, Attributes attr)
- throws DOMException, SAXException {
- /* create a DOM node from the current sax event */
- Element currentElement = dispatcher.getDocument().createElement(name);
- dispatcherHelper.setAttributesDOM(attr, currentElement);
- String tempPathWithoutAttr = path + "/" + name;
- String tempPath = dispatcherHelper
- .setAttributesXPath(attr, tempPathWithoutAttr);
- // If the hook has already been met, we use the position in the XPath to
- // avoid confusion ...
- if (hooksPosition.containsKey(tempPath)) {
- int pos = ((Integer) hooksPosition.get(tempPath)).intValue() + 1;
- hooksPosition.put(tempPath, new Integer(pos));
- tempPath = dispatcherHelper.setAttributesXPathWithPosition(attr,
- tempPathWithoutAttr, pos);
- } else {
- hooksPosition.put(tempPath, new Integer(1));
- }
- if (path == null || path.equals("")) {
- path = name;
- this.rootNode.appendChild(currentElement);
- } else {
- /* calculate, prepare and add node to the dispatcher */
+ public void endElement(String uri, String name, String raw)
+ throws SAXException {
+ getLogger().debug("Ending element: " + raw);
+ if (Captions.NS.equals(uri)) {
+ // we are in the dispatcher ns
try {
- Node xpathNode;
- xpathNode = DOMUtil.getSingleNode(rootNode, path, this.processor);
- if (xpathNode == null)
- createXpathNode(attr, tempPath);
- else
- xpathNode.appendChild(currentElement);
+ if (Captions.STRUCTURE_ELEMENT.equals(name)) {
+ // we are in a structurer end element
+ if (includeNodes) {
+ includeNodes = false;
+ }
+ } else if (Captions.HOOK_ELEMENT.equals(name) && this.includeNodes) {
+ // we are inside a hook end element
+ pathNode = (OMElement) pathNode.getParent();
+ } else if (Captions.CONTRACT_ELEMENT.equals(name) && this.includeNodes) {
+ // we are inside a contract end element
+ contractProcessingEnd();
+ } else if (Captions.PROPERTY_ELEMENT.equals(name) && this.includeNodes) {
+ // we are inside a property end element
+ if (config.isAllowXmlProperties()) {
+ String property = null;
+ try {
+ // XMLizable endSAXRecording = super.endSAXRecording();
+ property = prefixString + endSerializedXMLRecording()
+ + "</forrest:property>";
+ insideProperties = false;
+ getLogger().debug(
+ "super.endSerializedXMLRecording(): " + property);
+ } catch (Exception e) {
+ throw new SAXException(e);
+ }
+ if (null != property) {
+ localParams.put(currentProperty, property.getBytes());
+ }
+ }
+ }
} catch (Exception e) {
- String error = "dispatcherError: " + DispatcherException.ERROR_500 + "\n"
- + "Could not set up xpath!\n\n DispatcherStack:\n " + e;
- getLogger().error(error);
- throw new SAXException(error);
+ throw new SAXException(e);
}
- path = tempPath;
+ } else if (this.insideProperties && this.includeNodes) {
+ super.endElement(uri, name, raw);
}
}
- /**
- * @param attr
- * @param tempPath
- * @throws ProcessingException
- * @throws DOMException
+ public void characters(char c[], int start, int len) throws SAXException {
+ /*
+ * only if we in properties mode we want to record the characters.
+ */
+ if (includeNodes && insideProperties) {
+ super.characters(c, start, len);
+ }
+ }
+
+ public void startDocument() throws SAXException {
+ // Add the namespace filter to our own output.
+ RedundantNamespacesFilter nsPipe = new RedundantNamespacesFilter();
+ if (this.xmlConsumer != null) {
+ nsPipe.setConsumer(this.xmlConsumer);
+ } else {
+ nsPipe.setContentHandler(this.contentHandler);
+ }
+ setConsumer(nsPipe);
+ }
+
+ public void endDocument() throws SAXException {
+ structurerProcessingEnd();
+ }
+
+ /*
+ * do nothing on the following methods, since we do not use them
*/
- private void createXpathNode(Attributes attr, String tempPath)
- throws ProcessingException, DOMException {
- Node xpathNode;
- xpathNode = DOMUtil.selectSingleNode(rootNode, tempPath, this.processor);
- if (attr != null)
- dispatcherHelper.setAttributesDOM(attr, xpathNode);
+ public void ignorableWhitespace(char c[], int start, int len)
+ throws SAXException {
+ }
+
+ public void startCDATA() throws SAXException {
+ }
+
+ public void endCDATA() throws SAXException {
+ }
+
+ public void comment(char[] ary, int start, int length) throws SAXException {
}
/**
- * @param attr
- * @param tempPath
- * @throws ProcessingException
- * @throws DOMException
+ * Will execute the contract and process the result.
+ *
+ * @throws ContractException
+ * @throws IOException
+ * @throws JaxenException
+ * @throws XMLStreamException
*/
- private Node createXpathNode(String tempPath) throws ProcessingException,
- DOMException {
- Node xpathNode;
- xpathNode = DOMUtil.selectSingleNode(rootNode, tempPath, this.processor);
- return xpathNode;
+ private void contractProcessingEnd() throws ContractException, IOException,
+ JaxenException, XMLStreamException {
+ // get the result stream from contract by executing it
+ InputStream resultStream = contract.execute(dataStream, localParams);
+ // close data stream
+ StreamHelper.closeStream(dataStream);
+ // add the result of the contract to the overall result set
+ try {
+ processContractResult(resultStream, pathNode);
+ } catch (OMException e) {
+ String error = DispatcherException.ERROR_500 + "\n"
+ + "component: ContractBean" + "\n"
+ + "message: Could not setup contractBean \"" + contract.getName() + "\". It seems that the result of the contract " +
+ "is returning an empty document. This normally happens when no forrest:content container is returned or" +
+ " the container does not contains any forrest:part.\n\n"
+ + "dispatcherErrorStack:\n" + e;
+ getLogger().error(error);
+ throw new ContractException(error);
+ }
+ // close the result Stream
+ StreamHelper.closeStream(resultStream);
}
- public void endElement(String uri, String name, String raw) throws SAXException {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Ending element: " + raw);
- }
- // Are we inside of properties? If so we need to record the elements.
- if (this.insideProperties) {
- propertyProcessingEnd(uri, name, raw);
- } else if (DispatcherHelper.DISPATCHER_NAMESPACE_URI.equals(uri)) {
- if (STRUCTURER_ELEMENT.equals(name))
- structurerProcessingEnd(raw);
- else if (ContractBean.CONTRACT_ELEMENT.equals(name) && this.includeNodes)
- contractProcessingEnd();
- else if (DISPATCHER_HOOK_ELEMENT.equals(name) && this.includeNodes)
- if (path.lastIndexOf("/") > -1)
- path = path.substring(0, path.lastIndexOf("/"));
- else
- path = null;
- } else {
- if (!this.insideProperties && this.includeNodes && this.insideStructurer
- && this.allowMarkup)
- super.endElement(uri, name, raw);
- if (!this.insideProperties && this.includeNodes && !this.insideStructurer)
- super.endElement(uri, name, raw);
+ /**
+ * Process the contract result to add it to the overall result set.
+ *
+ * @param resultStream
+ * @param pathNode
+ * @throws XMLStreamException
+ * @throws JaxenException
+ */
+ @SuppressWarnings("unchecked")
+ private void processContractResult(InputStream resultStream,
+ OMElement pathNode) throws XMLStreamException, JaxenException {
+ // get xml stream reader
+ XMLStreamReader contractResultReader = config.getStaxHelper().getReader(
+ resultStream);
+ // get Axiom builder
+ StAXOMBuilder builder = new StAXOMBuilder(contractResultReader);
+ // get the document element
+ OMElement content = builder.getDocumentElement();
+ /*
+ * For full blown ns support we need to get all ns from the result. This
+ * will be passed later to the XPath processor.
+ */
+ Iterator<OMNamespace> ns = content.getAllDeclaredNamespaces();
+ HashSet<OMNamespace> spaces = new HashSet<OMNamespace>();
+ while (ns.hasNext()) {
+ OMNamespace space = ns.next();
+ spaces.add(space);
+ }
+ // get the different parts of the contract
+ Iterator<OMElement> parts = content.getChildrenWithName(qIt(
+ Captions.NS_CONTRACTS, Captions.PART_ELEMENT));
+ while (parts.hasNext()) {
+ // while we have more parts, get the next part
+ OMElement part = parts.next();
+ // where do we need to inject it
+ String xpath = part.getAttributeValue(qIt(Captions.RESULT_XPATH));
+ // get the children of a part. This children needs to be injected in
+ // the result
+ Iterator<OMNode> children = part.getChildren();
+
+ if (xpath == null) {
+ // when we do not have a xpath to inject we will inject it in the
+ // current loaction
+ while (children.hasNext()) {
+ OMNode child = (OMNode) children.next();
+ pathNode.addChild(child);
+ }
+ } else {
+ // make sure the xpath is starting with "/"
+ if (!xpath.startsWith("/")) {
+ String message = contract.getName()
+ + " is using relative injection points which is not permited. "
+ + "Please fix this ASAP, for now we will do it for you.";
+ getLogger().warn(message);
+ xpath = "/" + xpath;
+ }
+ // lookup the node where we want to inject the result part
+ xpath = "/" + PATH_PREFIX + xpath;
+ // we need to feed the xpathSelector with the ns we may have
+ AXIOMXPathCreate xpathSelector = new AXIOMXPathCreate(xpath);
+ // add all namespaces that are known to the selector
+ for (OMNamespace space : spaces) {
+ xpathSelector
+ .addNamespace(space.getPrefix(), space.getNamespaceURI());
+ }
+ // request the final inject point (node which will be used to inject the
+ // result)
+ OMElement injectionPoint = (OMElement) xpathSelector.selectSingleNode(
+ root, true);
+ // now iterate through the children of the result part and append the
+ // content to the injection point
+ while (children.hasNext()) {
+ OMNode child = (OMNode) children.next();
+ injectionPoint.addChild(child);
+ }
+
+ }
}
}
/**
- * view type="?" Here we check which format we have in the view. That should
- * be extended to matching the requested format
+ * Helper method to create a qname
*
- * @param attr
+ * @param name
+ * the element name
+ * @return a qualified qname
+ */
+ private QName qIt(String name) {
+ return new QName(name);
+ }
+
+ /**
+ * Helper method to create a qname
+ *
+ * @param name
+ * the element name
+ * @param uri
+ * the ns
+ * @return a qualified qname
+ */
+ private QName qIt(String uri, String name) {
+ return new QName(uri, name);
+ }
+
+ /**
+ * Finish the processing of the structurer
+ *
+ * @param raw
* @throws SAXException
*/
- private void structurerProcessingStart(Attributes attr) throws SAXException {
- this.insideStructurer = true;
- for (int i = 0; i < attr.getLength(); i++) {
- String localName = attr.getLocalName(i);
- String value = attr.getValue(i);
- if (localName.equals(STRUCTURER_FORMAT_ATTRIBUTE)) {
- currentFormat = value;
- }
- if (localName.equals(STRUCTURER_HOOK_XPATH_ATTRIBUTE)) {
- if ("/".equals(String.valueOf(value.charAt(0))) && value.length() != 1) {
- path = "result" + value;
- } else if ("/".equals(String.valueOf(value.charAt(0)))
- && value.length() == 1) {
- path = "result";
- } else {
- path = "result/" + value;
- }
- }
- }
- if (requestedFormat.equals(currentFormat)) {
- localRecycle();
- try {
- if (null == this.dispatcherHelper)
- this.dispatcherHelper = new DispatcherHelper(m_resolver);
- if (null == this.processor)
- this.processor = (XPathProcessor) this.manager
- .lookup(XPathProcessor.ROLE);
- } catch (Exception e) {
- String error = "dispatcherError:\n Could not set up the dispatcherHelper!\n DispatcherStack: "
- + e;
- getLogger().error(error);
- throw new SAXException(error);
- }
- String propertyURI = "cocoon://" + requestId + ".props";
- try {
- this.defaultProperties = org.apache.forrest.dispatcher.util.SourceUtil
- .readDOM(propertyURI, m_resolver);
- } catch (Exception e1) {
- String error = "dispatcherError:\n" + "Could not get the properties for "
- + propertyURI + "\n DispatcherStack: " + e1;
- getLogger().error(error);
- throw new SAXException(error);
- }
- try {
- if (this.hooksXSL == null || this.hooksXSL.equals("")) {
- String warning = "dispatcherError:\n"
- + "You did not set up the \"hooksTransformer\" parameter in the sitemap, we are not going to transform forrest:hooks elements."
- + " For text output where you would not have to use hooks as structurer, the way you want it.";
- getLogger().warn(warning);
- } else {
- // * just store the $hooksXSL and do the DOM-reading/storing
- // later
- DOMSource stylesheet = new DOMSource(dispatcherHelper
- .getDocument(this.hooksXSL));
- this.structurerTransformer = dispatcherHelper
- .createTransformer(stylesheet);
- }
-
- } catch (Exception e) {
- String error = "dispatcherError:\n"
- + "Could not set up the \"hooks transformer\".\n\n DispatcherStack:\n "
- + e;
- getLogger().error(error);
- throw new SAXException(error);
- }
- if (path == null)
- path = "result";
- this.includeNodes = true;
- this.recording = true;
- try {
- dispatcherHelper.setNamespaceHelper(
- DispatcherHelper.DISPATCHER_NAMESPACE_URI,
- DispatcherHelper.DISPATCHER_PREFIX, STRUCTURER_ELEMENT);
- this.dispatcher = dispatcherHelper.getNamespaceHelper();
- this.document = dispatcher.getDocument();
- this.rootNode = document.getDocumentElement();
- this.rootNode.setAttribute(STRUCTURER_FORMAT_ATTRIBUTE, currentFormat);
- this.rootNode.setAttribute(STRUCTURER_HOOK_XPATH_ATTRIBUTE, path);
- // we create the path node for the result node
- DOMUtil.selectSingleNode(rootNode, path, this.processor);
- } catch (Exception e) {
- String error = "dispatcherError: " + DispatcherException.ERROR_500 + "\n"
- + "Could not setup dispatcherHelper!\n\n DispatcherStack:\n " + e;
- getLogger().error(error);
- this.recording = false;
- throw new SAXException(error);
+ private void structurerProcessingEnd() throws SAXException {
+ try {
+ // get the result of the structurer as stream
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ OMElement firstElement = root.getFirstElement();
+
+ if (null != firstElement & !multipleRoot) {
+ firstElement.serialize(out);
+ } else {
+ root.serialize(out);
}
- } else {
- path = null; // unset path because we do not process the node
- this.includeNodes = false;
- this.recording = false;
+ InputSource is = new InputSource(new StringReader(out.toString()));
+ // adding the result to the consumer
+ parser.parse(is, super.xmlConsumer);
+ } catch (Exception e) {
+ throw new SAXException(e);
}
+
}
/**
+ * Start the processing of the properties including setting the correct state
+ * for the next event round
+ *
+ * @param uri
+ * @param name
* @param raw
+ * @param attr
* @throws SAXException
*/
- private void structurerProcessingEnd(String raw) throws SAXException {
- if (this.recording) {
- try {
- NodeList resultList = this.rootNode.getFirstChild().getChildNodes();
- for (int i = 0; i < resultList.getLength(); i++) {
- Node array_element = resultList.item(i);
- if (this.structurerTransformer == null) {
- XMLUtils.valueOf(new IncludeXMLConsumer(super.xmlConsumer),
- array_element);
- } else {
- DOMSource source = new DOMSource(array_element);
- DOMResult result = new DOMResult();
- this.structurerTransformer.transform(source, result);
- XMLUtils.valueOf(new IncludeXMLConsumer(super.xmlConsumer), result
- .getNode());
- }
- }
-
- } catch (Exception e) {
- String error = "dispatcherError: " + DispatcherException.ERROR_500 + "\n"
- + "Could not setup final transformer!\n\n DispatcherStack:\n " + e;
- getLogger().error(error);
- this.recording = false;
- throw new SAXException(error);
- } finally {
- this.recording = false;
- this.insideStructurer = false;
+ private void propertyProcessingStart(String uri, String name, String raw,
+ Attributes attr) throws SAXException {
+ // determine the name and a possible value
+ String id = null, value = null;
+ String attributesString = "";
+ for (int i = 0; i < attr.getLength(); i++) {
+ String localName = attr.getLocalName(i);
+ String localValue = attr.getValue(i);
+ attributesString += " " + localName + "=\"" + localValue + "\"";
+ if (Captions.NAME_ATT.equals(localName)) {
+ id = localValue;
+ } else if (Captions.VALUE_ATT.equals(localName)) {
+ value = localValue;
}
}
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Ending \"" + STRUCTURER_ELEMENT + "\" element: " + raw);
+ currentProperty = id;
+ // if we allow xml properties we will just record them
+ if (config.isAllowXmlProperties()) {
+ // just start the recording
+ prefixString = "<" + raw + attributesString + ">";
+ startSerializedXMLRecording((XMLUtils.createPropertiesForXML(true)));
+ insideProperties = true;
+ } else {
+ // if we do not allow xml we will use a simple key/value approach
+ if (id != null && value != null) {
+ localParams.put(id, new String(value));
+ }
}
+
}
/**
- * We have found a contract. Now we have to prepare a bean to later add it to
- * the output stream in the endElement.
+ * Start the processing of the contract this includes to resolve the data
+ * stream and the actual contract.
*
* @param attr
* @throws SAXException
*/
private void contractProcessingStart(Attributes attr) throws SAXException {
- try {
- if (contract == null)
- contract = new ContractBeanDOMImpl(m_resolver, parameterHelper,
- defaultProperties, (URIResolver) this);
- } catch (Exception e) {
- String error = DispatcherException.ERROR_500 + "\n"
- + "component: ContractBean" + "\n"
- + "message: Could not setup contractBean." + "\n" + "\n\n"
- + "dispatcherErrorStack:\n" + e;
- getLogger().error(error);
- throw new SAXException(error);
- }
+ String name = "", data = null;
for (int i = 0; i < attr.getLength(); i++) {
String localName = attr.getLocalName(i);
String value = attr.getValue(i);
- if (ContractBean.CONTRACT_ID_ATTRIBUTE.equals(localName)) {
- // getting the contract name
- contract.setContractName(value);
- String contractUri = ContractBean.CONTRACT_RESOLVE_PREFIX + "."
- + currentFormat + "." + value;
- Source contractSource = null;
- try {
- // Adding the contract to the validity object.
- // As soon the contract changes we want a rebuild of
- // the page and not the cached object.
- if (!validityOverride.equals(CACHING_OFF) && null != this.validity) {
- contractSource = m_resolver.resolveURI(contractUri);
- SourceValidity contractValidityId = contractSource
- .getValidity();
- // we cannot allow null in an AggregatedValidity
- if (null != contractValidityId)
- this.validity.add(contractValidityId);
- }
- Document doc = org.apache.forrest.dispatcher.util.SourceUtil.readDOM(
- contractUri, m_resolver);
- contract.setContractImpl(doc, contractUri);
- // contract.setContractImpl(contractUri);
- } catch (Exception e) {
- String error = "dispatcherError: "
- + DispatcherException.ERROR_500
- + "\n"
- + "The contract \""
- + contract.getContractName()
- + "\" has thrown an exception by resolving the implementation from \""
- + contractUri + "\".\n\n" + "dispatcherErrorStack:\n" + e;
- getLogger().error(error);
- throw new SAXException(error);
- }finally{
- release(contractSource);
- }
- if (getLogger().isDebugEnabled()) {
- getLogger().debug(
- "DISPATCHER_CONTRACT_ID_ATTRIBUTE" + "-->" + localName + "\n"
- + "value" + "-->" + value);
- }
- } else if (ContractBean.CONTRACT_NUGGET_ATTRIBUTE.equals(localName)) {
- // contract is a nugget-contract
- contract.setNugget(true);
- Source contractRawSource =null;
- try {
- // Adding the raw data to the validity object.
- // As soon the raw data changes we want a rebuild of
- // the page and not the cached object.
- if (!validityOverride.equals(CACHING_OFF) && null != this.validity) {
- contractRawSource = m_resolver.resolveURI(value);
- SourceValidity contractValidityRaw = contractRawSource
- .getValidity();
- // we cannot allow null in an AggregatedValidity
- if (null != contractValidityRaw)
- this.validity.add(contractValidityRaw);
- }
- Document doc = org.apache.forrest.dispatcher.util.SourceUtil.readDOM(
- value, m_resolver);
- contract.setContractRawData(doc);
- // contract.setNuggetUri(value);
- } catch (Exception e) {
- String error = "dispatcherError: " + DispatcherException.ERROR_500 + "\n"
- + "The contract \"" + contract.getContractName()
- + "\" has thrown thrown an exception by resolving raw data from \""
- + value + "\".\n\n" + "dispatcherErrorStack:\n " + e;
- getLogger().error(error);
- throw new SAXException(error);
- } finally{
- release(contractRawSource);
- }
- if (getLogger().isDebugEnabled()) {
- getLogger().debug(
- "ContractBean.CONTRACT_NUGGET_ATTRIBUTE" + "-->" + localName + "\n"
- + "value" + "-->" + value);
- }
- } else {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("localName" + "-->" + localName + " not implemented");
- }
+ if (Captions.NAME_ATT.equals(localName)) {
+ // get the name of the contract
+ name = value;
+ } else if (Captions.DATA_ATT.equals(localName)) {
+ // see whether we have a defined dataUri
+ data = value;
}
}
- /*
- * if we do not have a nugget add a foo element to the raw data to invoke
- * the transformation.
- */
- if (!contract.isNugget()) {
- Document foo;
+ dataStream = null;
+ if (null != data && !data.equals("")) {
+ // try resolving the dataUri
try {
- foo = dispatcherHelper.createDocument("foo");
- contract.setContractRawData(foo);
+ dataStream = resolverDispatcher.resolve(data);
} catch (Exception e) {
- String error = "dispatcherError: "
- + DispatcherException.ERROR_500
- + "\n"
- + "The contract \""
- + contract.getContractName()
- + "\" has thrown thrown an exception by creating the dummy foo document."
- + ".\n\n" + "dispatcherErrorStack:\n " + e;
+ String error = DispatcherException.ERROR_500 + "\n"
+ + "component: ContractBean" + "\n" + "message: ContractBean \""
+ + name + "\" has thrown an exception " + "resolving the dataUri \""
+ + data + "\".\n\n" + "dispatcherErrorStack:\n" + e;
getLogger().error(error);
throw new SAXException(error);
}
}
- }
-
- /**
- * @throws SAXException
- */
- private void contractProcessingEnd() throws SAXException {
try {
- contract.setContractResultData();
- Document node = (Document) contract.getContractResultData().getNode();
- Document root = this.rootNode.getOwnerDocument();
- /*
- * debug code - uncomment it if you need it! will output the contract
- * resulting data to sysout
- */
- // DOMSource source = new DOMSource(node);
- // StreamResult result = new StreamResult(System.out);
- // contract.getContractTransformer().transform(source, result);
- /*
- * append this node to the current path after testing where there is a
- * fixed location for the contract content. If so then add it there.
- */
- NodeList contentChildren = node.getElementsByTagNameNS(
- DispatcherHelper.DISPATCHER_NAMESPACE_URI, "part");
- for (int i = 0; i < contentChildren.getLength(); i++) {
- Element contentChild = (Element) contentChildren.item(i);
- NodeList finalContent = contentChild.getChildNodes();
- if (contentChild != null) {
- String location = contentChild.getAttribute("xpath");
- if (location.equals("") | location == null) {
- Node xpathNode = DOMUtil.getSingleNode(rootNode, path, this.processor);
- if (xpathNode != null) {
- // add everything *within* the forrest:part element
- appendChildToResultIterator(root, finalContent, xpathNode);
- }
- } else {
- if (location.charAt(0) == '/')
- location = "result" + location;
- else
- location = "result/" + location;
- Node xpathNode = DOMUtil.getSingleNode(rootNode, location,
- this.processor);
- if (xpathNode != null) {
- // add everything *within* the forrest:part element
- appendChildToResultIterator(root, finalContent, xpathNode);
- } else {
- xpathNode = createXpathNode(location);
- // add everything *within* the forrest:part element
- appendChildToResultIterator(root, finalContent, xpathNode);
- }
- }
- }
- }
+
+ // get the contract
+ contract = contractRep.resolve(name);
+ // prepare empty properties map
+ localParams = new HashMap<String, Object>(map);
+ localParams.put("contract.name", name);
} catch (Exception e) {
- String error = "dispatcherError: "
- + DispatcherException.ERROR_500
- + "\n"
- + "The contract \""
- + contract.getContractName()
- + "\" has thrown thrown an exception while trying to transform the final markup. \n\n"
- + "dispatcherErrorStack:\n " + e;
+ String error = DispatcherException.ERROR_500 + "\n"
+ + "component: ContractBean" + "\n"
+ + "message: Could not setup contractBean \"" + name + "\".\n\n"
+ + "dispatcherErrorStack:\n" + e;
getLogger().error(error);
throw new SAXException(error);
- } finally {
- this.contract.recycle();
- }
- }
-
- /**
- * @param root
- * @param finalContent
- * @param xpathNode
- * @throws DOMException
- */
- private void appendChildToResultIterator(Document root, NodeList finalContent,
- Node xpathNode) throws DOMException {
- for (int j = 0; j < finalContent.getLength(); j++) {
- appendChildToResult(root, finalContent, xpathNode, j);
}
- }
- /**
- * @param root
- * @param finalContent
- * @param xpathNode
- * @param j
- * @throws DOMException
- */
- private void appendChildToResult(Document root, NodeList finalContent,
- Node xpathNode, int j) throws DOMException {
- Node contractData = finalContent.item(j);
- Node toMove = root.importNode(contractData, true);
- xpathNode.appendChild(toMove);
}
/**
- * @param uri
+ * Start the processing of the hooks. Actually we just create a element in the
+ * result model with the same name and attributes as the incoming event.
+ *
* @param name
* @param raw
* @param attr
- * @throws SAXException
*/
- private void propertyProcessingStart(String uri, String name, String raw,
- Attributes attr) throws SAXException {
+ private void hookProcessingStart(String name, String raw, Attributes attr) {
+ OMElement element = factory.createOMElement(name, Captions.NS, "forrest");
for (int i = 0; i < attr.getLength(); i++) {
String localName = attr.getLocalName(i);
String value = attr.getValue(i);
- if (ContractBean.PROPERTY_ID_ATTRIBUTE.equals(localName))
- this.propertyID = value;
+ OMAttribute attribute = factory.createOMAttribute(localName, null, value);
+ element.addAttribute(attribute);
}
- if (this.propertyID.equals("") | this.propertyID == null) {
- String error = "dispatcherError: " + DispatcherException.ERROR_500 + "\n"
- + "The contract \"" + contract.getContractName()
- + "\" has no identifier attribute \""
- + ContractBean.PROPERTY_ID_ATTRIBUTE + "\" in the " + raw;
- getLogger().error(error);
- throw new SAXException(error);
- }
- this.builder = new DOMBuilder();
- this.builder.startDocument();
- launchStoredMappings();
- this.builder.startElement(uri, name, raw, attr);
+ pathNode.addChild(element);
+ pathNode = element;
}
/**
- * @param uri
- * @param name
- * @param raw
+ * view type="?" Here we check which format we have in the view. That should
+ * be extended to matching the requested format
+ *
+ * @param attr
+ * @throws JaxenException
* @throws SAXException
*/
- private void propertyProcessingEnd(String uri, String name, String raw)
- throws SAXException {
- if (ContractBean.PROPERTY_ELEMENT.equals(name)) {
- this.insideProperties = false;
- if (this.includeNodes) {
- this.builder.endElement(uri, name, raw);
- this.builder.endDocument();
- if (getLogger().isDebugEnabled()) {
- getLogger()
- .debug(
- "DispatcherTransformer: putting DOM tree into the contract transformer");
+ private void structurerProcessingStart(Attributes attr)
+ throws DispatcherException {
+ String m_type = "", path = "";
+ for (int i = 0; i < attr.getLength(); i++) {
+ String localName = attr.getLocalName(i);
+ String value = attr.getValue(i);
+ // determine what type (format) we have on the structurer
+ if (localName.equals(Captions.TYPE_ATT)) {
+ m_type = value;
+ }
+ /*
+ * Determine whether we have a hooks path attribute. If so it determines
+ * the smallest common path (e.g. <code>/html/body</code>)
+ */
+ if (localName.equals(Captions.HOOKS_ATT)) {
+ // adding the default path
+ boolean startsWithRoot = "/".equals(String.valueOf(value.charAt(0)));
+ if (!startsWithRoot) {
+ value = "/" + value;
+ } else if (value.length() == 1 && startsWithRoot) {
+ value = "";
}
- Transformer transformer = contract.getContractTransformer();
- transformer.setParameter(this.propertyID, this.builder.getDocument()
- .getFirstChild());
- contract.setContractTransformer(transformer);
- this.propertyID = "";
- contract.setHasProperties(true);
- if (getLogger().isDebugEnabled()) {
- getLogger().debug(
- "DispatcherTransformer: DOM tree is in the contract transformer");
+ path += value;
+ }
+ }
+ // are we in the format that have been requested?
+ if (requestedFormat.equals(m_type)) {
+ try {
+ // need to get the properties for this uri
+ map = new HashMap<String, Object>();
+ /*
+ * the properties are provided by a match in cocoon and are generated
+ * individually for each request
+ */
+ String propertyURI = "cocoon://" + requestId + ".props";
+ // get the source representation of the propertyURI
+ Source propsSource = m_resolver.resolveURI(propertyURI);
+ if (propsSource != null) {
+ // get an input stream from the properties
+ InputStream stream = new BufferedInputStream(propsSource
+ .getInputStream());
+ /*
+ * we need either just the bytes of the stream (if we allow xml
+ * properties) or we need to process it: extracting the properties.
+ */
+ if (config.isAllowXmlProperties()) {
+ // get the bytes from the stream
+ byte[] properties = IOUtils.getStreamAsByteArray(stream);
+ /*
+ * add the bytes to the properties map later on they will be picked
+ * up and parsed to a dom node.
+ */
+ map.put(DEFAULT_VARIABLES, properties);
+ } else {
+ // extract the properties of the incoming stream
+ XMLProperties.parseProperties(stream, map);
+ }
+ // release source - you need to ALWAYS do this!
+ release(propsSource);
}
- this.builder = null;
+ /*
+ * Preparing the model by creating a root document/element. Afterward we
+ * need to strip the root element again.
+ */
+ OMDocument doc = factory.createOMDocument();
+ // creating the root node for the xml document
+ root = factory.createOMElement(PATH_PREFIX, null);
+ // adding root element to the document (much like in DOM)
+ doc.addChild(root);
+ /*
+ * request a axiom xpath resolver that will return a axiom element for a
+ * given xpath expression. If the node does not exist, it is created and
+ * then returned.
+ */
+ AXIOMXPathCreate xpath = new AXIOMXPathCreate("/" + PATH_PREFIX + path);
+ // get the node (if it does not exist, create it)
+ pathNode = (OMElement) xpath.selectSingleNode(root, true);
+ // we need to set the status variable, indicating we need process the
+ // children.
+ this.includeNodes = true;
+ } catch (Exception e) {
+ throw new DispatcherException(e);
}
} else {
- if (this.includeNodes)
- this.builder.endElement(uri, name, raw);
+ pathNode = null; // unset path because we do not process the node
+ this.includeNodes = false;
}
- }
- public void characters(char c[], int start, int len) throws SAXException {
- if (this.insideProperties && this.includeNodes)
- this.builder.characters(c, start, len);
- else if (!this.insideProperties && this.includeNodes && !this.insideStructurer)
- super.contentHandler.characters(c, start, len);
}
- public void startCDATA() throws SAXException {
- if (this.insideProperties && this.includeNodes)
- this.builder.startCDATA();
- else if (!this.insideProperties && this.includeNodes && !this.insideStructurer)
- super.lexicalHandler.startCDATA();
+ /**
+ * Generate the unique key. This key must be unique inside the space of this
+ * component.
+ *
+ * @return The generated key hashes the src
+ */
+ public Serializable getKey() {
+ return this.cacheKey;
}
- public void endCDATA() throws SAXException {
- if (this.insideProperties && this.includeNodes)
- this.builder.endCDATA();
- else if (!this.insideProperties && this.includeNodes && !this.insideStructurer)
- super.lexicalHandler.endCDATA();
+ /**
+ * Generate the validity object.
+ *
+ * @return The generated validity object or <code>null</code> if the component
+ * is currently not cacheable.
+ */
+ public SourceValidity getValidity() {
+ // You can either request URL?dispatcher.caching=off
+ // or add this property to forrest.properties.xml
+ // to force a SourceValidity.INVALID
+ if (null != validityFile && !(validityChecking.equals(CACHING_OFF))) {
+ Source resolveSource = null;
+ try {
+ resolveSource = m_resolver.resolveURI(validityFile);
+ this.validity = resolveSource.getValidity();
+ } catch (Exception e) {
+ getLogger().error(e.getMessage());
+ } finally {
+ release(resolveSource);
+ }
+ } else
+ this.validity = null;
+ return this.validity;
}
- /** BEGIN SAX ContentHandler handlers * */
-
- public void startPrefixMapping(String prefix, String uri) throws SAXException {
- super.startPrefixMapping(prefix, uri);
- if (this.insideProperties && this.includeNodes) {
- this.builder.startPrefixMapping(prefix, uri);
- } else {
- storePrefixMapping(prefix, uri);
+ /**
+ * @see org.apache.excalibur.source.SourceFactory#release(org.apache.excalibur.source.Source)
+ */
+ public void release(Source source) {
+ if (source != null) {
+ m_resolver.release(source);
}
}
- /** END SAX ContentHandler handlers * */
-
- protected void storePrefixMapping(String prefix, String uri) {
- storedPrefixMap.put(prefix, uri);
+ /**
+ * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ */
+ public void service(ServiceManager manager) throws ServiceException {
+ super.service(manager);
+ this.entityResolver = (EntityResolver) this.manager
+ .lookup(org.apache.excalibur.xml.EntityResolver.ROLE);
}
- protected void launchStoredMappings() throws SAXException {
- Iterator it = storedPrefixMap.keySet().iterator();
- while (it.hasNext()) {
- String pre = (String) it.next();
- String uri = (String) storedPrefixMap.get(pre);
- getLogger().debug(
- "WriteSessionTransformer: launching prefix mapping[ pre: " + pre
- + " uri: " + uri + " ]");
- this.builder.startPrefixMapping(pre, uri);
+ /**
+ * @see org.apache.avalon.framework.activity.Disposable#dispose()
+ */
+ public void dispose() {
+ if (null != this.manager) {
+ if (null != m_resolver)
+ this.manager.release(m_resolver);
+ this.manager = null;
}
+ m_resolver = null;
+ super.dispose();
}
- protected void launchStoredMappingsDispatcher() throws SAXException {
- Iterator it = storedPrefixMap.keySet().iterator();
- while (it.hasNext()) {
- String pre = (String) it.next();
- String uri = (String) storedPrefixMap.get(pre);
- getLogger().debug(
- "WriteSessionTransformer: launching prefix mapping[ pre: " + pre
- + " uri: " + uri + " ]");
- this.dispatcherBuilder.startPrefixMapping(pre, uri);
- }
+ /**
+ * Recycle the component
+ */
+ public void recycle() {
+ this.includeNodes = false;
+ this.insideProperties = false;
+ this.requestId = "";
+ this.validity = null;
+ this.root = null;
+ this.pathNode = null;
+ this.contract = null;
+ this.map = null;
+ this.localParams = null;
+ this.currentProperty = null;
+ super.recycle();
+
}
+ /*
+ * From URIResolver, copied from TraxProcessor
+ *
+ * @see javax.xml.transform.URIResolver#resolve(java.lang.String,
+ * java.lang.String)
+ */
public javax.xml.transform.Source resolve(String href, String base)
throws TransformerException {
if (getLogger().isDebugEnabled()) {
@@ -1017,7 +1030,8 @@
// always be protocol:/....
return null; // we can't resolve this
} else {
- xslSource = m_resolver.resolveURI(base.substring(0, lastPathElementPos)
+ xslSource = m_resolver.resolveURI(base.substring(0,
+ lastPathElementPos)
+ "/" + href);
}
} else {
@@ -1038,39 +1052,36 @@
} catch (SourceException e) {
if (getLogger().isDebugEnabled()) {
getLogger().debug(
- "Failed to resolve " + href + "(base = " + base + "), return null", e);
+ "Failed to resolve " + href + "(base = " + base + "), return null",
+ e);
}
// CZ: To obtain the same behaviour as when the resource is
// transformed by the XSLT Transformer we should return null here.
return null;
} catch (java.net.MalformedURLException mue) {
- if (getLogger().isDebugEnabled()) {
- getLogger()
- .debug(
- "Failed to resolve " + href + "(base = " + base + "), return null",
- mue);
- }
+ getLogger().debug(
+ "Failed to resolve " + href + "(base = " + base + "), return null",
+ mue);
return null;
} catch (IOException ioe) {
if (getLogger().isDebugEnabled()) {
- getLogger()
- .debug(
- "Failed to resolve " + href + "(base = " + base + "), return null",
- ioe);
+ getLogger().debug(
+ "Failed to resolve " + href + "(base = " + base + "), return null",
+ ioe);
}
return null;
} finally {
- release(xslSource);
+ release(xslSource);
}
}
/**
- * Return a new <code>InputSource</code> object that uses the
- * <code>InputStream</code> and the system ID of the <code>Source</code>
- * object.
+ * Return a new <code>InputSource</code> object that uses the <code>
+ * InputStream</code>
+ * and the system ID of the <code>Source</code> object.
*
* @throws IOException
* if I/O error occured.
@@ -1081,5 +1092,4 @@
newObject.setSystemId(source.getURI());
return newObject;
}
-
}
Modified: forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.internal.dispatcher/status.xml
URL: http://svn.apache.org/viewvc/forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.internal.dispatcher/status.xml?rev=886147&r1=886146&r2=886147&view=diff
==============================================================================
--- forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.internal.dispatcher/status.xml (original)
+++ forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.internal.dispatcher/status.xml Wed Dec 2 13:58:18 2009
@@ -21,113 +21,95 @@
<person name="Ross Gardler" email="rgardler@apache.org" id="RDG" />
<person name="Thorsten Scherler" email="thorsten@apache.org" id="TS" />
<person name="Gavin McDonald" email="gmcdonald@apache.org" id="GM" />
- <person name="Volunteer needed" email="dev@forrest.apache.org" id="open"/>
+ <person name="Volunteer needed" email="dev@forrest.apache.org" id="open" />
</developers>
-<!-- Define here the Title of the Context you want to display in the Changes pages.
+ <!-- Define here the Title of the Context you want to display in the Changes pages.
id = the context value of actions
title = Title of the Context
-->
<contexts>
- <context id="code" title="Changes to the Code Base"/>
- <context id="docs" title="Changes to Documentation"/>
- <context id="admin" title="Changes to Project Administration"/>
- <context id="design" title="Changes to Design"/>
- <context id="build" title="Changes to Build"/>
+ <context id="code" title="Changes to the Code Base" />
+ <context id="docs" title="Changes to Documentation" />
+ <context id="admin" title="Changes to Project Administration" />
+ <context id="design" title="Changes to Design" />
+ <context id="build" title="Changes to Build" />
</contexts>
<changes>
-<!-- Add new releases here -->
- <release version="0.1" date="unreleased">
- <action context="code" dev="DC" importance="high" type="add" fixes-bug="FOR-1156">
- Enabled the output html serializer to be configurable to either xhtml or html.
- See docs: <link href="site:configure-serializer">Configure output serializer</link>.
- </action>
- <action context="docs" dev="GM" importance="high" type="add">
- Added an examples tab and section to show working examples
- of how to add independant and plugin dependent contracts.
- A first example showing the POD plugin & contract has
- been started.
- </action>
- <action context="code" dev="TS" type="update"> Cleaning up
- usage of structurer using the new chunks of FOR-1059. Reducing code duplications.
- </action>
- <action context="code" dev="TS" importance="high" type="update"> Cleaning up
- locationmap from the former xdocs location. See
- <link href="site:news">news #cleanup.15.06.07</link> how to update. </action>
- <action context="code" type="fix" dev="TS" fixes-bug="FOR-975" importance="high">
- FOR-975 Renaming tiles to panel.
- </action>
- <action context="code" type="add" dev="TS" fixes-bug="FOR-937" due-to="Sjur Moshagen">
- More i18n work by Sjur on Dispatcher. This patch correctly localizes menus & tabs.
- </action>
- <action context="code" type="fix" dev="DC" fixes-bug="FOR-939" due-to="Sjur Moshagen">
- Rename to ContractsMessages_en.xml, part of i18n changes by Sjur.
- </action>
- <action context="code" type="add" dev="RDG">
- Add ability to get a list of contracts provided by a plugin. For
- this to work the plugin name must have "plugin" within it, e.g.
- "org.apache.forrest.plugin.input.doap". Requesting
- <code>ls.contracts.org.apache.forrest.plugin.input.doap.source.xml</code>
- will return a source listing of plugins provided by the named plugin.
- Requesting <code>ls.contracts.org.apache.forrest.plugin.input.doap.[FORMAT]</code>
- will return a formatted output document listing all templates supplied
- by the identified plugin.
- </action>
+ <!-- Add new releases here -->
+ <release version="0.1" date="unreleased">
+ <action context="docs" dev="GM" importance="high" type="add">Added an
+ examples tab and section to show working examples of how to add
+ independant and plugin dependent contracts. A first example showing the
+ POD plugin & contract has been started.</action>
+ <action context="code" dev="TS" type="update">Cleaning up usage of
+ structurer using the new chunks of FOR-1059. Reducing code
+ duplications.</action>
+ <action context="code" dev="TS" importance="high" type="update">Cleaning
+ up locationmap from the former xdocs location. See
+ <link href="site:news">news #cleanup.15.06.07</link>how to
+ update.</action>
+ <action context="code" type="fix" dev="TS" fixes-bug="FOR-975"
+ importance="high">FOR-975 Renaming tiles to panel.</action>
+ <action context="code" type="add" dev="TS" fixes-bug="FOR-937"
+ due-to="Sjur Moshagen">More i18n work by Sjur on Dispatcher. This patch
+ correctly localizes menus & tabs.</action>
+ <action context="code" type="fix" dev="DC" fixes-bug="FOR-939"
+ due-to="Sjur Moshagen">Rename to ContractsMessages_en.xml, part of i18n
+ changes by Sjur.</action>
+ <action context="code" type="add" dev="RDG">Add ability to get a list of
+ contracts provided by a plugin. For this to work the plugin name must
+ have "plugin" within it, e.g. "org.apache.forrest.plugin.input.doap".
+ Requesting
+ <code>
+ ls.contracts.org.apache.forrest.plugin.input.doap.source.xml</code>will
+ return a source listing of plugins provided by the named plugin.
+ Requesting
+ <code>
+ ls.contracts.org.apache.forrest.plugin.input.doap.[FORMAT]</code>will
+ return a formatted output document listing all templates supplied by the
+ identified plugin.</action>
<action context="code" type="update" dev="DC" fixes-bug="FOR-935"
- due-to="Sjur Moshagen">
- i18n: Add LocaleAction action wrapper, and use the locale provided by it.
- Was taking the locale directly from the request instead of using the standard method in Forrest: LocaleAction.
- </action>
- <action dev="TS" type="add" context="docs">
- Adding the "how tos" from the site-author to this plugin.
- </action>
-<!-- 07/2006 -->
- <action dev="TS" type="add" context="code"> Extending the dispatcher
- with an internal format. This internal format is our xdoc or
- xhtml2. The internal format will then be contacted by e.g. html
- contracts. </action>
-<!-- < 07/2006 -->
- <action dev="TS" type="add" context="admin">
- Initial plugin code extracted from the old views plugin.
-</action>
- <action dev="TS" type="add" context="code"> Added first implementation of
- the dispatcher. Including contract bean implementation and interface;
- dispatcher exception and dispatcher transformers. </action>
- <action dev="GM" type="add" context="docs">
- Added a dispatcher glossary. Thanks to Thorsten for moving to the plugin.
- </action>
- <action dev="TS" type="add" context="docs">
- Added infos of the pattern the plugin is using.
- </action>
- <action dev="TS" type="add" context="docs">
- Updated the "how it works" section and moved it to its own site.
- </action>
- <action context="code" dev="TS" type="add">
- Adding the dispatcher concept documentation from the site-author.
- </action>
- <action dev="TS" type="update" context="docs" fixes-bug="FOR-768"
- due-to="Paul Bolger">
- Added section "linking to external css files" to howto-structurer-dsl doc.
- </action>
- <action dev="TS" type="add" context="code">
- Activated multiple output formats to be configured via a View.
- </action>
- <action dev="TS" type="add" context="code">
- Added contracts and nuggets to the "view" plugins.
- </action>
+ due-to="Sjur Moshagen">i18n: Add LocaleAction action wrapper, and use the
+ locale provided by it. Was taking the locale directly from the request
+ instead of using the standard method in Forrest: LocaleAction.</action>
+ <action dev="TS" type="add" context="docs">Adding the "how tos" from the
+ site-author to this plugin.</action>
+ <!-- 07/2006 -->
+ <action dev="TS" type="add" context="code">Extending the dispatcher with
+ an internal format. This internal format is our xdoc or xhtml2. The
+ internal format will then be contacted by e.g. html contracts.</action>
+ <!-- < 07/2006 -->
+ <action dev="TS" type="add" context="admin">Initial plugin code extracted
+ from the old views plugin.</action>
+ <action dev="TS" type="add" context="code">Added first implementation of
+ the dispatcher. Including contract bean implementation and interface;
+ dispatcher exception and dispatcher transformers.</action>
+ <action dev="GM" type="add" context="docs">Added a dispatcher glossary.
+ Thanks to Thorsten for moving to the plugin.</action>
+ <action dev="TS" type="add" context="docs">Added infos of the pattern the
+ plugin is using.</action>
+ <action dev="TS" type="add" context="docs">Updated the "how it works"
+ section and moved it to its own site.</action>
+ <action context="code" dev="TS" type="add">Adding the dispatcher concept
+ documentation from the site-author.</action>
+ <action dev="TS" type="update" context="docs" fixes-bug="FOR-768"
+ due-to="Paul Bolger">Added section "linking to external css files" to
+ howto-structurer-dsl doc.</action>
+ <action dev="TS" type="add" context="code">Activated multiple output
+ formats to be configured via a View.</action>
+ <action dev="TS" type="add" context="code">Added contracts and nuggets to
+ the "view" plugins.</action>
</release>
</changes>
<todo>
<actions priority="high">
- <action context="docs" dev="open">
- create some more example, that it is easier to adapt the concept. An examples section
- has been added, but more examples needed to cover the contracts available.
- </action>
- <action context="core" dev="open">
- Rewrite matches to allow other output implementation then html.
- </action>
- <action context="core" dev="open">
- Extract businessHelper to their on implementation plugin.
- </action>
+ <action context="docs" dev="open">create some more example, that it is
+ easier to adapt the concept. An examples section has been added, but more
+ examples needed to cover the contracts available.</action>
+ <action context="core" dev="open">Rewrite matches to allow other output
+ implementation then html.</action>
+ <action context="core" dev="open">Extract businessHelper to their on
+ implementation plugin.</action>
</actions>
</todo>
</status>
Modified: forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.internal.dispatcher/themes.xmap
URL: http://svn.apache.org/viewvc/forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.internal.dispatcher/themes.xmap?rev=886147&r1=886146&r2=886147&view=diff
==============================================================================
--- forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.internal.dispatcher/themes.xmap (original)
+++ forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.internal.dispatcher/themes.xmap Wed Dec 2 13:58:18 2009
@@ -17,16 +17,16 @@
-->
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<map:components>
- <map:generators default="file"/>
- <map:transformers default="xslt"/>
+ <map:generators default="file" />
+ <map:transformers default="xslt" />
<map:serializers default="xml">
- <map:serializer name="txt"
- src="org.apache.cocoon.serialization.TextSerializer"
- mime-type="text/plain" logger="sitemap.serializer.text" />
- <map:serializer mime-type="image/png" name="svg2png"
- src="org.apache.cocoon.serialization.SVGSerializer">
-<!--<parameter name="background_color" type="color" value="#ff00ff"/>-->
-<!-- <parameter name="gamma" type="float" value="0.48"/> -->
+ <map:serializer name="txt"
+ src="org.apache.cocoon.serialization.TextSerializer"
+ mime-type="text/plain" logger="sitemap.serializer.text" />
+ <map:serializer mime-type="image/png" name="svg2png"
+ src="org.apache.cocoon.serialization.SVGSerializer">
+ <!--<parameter name="background_color" type="color" value="#ff00ff"/>-->
+ <!-- <parameter name="gamma" type="float" value="0.48"/> -->
<parameter name="gamma" type="float" value="0" />
</map:serializer>
</map:serializers>
@@ -34,11 +34,9 @@
<map:resources>
<map:resource name="read-linked-text">
<map:generate type="text" src="{path}" />
- <map:transform type="pattern"
- src="{forrest:forrest.context}/resources/chaperon/grammars/link.xlex" />
- <map:transform
- src="{forrest:forrest.context}/resources/chaperon/stylesheets/pattern2link.xsl"
- />
+ <map:transform type="pattern"
+ src="{forrest:forrest.context}/resources/chaperon/grammars/link.xlex" />
+ <map:transform src="{forrest:forrest.context}/resources/chaperon/stylesheets/pattern2link.xsl" />
<map:serialize type="text" mime-type="text/css" />
</map:resource>
</map:resources>
@@ -54,7 +52,7 @@
</map:match>
</map:pipeline>
<map:pipeline>
-<!--
+ <!--
Last processing step.
Here we are overriding the default skin generation.
-->
@@ -62,16 +60,16 @@
<map:call resource="read-linked-text">
<map:parameter name="path" value="{lm:themes/{1}.css}" />
</map:call>
-<!-- <map:read mime-type="text/css" src="{lm:themes/{1}.css}" /> -->
+ <!-- <map:read mime-type="text/css" src="{lm:themes/{1}.css}" /> -->
</map:match>
<map:match pattern="themes/**.js">
- <map:read mime-type="application/x-javascript" src="{lm:themes/{1}.js}"
- />
+ <map:read mime-type="application/x-javascript"
+ src="{lm:themes/{1}.js}" />
</map:match>
- <map:match
- pattern="themes/images**/roundcorner-*-*-*-bg*-stroke*-fg*.svg">
- <map:generate src="{forrest:forrest.plugins}/org.apache.forrest.plugin.internal.dispatcher/status.xml" />
- <map:transform src="{forrest:forrest.plugins}/org.apache.forrest.plugin.internal.dispatcher/resources/stylesheets/round-corner-hex.svg.xslt">
+ <map:match pattern="themes/images**/roundcorner-*-*-*-bg*-stroke*-fg*.svg">
+
+ <map:generate src="status.xml" />
+ <map:transform src="{lm:theme.images.corner.round}">
<map:parameter name="orientation-tb" value="{2}" />
<map:parameter name="orientation-lr" value="{3}" />
<map:parameter name="size" value="{4}" />
@@ -81,18 +79,15 @@
</map:transform>
<map:serialize type="xml" />
</map:match>
- <map:match
- pattern="themes/images**/roundcorner-*-*-*-bg*-stroke*-fg*.svg-to-png">
- <map:generate
- src="cocoon:/themes/images{1}/roundcorner-{2}-{3}-{4}-bg{5}-stroke{6}-fg{7}.svg"
- />
+ <map:match pattern="themes/images**/roundcorner-*-*-*-bg*-stroke*-fg*.svg-to-png">
+
+ <map:generate src="cocoon:/themes/images{1}/roundcorner-{2}-{3}-{4}-bg{5}-stroke{6}-fg{7}.svg" />
<map:serialize type="svg2png" />
</map:match>
- <map:match
- pattern="themes/images**/roundcorner-*-*-*-bg*-stroke*-fg*.png">
- <map:read
- src="cocoon:/themes/images{1}/roundcorner-{2}-{3}-{4}-bg{5}-stroke{6}-fg{7}.svg-to-png"
- mime-type="image/png" />
+ <map:match pattern="themes/images**/roundcorner-*-*-*-bg*-stroke*-fg*.png">
+
+ <map:read src="cocoon:/themes/images{1}/roundcorner-{2}-{3}-{4}-bg{5}-stroke{6}-fg{7}.svg-to-png"
+ mime-type="image/png" />
</map:match>
<map:match pattern="themes/images/**.*">
<map:match type="regexp" pattern="(.*\.)(jpg|JPG|Jpg|jpeg|Jpeg|JPEG)$">
Propchange: forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.output.tei/LICENSE.txt
('svn:mergeinfo' removed)
Propchange: forrest/trunk/whiteboard/plugins/org.apache.forrest.plugin.output.tei/NOTICE.txt
('svn:mergeinfo' removed)