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: import java.util.TreeMap;
022:
023: import org.apache.avalon.framework.configuration.Configuration;
024: import org.apache.avalon.framework.configuration.ConfigurationException;
025: import org.apache.avalon.framework.thread.ThreadSafe;
026:
027: /**
028: *
029: * <h2>Configuration</h2>
030: * <table><tbody>
031: * <tr><th>input-module</th>
032: * <td>Configuration and name of input module used for the selection.</td>
033: * <td>req</td>
034: * <td>String</td><td><code>null</code></td>
035: * </tr>
036: * <tr><th>when</th>
037: * <td>Selection case, condition in test attribute, input module name
038: * in name attribute. Optional configuration as nested content.</td>
039: * <td>req</td><td>String</td><td><code>null</code></td>
040: * </tr>
041: * <tr><th>otherwise</th>
042: * <td>Default selection case. If not present and no case matches, <code>null</code>
043: * is returned.</td>
044: * <td></td><td>String</td><td><code>null</code></td>
045: * </tr>
046: * </tbody></table>
047: *
048: * @author <a href="mailto:haul@apache.org">Christian Haul</a>
049: * @version $Id: SelectMetaInputModule.java 433543 2006-08-22 06:22:54Z crossley $
050: */
051: public class SelectMetaInputModule extends AbstractMetaModule implements
052: ThreadSafe {
053:
054: private Map whenTest = null;
055: private ModuleHolder expression = null;
056: private ModuleHolder otherwise = null;
057: private String parameter = null;
058:
059: public SelectMetaInputModule() {
060: super ();
061: this .defaultInput = null; // not needed
062: }
063:
064: /* (non-Javadoc)
065: * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
066: */
067: public void configure(Configuration config)
068: throws ConfigurationException {
069:
070: Configuration[] expr = config.getChildren("input-module");
071: if (expr == null || expr.length != 1) {
072: throw new ConfigurationException(
073: "Need to have exactly one input-module element.");
074: }
075: this .parameter = config.getChild("parameter").getValue();
076: Configuration[] whens = config.getChildren("when");
077: Configuration[] others = config.getChildren("otherwise");
078: if ((whens == null && others == null)
079: || ((whens == null || whens.length == 0) && (others == null || others.length == 0))) {
080: throw new ConfigurationException(
081: "Need to have at least one when or otherwise element.");
082: }
083: if (others != null && others.length > 1) {
084: throw new ConfigurationException(
085: "Need to have at most one otherwise element.");
086: }
087: this .whenTest = new TreeMap();
088: for (int i = 0; i < expr.length; i++) {
089: String name = expr[i].getAttribute("name");
090: this .expression = new ModuleHolder(name, expr[i], null);
091: }
092:
093: if (others != null) {
094: for (int i = 0; i < others.length; i++) {
095: String name = others[i].getAttribute("name");
096: this .otherwise = new ModuleHolder(name, others[i], null);
097: }
098: }
099:
100: if (whens != null) {
101: for (int i = 0; i < whens.length; i++) {
102: String name = whens[i].getAttribute("name");
103: this .whenTest.put(whens[i].getAttribute("test"),
104: new ModuleHolder(name, whens[i], null));
105: }
106: }
107: }
108:
109: /* (non-Javadoc)
110: * @see org.apache.cocoon.components.modules.input.InputModule#getAttribute(String, Configuration, Map)
111: */
112: public Object getAttribute(String name, Configuration modeConf,
113: Map objectModel) throws ConfigurationException {
114: Object result = this .getAttribute(name, modeConf, objectModel,
115: false);
116: return result;
117: }
118:
119: public Object[] getAttributeValues(String name,
120: Configuration modeConf, Map objectModel)
121: throws ConfigurationException {
122: Object result = this .getAttribute(name, modeConf, objectModel,
123: true);
124: return (result != null ? (Object[]) result : null);
125: }
126:
127: private Object getAttribute(String name, Configuration modeConf,
128: Map objectModel, boolean getValues)
129: throws ConfigurationException {
130: if (!this .initialized) {
131: this .lazy_initialize();
132: }
133: ModuleHolder expression = this .expression;
134: ModuleHolder otherwise = this .otherwise;
135: ModuleHolder module = null;
136: String parameter = this .parameter;
137: boolean needRelease = false;
138: boolean dynamicConfig = (modeConf != null && modeConf
139: .getChildren().length > 0);
140:
141: if (dynamicConfig) {
142: // clear all configured values so that they
143: // don't get mixed up
144: expression = null;
145: otherwise = null;
146: needRelease = true;
147:
148: Configuration[] expr = modeConf.getChildren("input-module");
149: Configuration[] other = modeConf.getChildren("otherwise");
150: if (expr != null && expr.length == 1) {
151: expression = new ModuleHolder(expr[0]
152: .getAttribute("name"), expr[0]);
153: }
154: if (other != null && other.length == 1) {
155: otherwise = new ModuleHolder(other[0]
156: .getAttribute("name"), other[0]);
157: }
158: parameter = modeConf.getChild("parameter").getValue();
159: }
160:
161: String value = (String) this .getValue(parameter, objectModel,
162: expression.input, expression.name, expression.config);
163: if (needRelease) {
164: this .releaseModule(expression.input);
165: }
166: if (this .getLogger().isDebugEnabled()) {
167: this .getLogger().debug(
168: (dynamicConfig ? "(dyn)" : "(static)")
169: + " select (" + value + ") from "
170: + expression.name + ":" + parameter);
171: }
172:
173: if (dynamicConfig && value != null) {
174: Configuration[] whens = modeConf.getChildren("when");
175: if (whens != null && whens.length > 0) {
176: int i = 0;
177: boolean found = false;
178: while (!found && i < whens.length) {
179: if (whens[i].getAttribute("test").equals(value)) {
180: found = true;
181: break;
182: }
183: i++;
184: }
185: if (found) {
186: module = new ModuleHolder(whens[i]
187: .getAttribute("name"), whens[i]);
188: }
189: }
190: } else if (value != null) {
191: module = (ModuleHolder) this .whenTest.get(value);
192: }
193: if (module != null) {
194: if (this .getLogger().isDebugEnabled()) {
195: this .getLogger().debug(
196: "found matching when : " + module.name);
197: }
198: } else {
199: module = otherwise;
200: if (this .getLogger().isDebugEnabled()) {
201: this .getLogger().debug(
202: "using otherwise : " + module.name);
203: }
204: }
205:
206: Object result;
207: if (getValues) {
208: result = (module == null ? null : this .getValues(name,
209: objectModel, module));
210: } else {
211: result = (module == null ? null : this .getValue(name,
212: objectModel, module));
213: }
214:
215: if (needRelease && module != null) {
216: this .releaseModule(module.input);
217: }
218: if (this .getLogger().isDebugEnabled()) {
219: this .getLogger().debug("Obtained value : " + result);
220: }
221: return result;
222: }
223:
224: /* (non-Javadoc)
225: * @see org.apache.avalon.framework.activity.Disposable#dispose()
226: */
227: public void dispose() {
228: this .releaseModule(this .expression.input);
229: this .expression = null;
230:
231: if (this .otherwise != null) {
232: this .releaseModule(this .otherwise.input);
233: this .otherwise = null;
234: }
235:
236: for (Iterator i = this .whenTest.values().iterator(); i
237: .hasNext();) {
238: ModuleHolder holder = (ModuleHolder) i.next();
239: this .releaseModule(holder.input);
240: }
241: this .whenTest = null;
242:
243: super .dispose();
244: }
245:
246: /* (non-Javadoc)
247: * @see org.apache.cocoon.components.modules.input.AbstractMetaModule#lazy_initialize()
248: */
249: public synchronized void lazy_initialize() {
250: if (this .initialized) {
251: return;
252: }
253: super .lazy_initialize();
254:
255: if (this .expression != null) {
256: this .expression.input = this
257: .obtainModule(this .expression.name);
258: }
259: if (this .otherwise != null) {
260: this .otherwise.input = this
261: .obtainModule(this .otherwise.name);
262: }
263: if (this .whenTest != null) {
264: for (Iterator i = this .whenTest.values().iterator(); i
265: .hasNext();) {
266: ModuleHolder moduleHolder = (ModuleHolder) i.next();
267: moduleHolder.input = this
268: .obtainModule(moduleHolder.name);
269: }
270: }
271: }
272: }
|