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 org.apache.avalon.framework.configuration.Configuration;
020: import org.apache.avalon.framework.configuration.ConfigurationException;
021:
022: import org.apache.commons.jxpath.JXPathBeanInfo;
023: import org.apache.commons.jxpath.JXPathContext;
024: import org.apache.commons.jxpath.JXPathIntrospector;
025:
026: import java.util.Iterator;
027: import java.util.LinkedList;
028: import java.util.List;
029: import java.util.Map;
030:
031: /**
032: * @author <a href="mailto:haul@apache.org">Christian Haul</a>
033: * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
034: * @version $Id: JXPathHelper.java 575808 2007-09-14 22:40:40Z gkossakowski $
035: */
036: public class JXPathHelper {
037:
038: private JXPathHelper() {
039: // no instances allowed
040: }
041:
042: /**
043: * Configure component. Preprocess list of packages, functions
044: * and namespaces to add to the JXPath context later.
045: *
046: * This method used in both AbstractJXPathModule and JXPathMetaModule
047: * to configure JXPath.
048: *
049: * @param config a <code>Configuration</code> value
050: * @exception ConfigurationException if an error occurs
051: */
052: public static JXPathHelperConfiguration setup(Configuration config)
053: throws ConfigurationException {
054:
055: return new JXPathHelperConfiguration(config);
056: }
057:
058: /**
059: * Actually add global functions and packages as well as those
060: * listed in the configuration object.
061: *
062: * @param context a <code>JXPathContext</code> value
063: * @param conf a <code>Configuration</code> value holding local
064: * packages and functions.
065: */
066: private static void setup(JXPathHelperConfiguration setup,
067: JXPathContext context, Configuration conf)
068: throws ConfigurationException {
069:
070: // Create local config (if necessary)
071: JXPathHelperConfiguration local = conf == null ? setup
072: : new JXPathHelperConfiguration(setup, conf);
073:
074: // Setup context with local config
075: context.setLenient(setup.isLenient());
076: context.setFunctions(local.getLibrary());
077: if (local.getNamespaces() != null) {
078: for (Iterator i = local.getNamespaces().entrySet()
079: .iterator(); i.hasNext();) {
080: final Map.Entry entry = (Map.Entry) i.next();
081: context.registerNamespace((String) entry.getKey(),
082: (String) entry.getValue());
083: }
084: }
085: }
086:
087: public static Object getAttribute(String name,
088: Configuration modeConf, JXPathHelperConfiguration setup,
089: Object contextObj) throws ConfigurationException {
090:
091: if (contextObj == null) {
092: return null;
093: }
094:
095: try {
096: JXPathContext jxContext = JXPathContext
097: .newContext(contextObj);
098: setup(setup, jxContext, modeConf);
099:
100: return jxContext.selectSingleNode(name);
101: } catch (Exception e) {
102: throw new ConfigurationException(
103: "Module does not support <" + name + ">"
104: + "attribute.", e);
105: }
106: }
107:
108: public static Object[] getAttributeValues(String name,
109: Configuration modeConf, JXPathHelperConfiguration setup,
110: Object contextObj) throws ConfigurationException {
111:
112: if (contextObj == null) {
113: return null;
114: }
115:
116: try {
117: JXPathContext jxContext = JXPathContext
118: .newContext(contextObj);
119: setup(setup, jxContext, modeConf);
120:
121: List values = null;
122: Iterator i = jxContext.iterate(name);
123: if (i.hasNext()) {
124: values = new LinkedList();
125: }
126: while (i.hasNext()) {
127: values.add(i.next());
128: }
129: Object[] obj = null;
130: if (values != null) {
131: obj = values.toArray();
132: if (obj.length == 0) {
133: obj = null;
134: }
135: }
136: return obj;
137: } catch (Exception e) {
138: throw new ConfigurationException(
139: "Module does not support <" + name + ">"
140: + "attribute.", e);
141: }
142: }
143:
144: public static Iterator getAttributeNames(
145: JXPathHelperConfiguration setup, Object contextObj)
146: throws ConfigurationException {
147:
148: if (contextObj == null) {
149: return null;
150: }
151:
152: try {
153: JXPathBeanInfo info = JXPathIntrospector
154: .getBeanInfo(contextObj.getClass());
155: java.beans.PropertyDescriptor[] properties = info
156: .getPropertyDescriptors();
157:
158: List names = new LinkedList();
159: for (int i = 0; i < properties.length; i++) {
160: names.add(properties[i].getName());
161: }
162:
163: return names.listIterator();
164: } catch (Exception e) {
165: throw new ConfigurationException(
166: "Error retrieving attribute names for class: "
167: + contextObj.getClass(), e);
168: }
169: }
170: }
|