Source Code Cross Referenced for XPathDirectoryGenerator.java in  » Web-Framework » cocoon » org » apache » cocoon » generation » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Framework » cocoon » org.apache.cocoon.generation 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.cocoon.generation;
018:
019:        import java.io.BufferedReader;
020:        import java.io.File;
021:        import java.io.IOException;
022:        import java.io.InputStreamReader;
023:        import java.util.HashMap;
024:        import java.util.Map;
025:
026:        import org.apache.avalon.framework.logger.Logger;
027:        import org.apache.avalon.framework.parameters.Parameters;
028:        import org.apache.avalon.framework.service.ServiceException;
029:        import org.apache.avalon.framework.service.ServiceManager;
030:        import org.apache.cocoon.ProcessingException;
031:
032:        import org.apache.cocoon.components.source.SourceUtil;
033:
034:        import org.apache.cocoon.environment.SourceResolver;
035:
036:        import org.apache.cocoon.xml.dom.DOMStreamer;
037:
038:        import org.apache.excalibur.source.Source;
039:        import org.apache.excalibur.source.SourceNotFoundException;
040:
041:        import org.apache.excalibur.xml.dom.DOMParser;
042:        import org.apache.excalibur.xml.xpath.PrefixResolver;
043:        import org.apache.excalibur.xml.xpath.XPathProcessor;
044:
045:        import org.apache.regexp.RE;
046:        import org.apache.regexp.RESyntaxException;
047:
048:        import org.w3c.dom.Document;
049:        import org.w3c.dom.NodeList;
050:
051:        import org.xml.sax.SAXException;
052:
053:        import org.xml.sax.helpers.AttributesImpl;
054:
055:        /**
056:         * @cocoon.sitemap.component.documentation
057:         * Generates an XML directory listing performing XPath queries on XML files. It can be used both as a plain
058:         * DirectoryGenerator or, by specifying a parameter <code>xpath</code>, it will perform an XPath query on every XML
059:         * resource. 
060:         * 
061:         * @cocoon.sitemap.component.name   xpathdirectory
062:         * @cocoon.sitemap.component.label  content
063:         * @cocoon.sitemap.component.documentation.caching
064:         *               Uses the last modification date of the directory and the contained documents
065:         * @cocoon.sitemap.component.logger sitemap.generator.xpathdirectory
066:         * 
067:         * 
068:         * <p>
069:         * Generates an XML directory listing performing XPath queries on XML files. It can be used both as a plain
070:         * DirectoryGenerator or, by specifying a parameter <code>xpath</code>, it will perform an XPath query on every XML
071:         * resource. A <code>nsmapping</code> parameter can be specified to point to a file containing lines to map prefixes
072:         * to namespaces like this:
073:         * </p>
074:         * 
075:         * <p>
076:         * prefix=namespace-uri<br/> prefix2=namespace-uri-2
077:         * </p>
078:         * 
079:         * <p>
080:         * A parameter <code>nsmapping-reload</code> specifies if the prefix-2-namespace mapping file should be checked to be
081:         * reloaded on each request to this generator if it was modified since the last time it was read.
082:         * </p>
083:         * 
084:         * <p>
085:         * An additional parameter <code>xmlFiles</code> can be set in the sitemap setting the regular expression pattern for
086:         * determining if a file should be handled as XML file or not. The default value for this param is
087:         * <code>\.xml$</code>, so that it  matches all files ending <code>.xml</code>.
088:         * </p>
089:         * 
090:         * <p></p>
091:         * <br>Sample usage: <br><br>Sitemap:
092:         * <pre>
093:         *  &lt;map:match pattern="documents/**"&gt; 
094:         *   &lt;map:generate type="xpathdirectory" src="docs/{1}"&gt; 
095:         *    &lt;map:parameter name="xpath" value="/article/title|/article/abstract"/&gt; 
096:         *    &lt;map:parameter name="nsmapping" value="mapping.properties"/&gt; 
097:         *    &lt;map:parameter name="nsmapping-reload" value="false"/&gt; 
098:         *    &lt;map:parameter name="xmlFiles" value="\.xml$"/&gt; 
099:         *   &lt;/map:generate&gt; 
100:         *   &lt;map:serialize type="xml" /&gt; 
101:         *  &lt;/map:match&gt;
102:         * </pre>
103:         * 
104:         * <p>
105:         * Request: <br>http://www.some.host/documents/test
106:         * </p>
107:         * Result:
108:         * <pre>
109:         *  &lt;dir:directory name="test" lastModified="1010400942000" date="1/7/02 11:55 AM" requested="true" xmlns:dir="http://apache.org/cocoon/directory/2.0"&gt; 
110:         *   &lt;dir:directory name="subdirectory" lastModified="1010400942000" date="1/7/02 11:55 AM"/&gt; 
111:         *   &lt;dir:file name="test.xml" lastModified="1011011579000" date="1/14/02 1:32 PM"&gt; 
112:         *    &lt;dir:xpath query="/article/title"&gt; 
113:         *     &lt;title&gt;This is a test document&lt;/title&gt; 
114:         *      &lt;abstract&gt; 
115:         *       &lt;para&gt;Abstract of my test article&lt;/para&gt; 
116:         *      &lt;/abstract&gt; 
117:         *     &lt;/dir:xpath&gt; 
118:         *    &lt;/dir:file&gt; 
119:         *   &lt;dir:file name="test.gif" lastModified="1011011579000" date="1/14/02 1:32 PM"/&gt; 
120:         *  &lt;/dir:directory&gt;
121:         * </pre>
122:         *
123:         * @author <a href="mailto:giacomo@apache.org">Giacomo Pati</a>
124:         * @author <a href="mailto:gianugo@apache.org">Gianugo Rabellino</a>
125:         * @author <a href="mailto:joerg@apache.org">J\u00F6rg Heinicke</a>
126:         * @version CVS $Id: XPathDirectoryGenerator.java 433543 2006-08-22 06:22:54Z crossley $
127:         */
128:        public class XPathDirectoryGenerator extends DirectoryGenerator {
129:            /** Local name for the element that contains the included XML snippet. */
130:            protected static final String XPATH_NODE_NAME = "xpath";
131:
132:            /** Attribute for the XPath query. */
133:            protected static final String QUERY_ATTR_NAME = "query";
134:
135:            /** All the mapping files lastmodified dates */
136:            protected static final Map mappingFiles = new HashMap();
137:
138:            /** The parser for the XML snippets to be included. */
139:            protected DOMParser parser = null;
140:
141:            /** The document that should be parsed and (partly) included. */
142:            protected Document doc = null;
143:
144:            /** The PrefixResolver responsable for processing current request (if any). */
145:            protected PrefixResolver prefixResolver = null;
146:
147:            /** The regular expression for the XML files pattern. */
148:            protected RE xmlRE = null;
149:
150:            /** The XPath. */
151:            protected String xpath = null;
152:
153:            /** The XPath processor. */
154:            protected XPathProcessor processor = null;
155:
156:            /**
157:             * Disposable
158:             */
159:            public void dispose() {
160:                if (this .manager != null) {
161:                    this .manager.release(this .processor);
162:                    this .manager.release(this .parser);
163:                    this .processor = null;
164:                    this .parser = null;
165:                }
166:
167:                super .dispose();
168:            }
169:
170:            /**
171:             * Recycle resources
172:             */
173:            public void recycle() {
174:                this .xpath = null;
175:                this .doc = null;
176:
177:                //this.parser = null;
178:                //this.processor = null;
179:                super .recycle();
180:            }
181:
182:            /**
183:             * Serviceable
184:             *
185:             * @param manager the ComponentManager
186:             *
187:             * @throws ServiceException in case a component could not be found
188:             */
189:            public void service(ServiceManager manager) throws ServiceException {
190:                super .service(manager);
191:                this .processor = (XPathProcessor) manager
192:                        .lookup(XPathProcessor.ROLE);
193:                this .parser = (DOMParser) manager.lookup(DOMParser.ROLE);
194:            }
195:
196:            /**
197:             * Setup this sitemap component
198:             *
199:             * @param resolver the SourceResolver
200:             * @param objectModel The environmental object model
201:             * @param src the source attribute
202:             * @param par the parameters
203:             *
204:             * @throws ProcessingException if processing failes
205:             * @throws SAXException in case of XML related errors
206:             * @throws IOException in case of file related errors
207:             */
208:            public void setup(SourceResolver resolver, Map objectModel,
209:                    String src, Parameters par) throws ProcessingException,
210:                    SAXException, IOException {
211:                super .setup(resolver, objectModel, src, par);
212:
213:                // See if an XPath was specified
214:                this .xpath = par.getParameter("xpath", null);
215:                this .cacheKeyParList.add(this .xpath);
216:
217:                if (getLogger().isDebugEnabled()) {
218:                    getLogger().debug(
219:                            "Applying XPath: " + this .xpath + " to directory "
220:                                    + this .source);
221:                }
222:
223:                final String mappings = par.getParameter("nsmapping", null);
224:
225:                if (null != mappings) {
226:                    final boolean mapping_reload = par.getParameterAsBoolean(
227:                            "nsmapping-reload", false);
228:                    final Source mappingSource = resolver.resolveURI(mappings);
229:                    final String mappingKey = mappingSource.getURI();
230:                    final MappingInfo mappingInfo = (MappingInfo) XPathDirectoryGenerator.mappingFiles
231:                            .get(mappingKey);
232:
233:                    if ((null == mappingInfo)
234:                            || (mappingInfo.reload == false)
235:                            || (mappingInfo.mappingSource.getLastModified() < mappingSource
236:                                    .getLastModified())) {
237:                        this .prefixResolver = new MappingInfo(getLogger()
238:                                .getChildLogger("prefix-resolver"),
239:                                mappingSource, mapping_reload);
240:                        XPathDirectoryGenerator.mappingFiles.put(mappingKey,
241:                                this .prefixResolver);
242:                    } else {
243:                        this .prefixResolver = mappingInfo;
244:                    }
245:                }
246:
247:                String xmlFilesPattern = null;
248:
249:                try {
250:                    xmlFilesPattern = par.getParameter("xmlFiles", "\\.xml$");
251:                    this .cacheKeyParList.add(xmlFilesPattern);
252:                    this .xmlRE = new RE(xmlFilesPattern);
253:
254:                    if (getLogger().isDebugEnabled()) {
255:                        getLogger().debug(
256:                                "pattern for XML files: " + xmlFilesPattern);
257:                    }
258:                } catch (RESyntaxException rese) {
259:                    throw new ProcessingException(
260:                            "Syntax error in regexp pattern '"
261:                                    + xmlFilesPattern + "'", rese);
262:                }
263:            }
264:
265:            /**
266:             * Determines if a given File shall be handled as XML.
267:             *
268:             * @param path the File to check
269:             *
270:             * @return true if the given File shall handled as XML, false otherwise.
271:             */
272:            protected boolean isXML(File path) {
273:                return this .xmlRE.match(path.getName());
274:            }
275:
276:            /**
277:             * Performs an XPath query on the file.
278:             *
279:             * @param xmlFile the File the XPath is performed on.
280:             *
281:             * @throws SAXException if something goes wrong while adding the XML snippet.
282:             */
283:            protected void performXPathQuery(File xmlFile) throws SAXException {
284:                this .doc = null;
285:
286:                Source source = null;
287:
288:                try {
289:                    source = resolver.resolveURI(xmlFile.toURL()
290:                            .toExternalForm());
291:                    this .doc = this .parser.parseDocument(SourceUtil
292:                            .getInputSource(source));
293:                } catch (SAXException e) {
294:                    getLogger().error(
295:                            "Warning:" + xmlFile.getName()
296:                                    + " is not a valid XML file. Ignoring.", e);
297:                } catch (ProcessingException e) {
298:                    getLogger().error(
299:                            "Warning: Problem while reading the file "
300:                                    + xmlFile.getName() + ". Ignoring.", e);
301:                } catch (IOException e) {
302:                    getLogger().error(
303:                            "Warning: Problem while reading the file "
304:                                    + xmlFile.getName() + ". Ignoring.", e);
305:                } finally {
306:                    resolver.release(source);
307:                }
308:
309:                if (doc != null) {
310:                    NodeList nl = (null == this .prefixResolver) ? this .processor
311:                            .selectNodeList(this .doc.getDocumentElement(),
312:                                    this .xpath)
313:                            : this .processor.selectNodeList(this .doc
314:                                    .getDocumentElement(), this .xpath,
315:                                    this .prefixResolver);
316:                    AttributesImpl attributes = new AttributesImpl();
317:                    attributes.addAttribute("", QUERY_ATTR_NAME,
318:                            QUERY_ATTR_NAME, "CDATA", xpath);
319:                    super .contentHandler.startElement(URI, XPATH_NODE_NAME,
320:                            PREFIX + ":" + XPATH_NODE_NAME, attributes);
321:
322:                    DOMStreamer ds = new DOMStreamer(super .xmlConsumer);
323:
324:                    for (int i = 0; i < nl.getLength(); i++) {
325:                        ds.stream(nl.item(i));
326:                    }
327:
328:                    super .contentHandler.endElement(URI, XPATH_NODE_NAME,
329:                            PREFIX + ":" + XPATH_NODE_NAME);
330:                }
331:            }
332:
333:            /**
334:             * Extends the startNode() method of the DirectoryGenerator by starting a possible XPath query on a file.
335:             *
336:             * @param nodeName the node currently processing
337:             * @param path the file path
338:             *
339:             * @throws SAXException in case of errors
340:             */
341:            protected void startNode(String nodeName, File path)
342:                    throws SAXException {
343:                super .startNode(nodeName, path);
344:
345:                if ((this .xpath != null) && path.isFile() && this .isXML(path)) {
346:                    performXPathQuery(path);
347:                }
348:            }
349:
350:            /**
351:             * The MappingInfo class to resolve namespace prefixes to their namespace URI
352:             *
353:             * @author <a href="mailto:giacomo(at)apache.org">Giacomo Pati</a>
354:             * @version CVS $Id: XPathDirectoryGenerator.java 433543 2006-08-22 06:22:54Z crossley $
355:             */
356:            private static class MappingInfo implements  PrefixResolver {
357:                /** The Source of the mapping file */
358:                public final Source mappingSource;
359:
360:                /** Whether to reload if mapping file has changed */
361:                public final boolean reload;
362:
363:                /** Our Logger */
364:                private final Logger logger;
365:
366:                /** Map of prefixes to namespaces */
367:                private final Map prefixMap;
368:
369:                /**
370:                 * Creates a new MappingInfo object.
371:                 *
372:                 * @param logger DOCUMENT ME!
373:                 * @param mappingSource The Source of the mapping file
374:                 * @param reload Whether to reload if mapping file has changed
375:                 *
376:                 * @throws SourceNotFoundException In case the mentioned source is not there
377:                 * @throws IOException in case the source could not be read
378:                 */
379:                public MappingInfo(final Logger logger,
380:                        final Source mappingSource, final boolean reload)
381:                        throws SourceNotFoundException, IOException {
382:                    this .logger = logger;
383:                    this .mappingSource = mappingSource;
384:                    this .reload = reload;
385:                    prefixMap = new HashMap();
386:                    InputStreamReader input = null;
387:                    BufferedReader br = null;
388:
389:                    try {
390:                        input = new InputStreamReader(mappingSource
391:                                .getInputStream());
392:                        br = new BufferedReader(input);
393:
394:                        for (String line = br.readLine(); line != null; line = br
395:                                .readLine()) {
396:                            final int i = line.indexOf('=');
397:
398:                            if (i > 0) {
399:                                final String prefix = line.substring(0, i);
400:                                final String namespace = line.substring(i + 1);
401:                                prefixMap.put(prefix, namespace);
402:                                logger.debug("added mapping: '" + prefix
403:                                        + "'='" + namespace + "'");
404:                            }
405:                        }
406:                    } finally {
407:                        if (br != null) {
408:                            br.close();
409:                        }
410:                        if (input != null) {
411:                            input.close();
412:                        }
413:                    }
414:                }
415:
416:                /* (non-Javadoc)
417:                 * @see org.apache.excalibur.xml.xpath.PrefixResolver#prefixToNamespace(java.lang.String)
418:                 */
419:                public String prefixToNamespace(String prefix) {
420:                    final String namespace = (String) this .prefixMap
421:                            .get(prefix);
422:
423:                    if (logger.isDebugEnabled()) {
424:                        logger.debug("have to resolve prefix='" + prefix
425:                                + ", found namespace='" + namespace + "'");
426:                    }
427:
428:                    return namespace;
429:                }
430:            }
431:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.