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]