gianugo 02/02/03 08:50:35 Added: src/scratchpad/src/org/apache/cocoon/generation XPathDirectoryGenerator.java Log: Added the new XPath enabled DirectoryGenerator to the scratchpad Revision Changes Path 1.1 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/generation/XPathDirectoryGenerator.java Index: XPathDirectoryGenerator.java =================================================================== /***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.cocoon.generation; import org.apache.avalon.excalibur.pool.Recyclable; import org.apache.avalon.framework.component.ComponentManager; import org.apache.avalon.framework.component.Composable; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.excalibur.xml.xpath.XPathProcessor; import org.apache.cocoon.ProcessingException; import org.apache.cocoon.ResourceNotFoundException; import org.apache.cocoon.components.parser.Parser; import org.apache.cocoon.environment.Source; import org.apache.cocoon.environment.SourceResolver; import org.apache.cocoon.xml.dom.DOMStreamer; import org.apache.regexp.RE; import org.apache.regexp.RESyntaxException; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; import java.io.File; import java.io.IOException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import java.util.Stack; /** * Generates an XML directory listing performing XPath queries * on XML files. It can be used both as a plain DirectoryGenerator * or, using an "xpointerinsh" syntax it will perform an XPath * query on every XML resource. * * Sample usage: * * Sitemap: * <map:match pattern="documents/**"> * <map:generate type="xpathdirectory" * src="docs/{1}#/article/title|/article/abstract" /> * <map:serialize type="xml" /> * </map:match> * * Request: * http://www.some.host/documents/test * Result: * <dir:directory * name="test" lastModified="1010400942000" * date="1/7/02 11:55 AM" requested="true" * xmlns:dir="http://apache.org/cocoon/directory/2.0"> * <dir:directory name="subdirectory" lastModified="1010400942000" date="1/7/02 11:55 AM" /> * <dir:file name="test.xml" lastModified="1011011579000" date="1/14/02 1:32 PM"> * <dir:xpath docid="test.xml" query="/article/title"> * <title>This is a test document</title> * <abstract> * <para>Abstract of my test article</para> * </abstract> * </dir:xpath> * </dir:file> * <dir:file name="test.gif" lastModified="1011011579000" date="1/14/02 1:32 PM"> * </dir:directory> * * @author <a href="mailto:[EMAIL PROTECTED]">Gianugo Rabellino</a> * @version CVS $Id: XPathDirectoryGenerator.java,v 1.1 2002/02/03 16:50:35 gianugo Exp $ */ public class XPathDirectoryGenerator extends DirectoryGenerator { /** Element <result> */ protected static final String RESULT = "xpath"; protected static final String QRESULT = PREFIX + ":" + RESULT; protected static final String RESULT_DOCID_ATTR = "docid"; protected static final String QUERY_ATTR = "query"; protected static final String CDATA = "CDATA"; protected String XPathQuery = null; protected XPathProcessor processor = null; protected Parser parser; protected Document doc; public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException { super.setup(resolver, objectModel, src, par); // See if an XPath was specified int pointer; if ((pointer = this.source.indexOf("#")) != -1) { this.XPathQuery = source.substring(pointer + 1); this.source = source.substring(0, pointer); if (this.getLogger().isDebugEnabled()) this.getLogger().debug("Applying XPath: " + XPathQuery + " to directory " + source); } } public void compose(ComponentManager manager) { try { super.compose(manager); processor = (XPathProcessor)manager.lookup(XPathProcessor.ROLE); parser = (Parser)manager.lookup(Parser.ROLE); } catch (Exception e) { this.getLogger().error("Could not obtain a required component", e); } } /** * Adds a single node to the generated document. If the path is a * directory, and depth is greater than zero, then recursive calls * are made to add nodes for the directory's children. Moreover, * if the file is an XML file (ends with .xml), the XPath query * is performed and results returned. * * @param path * the file/directory to process * @param depth * how deep to scan the directory * * @throws SAXException * if an error occurs while constructing nodes */ protected void addPath(File path, int depth) throws SAXException { if (path.isDirectory()) { startNode(DIR_NODE_NAME, path); if (depth>0) { File contents[] = path.listFiles(); for (int i=0; i<contents.length; i++) { if (isIncluded(contents[i]) && !isExcluded(contents[i])) { addPath(contents[i], depth-1); } } } endNode(DIR_NODE_NAME); } else { if (isIncluded(path) && !isExcluded(path)) { startNode(FILE_NODE_NAME, path); if (path.getName().endsWith(".xml") && XPathQuery != null) performXPathQuery(path); endNode(FILE_NODE_NAME); } } } protected void performXPathQuery(File in) throws SAXException { doc = null; try { doc = parser.parseDocument( resolver.resolve(in.toURL().toExternalForm()).getInputSource()); } catch (SAXException se) { this.getLogger().error("Warning:" + in.getName() + " is not a valid XML file. Ignoring"); } catch (Exception e) { this.getLogger().error("Unable to resolve and parse file" + e); } if (doc != null) { NodeList nl = processor.selectNodeList(doc.getDocumentElement(), XPathQuery); final String id = in.getName(); AttributesImpl attributes = new AttributesImpl(); attributes.addAttribute("", RESULT_DOCID_ATTR, RESULT_DOCID_ATTR, CDATA, id); attributes.addAttribute("", QUERY_ATTR, QUERY_ATTR, CDATA, XPathQuery); super.contentHandler.startElement(URI, RESULT, QRESULT, attributes); DOMStreamer ds = new DOMStreamer(super.xmlConsumer); for (int i = 0; i < nl.getLength(); i++) ds.stream(nl.item(i)); super.contentHandler.endElement(URI, RESULT, QRESULT); } } /** * Recycle resources * */ public void recycle() { super.recycle(); this.XPathQuery = null; this.attributes = null; this.doc = null; } }
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]