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 java.util.HashMap;
024: import java.util.HashSet;
025: import java.util.Iterator;
026: import java.util.Map;
027: import java.util.Set;
028:
029: /** Meta module that obtains values from an other module and by
030: * replacing the requested attribute name with another name. This is
031: * done first through a replacement table and may additionally prepend
032: * or append a string. Replacement works in both ways, it is applied
033: * to the returned attribute names as well.
034: *
035: * <p>Example configuration:<pre>
036: * <prefix>cocoon.</prefix>
037: * <suffix>.attr</suffix>
038: * <mapping in="foo" out="bar"/>
039: * <mapping in="yuk" out="yeeha"/>
040: *</pre>
041: *
042: * Will map a parameter "foo" to the real one named
043: * "cocoon.bar.attr". If parameters "coocoon.yeeha.attr" and
044: * "shopping.cart" exist, the iterator will return
045: * "yeeha". "shopping.cart" does not contain the pre-/ suffix and thus
046: * is dropped.</p>
047: *
048: * <p>Similarily, rm-prefix and rm-suffix will be removed from the
049: * attribute name.</p>
050: *
051: * @author <a href="mailto:haul@apache.org">Christian Haul</a>
052: * @version $Id: SimpleMappingMetaModule.java 433543 2006-08-22 06:22:54Z crossley $
053: */
054: public class SimpleMappingMetaModule extends AbstractMetaModule
055: implements ThreadSafe {
056:
057: String prefix = null;
058: String suffix = null;
059: String rmPrefix = null;
060: String rmSuffix = null;
061: Mapping mapping = null;
062:
063: protected static class Mapping {
064: Map toMap = null;
065: Map fromMap = null;
066:
067: public Mapping() {
068: }
069:
070: public Mapping(Map to, Map from) {
071: this .toMap = to;
072: this .fromMap = from;
073: }
074:
075: public Mapping(Configuration config)
076: throws ConfigurationException {
077: Configuration[] mappings = config.getChildren("mapping");
078: if (mappings != null) {
079: if (this .toMap == null)
080: this .toMap = new HashMap();
081: if (this .fromMap == null)
082: this .fromMap = new HashMap();
083: for (int i = 0; i < mappings.length; i++) {
084: String in = mappings[i].getAttribute("in", null);
085: String out = mappings[i].getAttribute("out", null);
086: if (in != null && out != null) {
087: this .toMap.put(in, out);
088: this .fromMap.put(out, in);
089: }
090: }
091: }
092: }
093:
094: private String mapIt(Map map, String param) {
095: Object newParam = param;
096: if (map != null) {
097: newParam = map.get(param);
098: if (!map.containsKey(param) || newParam == null)
099: newParam = param;
100: }
101: return (String) newParam;
102: }
103:
104: public String mapFrom(String param) {
105: return this .mapIt(this .fromMap, param);
106: }
107:
108: public String mapTo(String param) {
109: return this .mapIt(this .toMap, param);
110: }
111: }
112:
113: public void configure(Configuration config)
114: throws ConfigurationException {
115:
116: // It seems that even if there is no config, we'll get an empty
117: // input-module element here, so it will never be null (JT)
118: this .inputConf = config.getChild("input-module");
119: this .defaultInput = this .inputConf.getAttribute("name",
120: this .defaultInput);
121: this .prefix = config.getChild("prefix").getValue(null);
122: this .suffix = config.getChild("suffix").getValue(null);
123: this .rmPrefix = config.getChild("rm-prefix").getValue(null);
124: this .rmSuffix = config.getChild("rm-suffix").getValue(null);
125: this .mapping = new Mapping(config);
126: }
127:
128: public Object getAttribute(String name, Configuration modeConf,
129: Map objectModel) throws ConfigurationException {
130:
131: if (!this .initialized) {
132: this .lazy_initialize();
133: }
134: if (this .defaultInput == null) {
135: if (getLogger().isWarnEnabled())
136: getLogger().warn("No input module given. FAILING");
137: return null;
138: }
139:
140: Configuration inputConfig = null;
141: String inputName = null;
142: Mapping mapping = this .mapping;
143: String prefix = this .prefix;
144: String suffix = this .suffix;
145: String rmPrefix = this .rmPrefix;
146: String rmSuffix = this .rmSuffix;
147:
148: if (modeConf != null && modeConf.getChildren().length > 0) {
149: inputName = modeConf.getChild("input-module").getAttribute(
150: "name", null);
151: if (inputName != null) {
152: inputConfig = modeConf.getChild("input-module");
153: }
154: mapping = new Mapping(modeConf);
155: prefix = modeConf.getChild("prefix").getValue(null);
156: suffix = modeConf.getChild("suffix").getValue(null);
157: rmPrefix = modeConf.getChild("rm-prefix").getValue(null);
158: rmSuffix = modeConf.getChild("rm-suffix").getValue(null);
159: }
160:
161: // remove rm-prefix and rm-suffix
162: if (rmPrefix != null && name.startsWith(rmPrefix)) {
163: name = name.substring(rmPrefix.length());
164: }
165: if (rmSuffix != null && name.endsWith(rmSuffix)) {
166: name = name.substring(0, name.length() - rmSuffix.length());
167: }
168: // map
169: String param = mapping.mapTo(name);
170: // add prefix and suffix
171: if (prefix != null)
172: param = prefix + param;
173: if (suffix != null)
174: param = param + suffix;
175: if (getLogger().isDebugEnabled())
176: getLogger().debug(
177: "mapping ['" + name + "'] to ['" + param + "']");
178:
179: Object res = getValue(param, objectModel, this .input,
180: this .defaultInput, this .inputConf, null, inputName,
181: inputConfig);
182:
183: if (getLogger().isDebugEnabled())
184: getLogger().debug(
185: "getting for real attribute ['" + param
186: + "'] value: " + res);
187:
188: return res;
189: }
190:
191: public Object[] getAttributeValues(String name,
192: Configuration modeConf, Map objectModel)
193: throws ConfigurationException {
194:
195: if (!this .initialized) {
196: this .lazy_initialize();
197: }
198: if (this .defaultInput == null) {
199: if (getLogger().isWarnEnabled())
200: getLogger().warn("No input module given. FAILING");
201: return null;
202: }
203:
204: Configuration inputConfig = null;
205: String inputName = null;
206: Mapping mapping = this .mapping;
207: String prefix = this .prefix;
208: String suffix = this .suffix;
209: String rmPrefix = this .rmPrefix;
210: String rmSuffix = this .rmSuffix;
211:
212: if (modeConf != null && modeConf.getChildren().length > 0) {
213: inputName = modeConf.getChild("input-module").getAttribute(
214: "name", null);
215: if (inputName != null) {
216: inputConfig = modeConf.getChild("input-module");
217: }
218: mapping = new Mapping(modeConf);
219: prefix = modeConf.getChild("prefix").getValue(null);
220: suffix = modeConf.getChild("suffix").getValue(null);
221: rmPrefix = modeConf.getChild("rm-prefix").getValue(null);
222: rmSuffix = modeConf.getChild("rm-suffix").getValue(null);
223: }
224:
225: // remove rm-prefix and rm-suffix
226: if (rmPrefix != null && name.startsWith(rmPrefix)) {
227: name = name.substring(rmPrefix.length());
228: }
229: if (rmSuffix != null && name.endsWith(rmSuffix)) {
230: name = name.substring(0, name.length() - rmSuffix.length());
231: }
232: // map
233: String param = mapping.mapTo(name);
234: // add prefix and suffix
235: if (prefix != null)
236: param = prefix + param;
237: if (suffix != null)
238: param = param + suffix;
239: if (getLogger().isDebugEnabled())
240: getLogger().debug(
241: "mapping ['" + name + "'] to ['" + param + "']");
242:
243: Object[] res = getValues(param, objectModel, this .input,
244: this .defaultInput, this .inputConf, null, inputName,
245: inputConfig);
246: if (getLogger().isDebugEnabled())
247: getLogger().debug(
248: "getting for real attribute ['" + param
249: + "'] value: " + res);
250:
251: return res;
252: }
253:
254: public Iterator getAttributeNames(Configuration modeConf,
255: Map objectModel) throws ConfigurationException {
256:
257: if (!this .initialized) {
258: this .lazy_initialize();
259: }
260: if (this .defaultInput == null) {
261: if (getLogger().isWarnEnabled())
262: getLogger().warn("No input module given. FAILING");
263: return null;
264: }
265:
266: Configuration inputConfig = null;
267: String inputName = null;
268: Mapping mapping = this .mapping;
269: String prefix = this .prefix;
270: String suffix = this .suffix;
271: String rmPrefix = this .rmPrefix;
272: String rmSuffix = this .rmSuffix;
273: if (modeConf != null && modeConf.getChildren().length > 0) {
274: inputName = modeConf.getChild("input-module").getAttribute(
275: "name", null);
276: if (inputName != null) {
277: inputConfig = modeConf.getChild("input-module");
278: }
279: mapping = new Mapping(modeConf);
280: prefix = modeConf.getChild("prefix").getValue(null);
281: suffix = modeConf.getChild("suffix").getValue(null);
282: rmPrefix = modeConf.getChild("rm-prefix").getValue(null);
283: rmSuffix = modeConf.getChild("rm-suffix").getValue(null);
284: }
285:
286: Iterator names = getNames(objectModel, this .input,
287: this .defaultInput, this .inputConf, null, inputName,
288: inputConfig);
289:
290: Set set = new HashSet();
291: while (names.hasNext()) {
292: String param = (String) names.next();
293: if (getLogger().isDebugEnabled())
294: getLogger()
295: .debug(
296: "reverse mapping starts with ['"
297: + param + "']");
298: if (prefix != null)
299: if (param.startsWith(prefix))
300: param = param.substring(prefix.length());
301: else
302: continue; // prefix is set but parameter does not start with it.
303:
304: //if (getLogger().isDebugEnabled())
305: // getLogger().debug("reverse mapping after remove prefix ['"+param+"']");
306:
307: if (suffix != null)
308: if (param.endsWith(suffix))
309: param = param.substring(0, param.length()
310: - suffix.length());
311: else
312: continue; // suffix is set but parameter does not end with it.
313:
314: //if (getLogger().isDebugEnabled())
315: // getLogger().debug("reverse mapping after remove suffix ['"+param+"']");
316:
317: if (param.length() < 1)
318: continue; // nothing left
319:
320: String newName = mapping.mapFrom(param);
321:
322: if (rmPrefix != null)
323: newName = rmPrefix + newName;
324: if (rmSuffix != null)
325: newName = newName + rmSuffix;
326:
327: if (getLogger().isDebugEnabled())
328: getLogger().debug(
329: "reverse mapping results in ['" + newName
330: + "']");
331:
332: set.add(newName);
333: }
334:
335: return set.iterator();
336:
337: }
338:
339: }
|