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: import org.apache.avalon.framework.thread.ThreadSafe;
022:
023: import org.apache.cocoon.util.JDBCTypeConversions;
024:
025: import java.util.ArrayList;
026: import java.util.Map;
027: import java.util.Iterator;
028: import java.util.SortedSet;
029: import java.util.TreeSet;
030:
031: /**
032: * Constructs an array of values suitable for a JDBC collection type
033: * from parameters obtained from another input module. Application is
034: * not limited to JDBC collections but can be used wherever similar
035: * named attributes shall be collected to an array of a given
036: * type. Currently, long, int, and string are known, more to come.
037: *
038: * <p><b>Global and local configuration</b></p>
039: * <table border="1">
040: * <tr><td><code>input-module</code></td><td>Name of the input module used to obtain the value and its configuration</td></tr>
041: * <tr><td><code>member</code></td> <td>Collection member <table
042: * <tr><td>Attribute</td><td></td></tr>
043: * <tr><td>name</td><td>Parameter name, "*" may distinguish multiple collections</td></tr>
044: * <tr><td>type</td><td>JDBC type name of members</td></tr>
045: * </table> </td></tr>
046: * </table>
047: *
048: * @author <a href="mailto:haul@apache.org">Christian Haul</a>
049: * @version CVS $Id: CollectionMetaModule.java 433543 2006-08-22 06:22:54Z crossley $
050: */
051: public class CollectionMetaModule extends AbstractMetaModule implements
052: ThreadSafe {
053:
054: protected Configuration memberConf = null;
055:
056: public void configure(Configuration config)
057: throws ConfigurationException {
058:
059: this .memberConf = config.getChild("member");
060: this .inputConf = config.getChild("input-module");
061: this .defaultInput = this .inputConf.getAttribute("name",
062: this .defaultInput);
063: }
064:
065: public Object getAttribute(String name, Configuration modeConf,
066: Map objectModel) throws ConfigurationException {
067:
068: if (!this .initialized) {
069: this .lazy_initialize();
070: }
071: if (this .defaultInput == null) {
072: if (getLogger().isWarnEnabled())
073: getLogger().warn("No input module given. FAILING");
074: return null;
075: }
076:
077: // obtain correct configuration objects
078: // default vs dynamic
079: Configuration mConf = this .memberConf;
080: Configuration inputConfig = null;
081: String inputName = null;
082: if (modeConf != null) {
083: mConf = modeConf.getChild("member");
084: inputName = modeConf.getChild("input-module").getAttribute(
085: "name", null);
086: if (inputName != null) {
087: inputConfig = modeConf.getChild("input-module");
088: }
089: }
090:
091: // read necessary parameters
092: // name is used only if parameter name contains '*'
093: // in that case it replaces '*' otherwise it is
094: // ignored
095: String jType = mConf.getAttribute("type", "string");
096: String pName = mConf.getAttribute("name");
097: int index = pName.indexOf("*");
098: if (index > -1) {
099: String prefix = (index > 0 ? pName.substring(0, index)
100: : null);
101: String suffix = (index < (pName.length() - 1) ? pName
102: .substring(index + 1, pName.length()) : null);
103: pName = prefix + name + suffix;
104: }
105:
106: getLogger().debug("jType " + jType);
107:
108: Object[] values = getValues(pName, objectModel, this .input,
109: this .defaultInput, this .inputConf, null, inputName,
110: inputConfig);
111: Object[] objects = null;
112:
113: if (values != null) {
114:
115: objects = new Object[values.length];
116:
117: for (int i = 0; i < values.length; i++) {
118: Object value = values[i];
119: objects[i] = JDBCTypeConversions.convert(value, jType);
120: }
121: }
122:
123: return objects;
124: }
125:
126: public Iterator getAttributeNames(Configuration modeConf,
127: Map objectModel) throws ConfigurationException {
128:
129: if (!this .initialized) {
130: this .lazy_initialize();
131: }
132: if (this .defaultInput == null) {
133: if (getLogger().isWarnEnabled())
134: getLogger().warn("No input module given. FAILING");
135: return null;
136: }
137:
138: // obtain correct configuration objects
139: // default vs dynamic
140:
141: Configuration mConf = this .memberConf;
142: Configuration inputConfig = null;
143: String inputName = null;
144: if (modeConf != null) {
145: mConf = modeConf.getChild("member");
146: inputName = modeConf.getChild("input-module").getAttribute(
147: "name", null);
148: if (inputName != null) {
149: inputConfig = modeConf.getChild("input-module");
150: }
151: }
152:
153: Iterator names = getNames(objectModel, this .input,
154: this .defaultInput, this .inputConf, null, inputName,
155: inputConfig);
156:
157: if (names != null) {
158: SortedSet matchset = new TreeSet();
159: String pName = mConf.getAttribute("name");
160: int index = pName.indexOf("*");
161:
162: if (index > -1) {
163: // parameter name contains '*'
164: // find all strings that match this '*'
165: // return them in an enumeration
166:
167: String prefix = (index > 0 ? pName.substring(0, index)
168: : null);
169: String suffix = (index < (pName.length() - 1) ? pName
170: .substring(index + 1, pName.length()) : null);
171:
172: while (names.hasNext()) {
173: String name = (String) names.next();
174: if (name.startsWith(prefix)
175: && name.endsWith(suffix)) {
176: String wildcard = name.substring(prefix
177: .length());
178: wildcard = wildcard.substring(0, wildcard
179: .length()
180: - suffix.length());
181: matchset.add(wildcard);
182: }
183: }
184: } else {
185: // parameter name without wildcard
186: // check that name is among available names
187: // and return it in that case
188: boolean done = false;
189: while (!done && names.hasNext()) {
190: String name = (String) names.next();
191: if (name.equals(pName)) {
192: matchset.add(pName);
193: done = true;
194: }
195: }
196: }
197: return matchset.iterator();
198: } else {
199: return null;
200: }
201: }
202:
203: public Object[] getAttributeValues(String name,
204: Configuration modeConf, Map objectModel)
205: throws ConfigurationException {
206:
207: Iterator names = this .getAttributeNames(modeConf, objectModel);
208: ArrayList values = new ArrayList();
209: while (names.hasNext()) {
210: values.add(this .getAttribute((String) names.next(),
211: modeConf, objectModel));
212: }
213:
214: return values.toArray();
215:
216: }
217: }
|