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.modules.input;
018:
019: import java.util.Iterator;
020: import java.util.Map;
021:
022: import org.apache.avalon.framework.configuration.Configuration;
023: import org.apache.avalon.framework.configuration.ConfigurationException;
024:
025: /**
026: * JXPathModule allows to access properties of any object in generic
027: * way. JXPath provides APIs for the traversal of graphs of
028: * JavaBeans, DOM and other types of objects using the XPath
029: * syntax.
030: *
031: * <p><strong>Note:</strong> JXPathMetaModule is based on this class
032: * and duplicates the code since multiple inheritance is not possible.
033: * Please keep both classes in sync.</p>
034: *
035: * <h3>Configuration</h3>
036: * <table>
037: * <tr>
038: * <td><code><lenient>false</lenient></code></td>
039: * <td>When set to true, non-existing attributes return null; when set to false,
040: * an exception is thrown. Default is true.</td>
041: * </tr>
042: * <tr>
043: * <td><code><parameter>foo</parameter></td>
044: * <td>When set overrides attribute name passed to module.</td>
045: * </tr>
046: * <tr>
047: * <td><code><function name="java.lang.String" prefix="str"/></td>
048: * <td>Imports the class "String" as extension class to the JXPathContext using
049: * the prefix "str". Thus "str:length(xpath)" would apply the method "length" to
050: * the string object obtained from the xpath expression. Please note that the class
051: * needs to be fully qualified.</td>
052: * </tr>
053: * <tr>
054: * <td><code><package name="java.util" prefix="util"/></td>
055: * <td>Imports all classes in the package "java.util" as extension classes to the
056: * JXPathContext using the prefix "util". Thus "util:Date.new()" would create a
057: * new java.util.Date object.</td>
058: * </tr>
059: * <tr>
060: * <td><code><namespace uri="uri:foo" prefix="bar"/></td>
061: * <td>Registers the namespace identified by URI <code>uri:foo</code>
062: * with the JXPathContext using the prefix <code>bar</code>. Thus
063: * expressions can query XML with nodes in this namespace using
064: * registered prefix.</td>
065: * </tr>
066: * </table>
067: *
068: * @author <a href="mailto:kpiroumian@apache.org">Konstantin Piroumian</a>
069: * @author <a href="mailto:haul@apache.org">Christian Haul</a>
070: * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
071: * @version $Id: AbstractJXPathModule.java 433543 2006-08-22 06:22:54Z crossley $
072: */
073: public abstract class AbstractJXPathModule extends AbstractInputModule {
074:
075: /**
076: * Contains all globally registered extension classes and
077: * packages. Thus the lookup and loading of globally registered
078: * extensions is done only once.
079: */
080: protected JXPathHelperConfiguration configuration;
081:
082: /**
083: * Overrides attribute name
084: */
085: protected String parameter;
086:
087: /**
088: * Configure component. Preprocess list of packages and functions
089: * to add to JXPath context later.
090: *
091: * @param config a <code>Configuration</code> value
092: * @exception ConfigurationException if an error occurs
093: */
094: public void configure(Configuration config)
095: throws ConfigurationException {
096:
097: this .configuration = JXPathHelper.setup(config);
098: }
099:
100: public Object getAttribute(String name, Configuration modeConf,
101: Map objectModel) throws ConfigurationException {
102:
103: Object contextObj = getContextObject(modeConf, objectModel);
104: if (modeConf != null) {
105: name = modeConf.getChild("parameter").getValue(
106: this .parameter != null ? this .parameter : name);
107: }
108: return JXPathHelper.getAttribute(name, modeConf,
109: this .configuration, contextObj);
110: }
111:
112: public Iterator getAttributeNames(Configuration modeConf,
113: Map objectModel) throws ConfigurationException {
114:
115: Object contextObj = getContextObject(modeConf, objectModel);
116: return JXPathHelper.getAttributeNames(this .configuration,
117: contextObj);
118: }
119:
120: public Object[] getAttributeValues(String name,
121: Configuration modeConf, Map objectModel)
122: throws ConfigurationException {
123:
124: Object contextObj = getContextObject(modeConf, objectModel);
125: if (modeConf != null) {
126: name = modeConf.getChild("parameter").getValue(
127: this .parameter != null ? this .parameter : name);
128: }
129: return JXPathHelper.getAttributeValues(name, modeConf,
130: this .configuration, contextObj);
131: }
132:
133: /**
134: * Returns the object which should be used as JXPath context.
135: * Descendants should override this method to return a specific object
136: * that is requried by the implementing class.
137: * Examples are: request, session and application context objects.
138: */
139: protected abstract Object getContextObject(Configuration modeConf,
140: Map objectModel) throws ConfigurationException;
141: }
|