Author: thorsten Date: Tue Sep 30 06:16:26 2008 New Revision: 700452 URL: http://svn.apache.org/viewvc?rev=700452&view=rev Log: FOR-1118 removing all obsolete code from the transformer
Modified: forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java Modified: forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java URL: http://svn.apache.org/viewvc/forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java?rev=700452&r1=700451&r2=700452&view=diff ============================================================================== --- forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java (original) +++ forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/transformation/DispatcherTransformer.java Tue Sep 30 06:16:26 2008 @@ -16,22 +16,15 @@ */ package org.apache.forrest.dispatcher.transformation; -import java.io.File; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.Serializable; -import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -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; @@ -39,191 +32,136 @@ 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.xml.XMLUtils; -import org.apache.cocoon.xml.dom.DOMBuilder; -import org.apache.cocoon.xml.dom.DOMUtil; 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.xml.sax.Attributes; -import org.xml.sax.InputSource; +import org.apache.excalibur.xml.sax.XMLizable; +import org.apache.forrest.dispatcher.api.Structurer; +import org.apache.forrest.dispatcher.config.DispatcherBean; +import org.apache.forrest.dispatcher.exception.DispatcherException; +import org.apache.forrest.dispatcher.impl.CocoonResolver; +import org.apache.forrest.dispatcher.impl.XMLStructurer; +import org.apache.forrest.dispatcher.impl.XMLStructurerAxiom; +import org.apache.forrest.dispatcher.impl.helper.Captions; import org.xml.sax.SAXException; -import org.xml.sax.helpers.AttributesImpl; public class DispatcherTransformer extends AbstractSAXTransformer implements - Disposable, CacheableProcessingComponent, URIResolver { + Disposable, CacheableProcessingComponent { - /* 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> + * The requested format. */ - public static final String STRUCTURER_ELEMENT = "view"; + private String requestedFormat,requestId; /** - * <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> + * Caching and validity properties */ - public static final String STRUCTURER_FORMAT_ATTRIBUTE = "type"; - - public static final String STRUCTURER_HOOK_XPATH_ATTRIBUTE = "hooksXpath"; - - protected String requestedFormat; - - private boolean includeNodes = true; - - /** - * <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> - * - * <p> - * will be transformed to - * </p> - * - * <pre> - * <div id="test"/> - * </pre> - */ - public static final String DISPATCHER_HOOK_ELEMENT = "hook"; - - /** - * <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> - */ - public static final String DISPATCHER_CSS_ELEMENT = "css"; - - private String propertyID; + private String cacheKey, validityFile; - private boolean insideProperties = false; - - /** - * Convenience object, so we don't need to create an AttributesImpl for every - * element. - */ - protected AttributesImpl attributes; + private AggregatedValidity validity; - protected String currentFormat; + private String validityOverride; - 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 [EMAIL PROTECTED] #defaultNamespaceURI} or to the value set by - * the <code>namespaceURI</code> sitemap parameter for the pipeline. Must - * never be null. - */ - protected String namespaceURI; + private DispatcherBean config; /** - * This is the default namespace used by the transformer. Implementations - * should set its value in the constructor. Must never be null. + * basic | enhanced */ - 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 HOOKS_TRANSFORMER_PARAMETER = "hooksTransformer"; + private String xpathSupport; public static final String PATH_PARAMETER = "path"; - static public final String DISPATCHER_REQUEST_ATTRIBUTE = "request"; + public static final String DISPATCHER_REQUEST_ATTRIBUTE = "request"; public static final String CACHE_PARAMETER = "cacheKey"; public static final String VALIDITY_PARAMETER = "validityFile"; - private static final String VALIDITY_OVERRIDE_PARAMETER = "dispatcher.caching"; + public static final String VALIDITY_OVERRIDE_PARAMETER = "dispatcher.caching"; - private static final String CACHING_OFF = "off"; + public static final String CACHING_OFF = "off"; - private static final String CACHING_ON = "on"; - - /** - * Constructor Set the namespace + public static final String CACHING_ON = "on"; + + + /* + * @see org.apache.cocoon.transformation.AbstractSAXTransformer#configure(org.apache.avalon.framework.configuration.Configuration) */ - public DispatcherTransformer() { - this.defaultNamespaceURI = DispatcherHelper.DISPATCHER_NAMESPACE_URI; + public void configure(Configuration configuration) throws ConfigurationException { + config = new DispatcherBean(); + boolean allowXml=configuration.getChild("allowXml").getValueAsBoolean(false); + config.setAllowXmlProperties(allowXml); + String contractUriPrefix = configuration.getChild("contractUriPrefix").getValue("cocoon://resolve.contract"); + config.setContractUriPrefix(contractUriPrefix); + xpathSupport = configuration.getChild("xpathSupport").getValue("basic"); + } + +//we do all the heavy stuff later and only prepare the basics here, + // this enhance the response time while caching. + public void setup(SourceResolver resolver, Map objectModel, String src, + Parameters par) throws ProcessingException, SAXException, IOException { + super.setup(resolver, objectModel, src, par); + + this.requestId = parameters.getParameter(DISPATCHER_REQUEST_ATTRIBUTE, null); + 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."); + this.validityFile = parameters.getParameter(VALIDITY_PARAMETER, null); + this.validityOverride = parameters + .getParameter(VALIDITY_OVERRIDE_PARAMETER, ""); + this.cacheKey += validityOverride; + + if (requestId == null) { + String error = "dispatcherError:\n" + + "You have to set the \"request\" parameter in the sitemap!"; + getLogger().error(error); + throw new ProcessingException(error); + } + this.requestedFormat = parameters.getParameter(Captions.TYPE_ATT, + null); + if (requestedFormat == null) { + String error = "dispatcherError:\n" + + "You have to set the \"type\" parameter in the sitemap!"; + getLogger().error(error); + throw new ProcessingException(error); + } + if (null == m_resolver) + try { + m_resolver = (org.apache.excalibur.source.SourceResolver) manager.lookup(SourceResolver.ROLE); + config.setResolver(new CocoonResolver(m_resolver)); + } catch (ServiceException e) { + throw new ProcessingException(e); + } + + } + public void startDocument() throws SAXException { + super.startDocument(); + startSerializedXMLRecording(null); + } + public void endDocument() + throws SAXException { + super.endDocument(); + String document=null; + try { + document = super.endSerializedXMLRecording(); + } catch (ProcessingException e) { + throw new SAXException(e); + } + Structurer structurer = null; + if(xpathSupport.equals("enhanced")){ + structurer =new XMLStructurerAxiom(config); + }else{ + structurer =new XMLStructurer(config); + } + try { + structurer.execute(new BufferedInputStream(new ByteArrayInputStream(document.getBytes())), requestedFormat); + } catch (DispatcherException e) { + throw new SAXException(e); + } } /** @@ -288,7 +226,6 @@ this.manager = null; } m_resolver = null; - insideProperties = false; super.dispose(); } @@ -296,790 +233,8 @@ * Recycle the component */ public void recycle() { - localRecycle(); this.validity = null; super.recycle(); } - - // we do all the heavy stuff later and only prepare the basics here, - // this enhance the response time while caching. - public void setup(SourceResolver resolver, Map objectModel, String src, - Parameters par) throws ProcessingException, SAXException, IOException { - 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); - 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."); - this.validityFile = parameters.getParameter(VALIDITY_PARAMETER, null); - this.validityOverride = parameters - .getParameter(VALIDITY_OVERRIDE_PARAMETER, ""); - this.cacheKey += validityOverride; - - 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); - 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) - try { - m_resolver = (org.apache.excalibur.source.SourceResolver) manager.lookup(SourceResolver.ROLE); - } catch (ServiceException e) { - throw new ProcessingException(e); - } - - } - - /** - * Cleanup the transformer - */ - 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) { - 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()) { - 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); - } - } 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); - } - } - - /** - * @param name - * @param raw - * @param attr - * @throws DOMException - * @throws SAXException - */ - 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 */ - try { - Node xpathNode; - xpathNode = DOMUtil.getSingleNode(rootNode, path, this.processor); - if (xpathNode == null) - createXpathNode(attr, tempPath); - else - xpathNode.appendChild(currentElement); - } 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); - } - path = tempPath; - } - } - - /** - * @param attr - * @param tempPath - * @throws ProcessingException - * @throws DOMException - */ - 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); - } - - /** - * @param attr - * @param tempPath - * @throws ProcessingException - * @throws DOMException - */ - private Node createXpathNode(String tempPath) throws ProcessingException, - DOMException { - Node xpathNode; - xpathNode = DOMUtil.selectSingleNode(rootNode, tempPath, this.processor); - return xpathNode; - } - - 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); - } - } - - /** - * view type="?" Here we check which format we have in the view. That should - * be extended to matching the requested format - * - * @param attr - * @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); - } - - } else { - path = null; // unset path because we do not process the node - this.includeNodes = false; - this.recording = false; - } - } - - /** - * @param raw - * @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; - } - } - if (getLogger().isDebugEnabled()) { - getLogger().debug("Ending \"" + STRUCTURER_ELEMENT + "\" element: " + raw); - } - } - - /** - * We have found a contract. Now we have to prepare a bean to later add it to - * the output stream in the endElement. - * - * @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); - } - 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 we do not have a nugget add a foo element to the raw data to invoke - * the transformation. - */ - if (!contract.isNugget()) { - Document foo; - try { - foo = dispatcherHelper.createDocument("foo"); - contract.setContractRawData(foo); - } 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; - 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); - } - } - } - } - } 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; - 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 - * @param name - * @param raw - * @param attr - * @throws SAXException - */ - private void propertyProcessingStart(String uri, String name, String raw, - Attributes attr) throws SAXException { - 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; - } - 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); - } - - /** - * @param uri - * @param name - * @param raw - * @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"); - } - 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"); - } - this.builder = null; - } - } else { - if (this.includeNodes) - this.builder.endElement(uri, name, raw); - } - } - - 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(); - } - - public void endCDATA() throws SAXException { - if (this.insideProperties && this.includeNodes) - this.builder.endCDATA(); - else if (!this.insideProperties && this.includeNodes && !this.insideStructurer) - super.lexicalHandler.endCDATA(); - } - - /** 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); - } - } - - /** END SAX ContentHandler handlers * */ - - protected void storePrefixMapping(String prefix, String uri) { - storedPrefixMap.put(prefix, uri); - } - - 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); - } - } - - 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); - } - } - - public javax.xml.transform.Source resolve(String href, String base) - throws TransformerException { - if (getLogger().isDebugEnabled()) { - getLogger().debug( - "resolve(href = " + href + ", base = " + base + "); resolver = " - + m_resolver); - } - - Source xslSource = null; - try { - if (base == null || href.indexOf(":") > 1) { - // Null base - href must be an absolute URL - xslSource = m_resolver.resolveURI(href); - } else if (href.length() == 0) { - // Empty href resolves to base - xslSource = m_resolver.resolveURI(base); - } else { - // is the base a file or a real m_url - if (!base.startsWith("file:")) { - int lastPathElementPos = base.lastIndexOf('/'); - if (lastPathElementPos == -1) { - // this should never occur as the base should - // always be protocol:/.... - return null; // we can't resolve this - } else { - xslSource = m_resolver.resolveURI(base.substring(0, lastPathElementPos) - + "/" + href); - } - } else { - File parent = new File(base.substring(5)); - File parent2 = new File(parent.getParentFile(), href); - xslSource = m_resolver.resolveURI(parent2.toURL().toExternalForm()); - } - } - - InputSource is = getInputSource(xslSource); - - if (getLogger().isDebugEnabled()) { - getLogger().debug( - "xslSource = " + xslSource + ", system id = " + xslSource.getURI()); - } - - return new StreamSource(is.getByteStream(), is.getSystemId()); - } catch (SourceException e) { - if (getLogger().isDebugEnabled()) { - getLogger().debug( - "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); - } - - return null; - } catch (IOException ioe) { - if (getLogger().isDebugEnabled()) { - getLogger() - .debug( - "Failed to resolve " + href + "(base = " + base + "), return null", - ioe); - } - - return null; - } finally { - 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. - * - * @throws IOException - * if I/O error occured. - */ - private static InputSource getInputSource(final Source source) - throws IOException, SourceException { - final InputSource newObject = new InputSource(source.getInputStream()); - newObject.setSystemId(source.getURI()); - return newObject; - } - }