Author: reinhard Date: Sun Nov 14 09:12:03 2004 New Revision: 65607 Added: cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/XPatchLogger.java cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/ cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/DocumentCache.java cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/NullPropertyResolver.java cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/PropertyResolver.java cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/XPatch.java cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/XPatchLoggerFacade.java cocoon/whiteboard/block-deployer/test/junit/org/apache/cocoon/blockdeployer/utils/xpatch/ cocoon/whiteboard/block-deployer/test/junit/org/apache/cocoon/blockdeployer/utils/xpatch/XPatchTest.java cocoon/whiteboard/block-deployer/test/xpatch/ cocoon/whiteboard/block-deployer/test/xpatch/zip-source.xconf cocoon/whiteboard/block-deployer/test/xpatch/zip-source_cocoon.xconf Log: Refactoring of XPatch to make it independant of Ant
Added: cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/XPatchLogger.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/XPatchLogger.java Sun Nov 14 09:12:03 2004 @@ -0,0 +1,44 @@ +/* + * Copyright 2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cocoon.blockdeployer.utils; + +import org.apache.cocoon.blockdeployer.logging.LoggerFacade; +import org.apache.cocoon.blockdeployer.utils.xpatch.XPatchLoggerFacade; + +/** + * @since 0.1 + */ +public class XPatchLogger implements XPatchLoggerFacade { + + private LoggerFacade logger; + + public XPatchLogger(LoggerFacade logger) { + this.logger = logger; + } + + public void error(Class clazz, String error) { + this.logger.error(clazz, error); + } + + public void info(Class clazz, String info) { + this.logger.info(clazz, info); + } + + public void debug(Class clazz, String debug) { + this.logger.debug(clazz, debug); + } + +} Added: cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/DocumentCache.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/DocumentCache.java Sun Nov 14 09:12:03 2004 @@ -0,0 +1,145 @@ +/* + * Copyright 2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cocoon.blockdeployer.utils.xpatch; + +import java.io.File; +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.cocoon.blockdeployer.logging.LoggerFacade; +import org.w3c.dom.Document; +import org.w3c.dom.DocumentType; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * @since 0.1 + */ +public final class DocumentCache { + + /** Cache the read configuration files (Documents) */ + private static Map fileCache = new HashMap(); + + /** The document builder */ + private static DocumentBuilder builder; + private static Transformer transformer; + + /** + * Initialize internal instance of XMLCatalog + */ + static { + try { + DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); + builderFactory.setValidating(false); + builderFactory.setExpandEntityReferences(false); + builderFactory.setNamespaceAware(false); + builderFactory.setAttribute( + "http://apache.org/xml/features/nonvalidating/load-external-dtd", + Boolean.FALSE); + builder = builderFactory.newDocumentBuilder(); + transformer = TransformerFactory.newInstance().newTransformer(); + } catch (TransformerException e) { + throw new RuntimeException("TransformerException: "+e); + } catch (ParserConfigurationException e) { + throw new RuntimeException("ParserConfigurationException: "+e); + } + } + + public static Document getDocument(File file, XPatchLoggerFacade logger) + throws SAXException, IOException { + if(logger == null) { + throw new NullPointerException("Logger is null"); + } + final String fileName = file.toURL().toExternalForm(); + Document document = (Document)fileCache.get(fileName); + if ( document != null ) { + logger.debug(DocumentCache.class, "Using file from cache: " + fileName); + fileCache.remove(fileName); + } else { + try { + // load xml + logger.debug(DocumentCache.class, "Reading: " + fileName); + document = builder.parse(fileName); + } catch (IOException e) { + throw new RuntimeException("IOException: "+e); + } + } + return document; + } + + public static Document getDocument(String string, String systemURI) { + try { + final InputSource is = new InputSource(new StringReader(string)); + if ( systemURI != null ) { + is.setSystemId(systemURI); + } + return builder.parse(is); + } catch (Exception e) { + throw new RuntimeException("Unable to parse string.", e); + } + } + + public static void storeDocument(File file, Document document, LoggerFacade logger) + throws IOException { + if(logger==null) { + throw new NullPointerException("Logger is null."); + } + logger.debug(DocumentCache.class, "Storing file in cache: " + file); + final String fileName = file.toURL().toExternalForm(); + fileCache.put(fileName, document); + } + + public static void writeDocument(File file, Document document, LoggerFacade logger) { + if(logger == null) { + throw new NullPointerException("Logger is null."); + } + logger.debug(DocumentCache.class, "Writing: " + file); + + // Set the DOCTYPE output option on the transformer + // if we have any DOCTYPE declaration in the input xml document + final DocumentType doctype = document.getDoctype(); + Properties props = new Properties(); + if (null != doctype) { + if (null != doctype.getPublicId()) { + props.put(OutputKeys.DOCTYPE_PUBLIC, doctype.getPublicId()); + } + if (null != doctype.getSystemId()) { + props.put(OutputKeys.DOCTYPE_SYSTEM, doctype.getSystemId()); + } + } + transformer.setOutputProperties(props); + + try { + transformer.transform(new DOMSource(document), + new StreamResult(file)); + } catch (TransformerException e) { + throw new RuntimeException("TransformerException: " + e); + } + } +} Added: cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/NullPropertyResolver.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/NullPropertyResolver.java Sun Nov 14 09:12:03 2004 @@ -0,0 +1,31 @@ +/* + * Copyright 2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cocoon.blockdeployer.utils.xpatch; + +/** + * @since 0.1 + */ +public class NullPropertyResolver implements PropertyResolver { + + public String replaceProperties(String property) { + return property; + } + + public String getProperty(String ifProp) { + return ""; + } + +} Added: cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/PropertyResolver.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/PropertyResolver.java Sun Nov 14 09:12:03 2004 @@ -0,0 +1,27 @@ +/* + * Copyright 2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cocoon.blockdeployer.utils.xpatch; + +/** + * @since 0.1 + */ +public interface PropertyResolver { + + public String replaceProperties(String property); + + public String getProperty(String ifProp); + +} Added: cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/XPatch.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/XPatch.java Sun Nov 14 09:12:03 2004 @@ -0,0 +1,312 @@ +/* + * Copyright 2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cocoon.blockdeployer.utils.xpatch; + +import java.io.File; +import java.io.IOException; + +import javax.xml.transform.TransformerException; + +import org.apache.xpath.XPathAPI; +import org.w3c.dom.Attr; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + + +/** + * Patch Cocoon XML configuration files (.xconf, .xmap, ...) + * + * Refactoring of + * @since 0.1 + */ +public class XPatch { + private boolean addComments = true; + private static final String NL = System.getProperty("line.separator"); + private static final String FSEP = System.getProperty("file.separator"); + private PropertyResolver propertyResolver; + private XPatchLoggerFacade logger; + private String startCommentText = null; + private String endCommentText = null; + + /* + * FIXME change LoggerFacade to XPatchLogger to make it easier to use in Cocoon 2.1 + */ + public XPatch(PropertyResolver propertyResolver, XPatchLoggerFacade logger) { + if(logger == null) { + throw new NullPointerException("Logger mustn't be null."); + } + this.logger = logger; + if(propertyResolver == null) { + throw new NullPointerException("PropertyResolver mustn't be null."); + } + this.propertyResolver = propertyResolver; + } + + public void setAddComments(Boolean addComments) { + this.addComments = addComments.booleanValue(); + } + + public void setStartCommentText(String text) { + this.startCommentText = text; + } + + public void setEndCommentText(String text) { + this.endCommentText = text; + } + + public String getStartCommentText(String confName) { + String defaultText = "..... Start configuration from '" + confName + "'"; + if(this.startCommentText == null) { + return defaultText; + } + return defaultText + "\n" + this.startCommentText; + } + + public String getEndCommentText(String confName) { + String defaultText = "..... End configuration from '" + confName + "'"; + if(this.endCommentText == null) { + return defaultText; + } + return defaultText + "\n" + this.endCommentText; + } + + public boolean patch(final Document configuration, final File patchFile) + throws TransformerException, IOException, DOMException, + SAXException { + + // FIXME should be refactored and set externally (this object shouldn't know about where the documents are cached) + Document component = DocumentCache.getDocument(patchFile, this.logger); + String filename = patchFile.toString(); + + // Check to see if Document is an xconf-tool document + Element elem = component.getDocumentElement(); + + String extension = filename.lastIndexOf(".") > 0 ? filename + .substring(filename.lastIndexOf(".") + 1) : ""; + String basename = basename(filename); + + if (!elem.getTagName().equals(extension)) { + this.logger.info(XPatch.class, "Skipping non xconf-tool file: " + filename); + return false; + } + + String replacePropertiesStr = elem.getAttribute("replace-properties"); + + boolean replaceProperties = !("no" + .equalsIgnoreCase(replacePropertiesStr) || "false" + .equalsIgnoreCase(replacePropertiesStr)); + + // Get 'root' node were 'component' will be inserted into + String xpath = getAttribute(elem, "xpath", replaceProperties); + + NodeList nodes = XPathAPI.selectNodeList(configuration, xpath); + + // Suspend, because the xpath returned not one node + if (nodes.getLength() != 1) { + this.logger.debug(XPatch.class, "Suspending: " + filename); + return false; + } + Node root = nodes.item(0); + + // Test that 'root' node satisfies 'component' insertion criteria + String testPath = getAttribute(elem, "unless-path", replaceProperties); + if (testPath == null || testPath.length() == 0) { + // only look for old "unless" attr if unless-path is not present + testPath = getAttribute(elem, "unless", replaceProperties); + } + // Is if-path needed? + String ifProp = getAttribute(elem, "if-prop", replaceProperties); + boolean ifValue = false; + + if (ifProp != null && !ifProp.equals("")) { + ifValue = Boolean.valueOf(this.propertyResolver.getProperty(ifProp)) + .booleanValue(); + } + + if (ifProp != null && ifProp.length() > 0 && !ifValue) { + this.logger.debug(XPatch.class, "Skipping: " + filename); + return false; + } else if (testPath != null && testPath.length() > 0 + && XPathAPI.selectNodeList(root, testPath).getLength() != 0) { + this.logger.debug(XPatch.class, "Skipping: " + filename); + return false; + } else { + // Test if component wants us to remove a list of nodes first + xpath = getAttribute(elem, "remove", replaceProperties); + + if (xpath != null && xpath.length() > 0) { + nodes = XPathAPI.selectNodeList(configuration, xpath); + + for (int i = 0, length = nodes.getLength(); i < length; i++) { + Node node = nodes.item(i); + Node parent = node.getParentNode(); + + parent.removeChild(node); + } + } + + // Test for an attribute that needs to be added to an element + String name = getAttribute(elem, "add-attribute", replaceProperties); + String value = getAttribute(elem, "value", replaceProperties); + + if (name != null && name.length() > 0) { + if (value == null) { + throw new IOException( + "No attribute value specified for 'add-attribute' " + + xpath); + } + if (root instanceof Element) { + ((Element) root).setAttribute(name, value); + } + } + + // Override addComments from ant task if specified as an attribute + String addCommentsAttr = getAttribute(elem, "add-comments", + replaceProperties); + if ((addCommentsAttr != null) && (addCommentsAttr.length() > 0)) { + setAddComments(new Boolean(addCommentsAttr)); + } + + // Allow multiple attributes to be added or modified + if (root instanceof Element) { + NamedNodeMap attrMap = elem.getAttributes(); + for (int i = 0; i < attrMap.getLength(); ++i) { + Attr attr = (Attr) attrMap.item(i); + final String addAttr = "add-attribute-"; + if (attr.getName().startsWith(addAttr)) { + String key = attr.getName().substring(addAttr.length()); + ((Element) root).setAttribute(key, attr.getValue()); + } + } + } + + // Test if 'component' provides desired insertion point + xpath = getAttribute(elem, "insert-before", replaceProperties); + Node before = null; + + if (xpath != null && xpath.length() > 0) { + nodes = XPathAPI.selectNodeList(root, xpath); + if (nodes.getLength() == 0) { + this.logger.error(XPatch.class, "Error in: " + filename); + throw new IOException("XPath (" + xpath + + ") returned zero nodes"); + } + before = nodes.item(0); + } else { + xpath = getAttribute(elem, "insert-after", replaceProperties); + if (xpath != null && xpath.length() > 0) { + nodes = XPathAPI.selectNodeList(root, xpath); + if (nodes.getLength() == 0) { + this.logger.error(XPatch.class, "Error in: " + filename); + throw new IOException("XPath (" + xpath + + ") zero nodes."); + } + before = nodes.item(nodes.getLength() - 1).getNextSibling(); + } + } + + // Add 'component' data into 'root' node + this.logger.debug(XPatch.class, "Processing: " + filename); + NodeList componentNodes = component.getDocumentElement() + .getChildNodes(); + + if (this.addComments) { + root.appendChild(configuration.createComment(this.getStartCommentText(basename))); + root.appendChild(configuration.createTextNode(NL)); + } + for (int i = 0; i < componentNodes.getLength(); i++) { + Node node = configuration.importNode(componentNodes.item(i), + true); + + // FIXME + // if (replaceProperties) { + // replaceProperties(node); + // } + if (before == null) { + root.appendChild(node); + } else { + root.insertBefore(node, before); + } + } + if (this.addComments) { + root.appendChild(configuration.createComment(this.getEndCommentText(basename))); + root.appendChild(configuration.createTextNode(NL)); + } + return true; + } + } + + private String getAttribute(Element elem, String attrName, + boolean replaceProperties) { + String attr = elem.getAttribute(attrName); + if (attr == null) { + return null; + } else if (replaceProperties) { + return this.propertyResolver.replaceProperties(attr); + } + else { + return attr; + } + } + + private void replaceProperties(Node n) throws DOMException { + NamedNodeMap attrs = n.getAttributes(); + if (attrs != null) { + for (int i = 0; i < attrs.getLength(); i++) { + Node attr = attrs.item(i); + attr.setNodeValue(this.propertyResolver.replaceProperties( + attr.getNodeValue())); + } + } + switch (n.getNodeType()) { + case Node.ATTRIBUTE_NODE: + case Node.CDATA_SECTION_NODE: + case Node.TEXT_NODE: { + n.setNodeValue(this.propertyResolver.replaceProperties(n.getNodeValue())); + break; + } + case Node.DOCUMENT_NODE: + case Node.DOCUMENT_FRAGMENT_NODE: + case Node.ELEMENT_NODE: { + Node child = n.getFirstChild(); + while (child != null) { + replaceProperties(child); + child = child.getNextSibling(); + } + break; + } + default: { + // ignore all other node types + } + } + } + + private String basename(String fileName) { + int start = fileName.lastIndexOf(FSEP) + 1; // last '/' + int end = fileName.lastIndexOf("."); // last '.' + + if (end == 0) { + end = fileName.length(); + } + return fileName.substring(start, end); + } + +} \ No newline at end of file Added: cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/XPatchLoggerFacade.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/block-deployer/src/impl/org/apache/cocoon/blockdeployer/utils/xpatch/XPatchLoggerFacade.java Sun Nov 14 09:12:03 2004 @@ -0,0 +1,29 @@ +/* + * Copyright 2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cocoon.blockdeployer.utils.xpatch; + +/** + * @since 0.1 + */ +public interface XPatchLoggerFacade { + + public void error(Class clazz, String error); + + public void info(Class clazz, String info); + + public void debug(Class clazz, String debug); + +} Added: cocoon/whiteboard/block-deployer/test/junit/org/apache/cocoon/blockdeployer/utils/xpatch/XPatchTest.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/block-deployer/test/junit/org/apache/cocoon/blockdeployer/utils/xpatch/XPatchTest.java Sun Nov 14 09:12:03 2004 @@ -0,0 +1,66 @@ +/* + * Copyright 2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cocoon.blockdeployer.utils.xpatch; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.apache.cocoon.blockdeployer.LogEnabledTestCase; +import org.apache.cocoon.blockdeployer.utils.XPatchLogger; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.XMLSerializer; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +/** + * @since 0.1 + */ +public class XPatchTest extends LogEnabledTestCase { + + public void testXConfPatching() throws DOMException, TransformerException, IOException, SAXException, ParserConfigurationException { + XPatch xpatch = new XPatch(new NullPropertyResolver(), new XPatchLogger(this.logger)); + + File confFile = new File("./test/xpatch/zip-source_cocoon.xconf"); + File patchFile = new File("./test/xpatch/zip-source.xconf"); + + DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); + builderFactory.setValidating(false); + builderFactory.setExpandEntityReferences(false); + builderFactory.setNamespaceAware(false); + + DocumentBuilder builder = builderFactory.newDocumentBuilder(); + Document doc = builder.parse(confFile); + xpatch.patch(doc, patchFile); + + FileOutputStream fos = new FileOutputStream(new File("rpo.xml")); + OutputFormat of = new OutputFormat("XML","UTF-8",true); + of.setIndent(1); + of.setIndenting(true); + XMLSerializer serializer = new XMLSerializer(fos,of); + + serializer.asDOMSerializer(); + serializer.serialize( doc.getDocumentElement() ); + fos.close(); + } + +} Added: cocoon/whiteboard/block-deployer/test/xpatch/zip-source.xconf ============================================================================== --- (empty file) +++ cocoon/whiteboard/block-deployer/test/xpatch/zip-source.xconf Sun Nov 14 09:12:03 2004 @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- + Copyright 1999-2004 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<xconf xpath="/cocoon/source-factories" unless="[EMAIL PROTECTED]'zip']"> + + <!-- zip pseudo protocol --> + <component-instance class="org.apache.cocoon.components.source.impl.ZipSourceFactory" name="zip"/> + +</xconf> Added: cocoon/whiteboard/block-deployer/test/xpatch/zip-source_cocoon.xconf ============================================================================== --- (empty file) +++ cocoon/whiteboard/block-deployer/test/xpatch/zip-source_cocoon.xconf Sun Nov 14 09:12:03 2004 @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<!-- + Copyright 1999-2004 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<cocoon> + <source-factories/> +</cocoon> \ No newline at end of file