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.components.source.impl;
018:
019: import java.io.IOException;
020:
021: import org.apache.avalon.framework.logger.AbstractLogEnabled;
022: import org.apache.avalon.framework.parameters.ParameterException;
023: import org.apache.avalon.framework.parameters.Parameterizable;
024: import org.apache.avalon.framework.parameters.Parameters;
025: import org.apache.avalon.framework.service.ServiceException;
026: import org.apache.avalon.framework.service.ServiceManager;
027: import org.apache.avalon.framework.service.Serviceable;
028: import org.apache.avalon.framework.thread.ThreadSafe;
029: import org.apache.cocoon.components.source.SourceInspector;
030: import org.apache.cocoon.components.source.helpers.SourceProperty;
031: import org.apache.excalibur.source.Source;
032: import org.apache.excalibur.source.SourceException;
033: import org.apache.excalibur.source.SourceValidity;
034: import org.apache.excalibur.source.impl.validity.NOPValidity;
035: import org.apache.excalibur.xml.dom.DOMParser;
036: import org.apache.excalibur.xml.xpath.XPathProcessor;
037: import org.w3c.dom.Document;
038: import org.w3c.dom.NodeList;
039: import org.xml.sax.InputSource;
040: import org.xml.sax.SAXException;
041:
042: /**
043: * This source inspector inspects XML files with a xpath expression.
044: *
045: * @version $Id: XPathSourceInspector.java 433543 2006-08-22 06:22:54Z crossley $
046: */
047: public class XPathSourceInspector extends AbstractLogEnabled implements
048: SourceInspector, Serviceable, Parameterizable, ThreadSafe {
049:
050: /**
051: * The default namespace uri of the property exposed by this SourceInspector.
052: * <p>
053: * The value is <code>http://apache.org/cocoon/inspector/xpath/1.0</code>.
054: * </p>
055: */
056: public static final String DEFAULT_PROPERTY_NS = "http://apache.org/cocoon/inspector/xpath/1.0";
057:
058: /**
059: * The default property name exposed by this SourceInspector.
060: * <p>
061: * The value is <code>result</code> .
062: * </p>
063: */
064: public static final String DEFAULT_PROPERTY_NAME = "result";
065:
066: private String m_namespace;
067: private String m_propertyname;
068: private String m_extension;
069: private String m_xpath;
070:
071: private ServiceManager manager;
072:
073: public XPathSourceInspector() {
074: }
075:
076: public void service(ServiceManager manager) {
077: this .manager = manager;
078: }
079:
080: public void parameterize(Parameters params)
081: throws ParameterException {
082: this .m_namespace = params.getParameter("namespace",
083: DEFAULT_PROPERTY_NS);
084: this .m_propertyname = params.getParameter("name",
085: DEFAULT_PROPERTY_NAME);
086: this .m_extension = params.getParameter("extension", ".xml");
087: this .m_xpath = params.getParameter("xpath", "/*");
088: }
089:
090: public SourceProperty getSourceProperty(Source source,
091: String namespace, String name) throws SourceException {
092:
093: if ((namespace.equals(m_namespace))
094: && (name.equals(m_propertyname))
095: && (source.getURI().endsWith(m_extension))) {
096:
097: DOMParser parser = null;
098: Document doc = null;
099: try {
100: parser = (DOMParser) manager.lookup(DOMParser.ROLE);
101: InputSource is = new InputSource(source
102: .getInputStream());
103: is.setSystemId(source.getURI());
104: doc = parser.parseDocument(is);
105: } catch (SAXException se) {
106: getLogger().error(
107: source.getURI() + " is not a valid XML file");
108: } catch (IOException ioe) {
109: getLogger().error("Could not read file", ioe);
110: } catch (ServiceException ce) {
111: getLogger().error(
112: "Missing service dependency: DOMParser", ce);
113: } finally {
114: if (parser != null) {
115: this .manager.release(parser);
116: }
117: }
118:
119: if (doc != null) {
120: XPathProcessor processor = null;
121: try {
122: processor = (XPathProcessor) manager
123: .lookup(XPathProcessor.ROLE);
124: NodeList nodelist = processor.selectNodeList(doc
125: .getDocumentElement(), m_xpath);
126: SourceProperty property = new SourceProperty(
127: m_namespace, m_propertyname);
128: property.setValue(nodelist);
129: return property;
130: } catch (ServiceException se) {
131: this .getLogger().error(
132: "Could not retrieve component", se);
133: } finally {
134: if (processor != null) {
135: this .manager.release(processor);
136: }
137: }
138: }
139: }
140: return null;
141: }
142:
143: public SourceProperty[] getSourceProperties(Source source)
144: throws SourceException {
145: SourceProperty property = getSourceProperty(source,
146: this .m_namespace, this .m_propertyname);
147: if (property != null)
148: return new SourceProperty[] { property };
149: return null;
150: }
151:
152: public boolean handlesProperty(String namespace, String name) {
153: return this .m_namespace.equals(namespace)
154: && this .m_propertyname.equals(name);
155: }
156:
157: /**
158: * Returns NOPValidity
159: */
160: public SourceValidity getValidity(Source source) {
161: return NOPValidity.SHARED_INSTANCE;
162: }
163:
164: }
|