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.CascadingRuntimeException;
020: import org.apache.avalon.framework.component.ComponentManager;
021: import org.apache.avalon.framework.component.ComponentSelector;
022: import org.apache.avalon.framework.configuration.Configuration;
023: import org.apache.avalon.framework.service.ServiceManager;
024: import org.apache.avalon.framework.service.ServiceSelector;
025:
026: import java.util.HashMap;
027: import java.util.Iterator;
028: import java.util.Map;
029:
030: /**
031: * @author <a href="mailto:haul@apache.org">Christian Haul</a>
032: * @version $Id: InputModuleHelper.java 433543 2006-08-22 06:22:54Z crossley $
033: */
034: public class InputModuleHelper {
035:
036: // TODO consolidate code with AbstractMetaModule to use this class as delegate
037:
038: protected final static String INPUT_MODULE_SELECTOR = InputModule.ROLE
039: + "Selector";
040:
041: /* Operation codes */
042: private final static int OP_GET = 0;
043: private final static int OP_VALUES = 1;
044: private final static int OP_NAMES = 2;
045:
046: private Map inputModules;
047: private ComponentManager componentManager;
048: private ComponentSelector componentInputSelector;
049: private ServiceManager serviceManager;
050: private ServiceSelector serviceInputSelector;
051:
052: /**
053: * Get the input module
054: */
055: private InputModule getInputModule(String name)
056: throws CascadingRuntimeException {
057: if (this .inputModules == null) {
058: throw new RuntimeException(
059: "ModuleHelper is not setup correctly.");
060: }
061: InputModule module = (InputModule) this .inputModules.get(name);
062: if (module == null) {
063: try {
064: if (this .componentManager != null) {
065: if (this .componentInputSelector.hasComponent(name)) {
066: module = (InputModule) this .componentInputSelector
067: .select(name);
068: }
069: } else {
070: if (this .serviceInputSelector.isSelectable(name)) {
071: module = (InputModule) this .serviceInputSelector
072: .select(name);
073: }
074: }
075: } catch (Exception e) {
076: throw new CascadingRuntimeException(
077: "Unable to lookup input module " + name, e);
078: }
079: if (module == null) {
080: throw new RuntimeException("No such InputModule: "
081: + name);
082: }
083: this .inputModules.put(name, module);
084: }
085: return module;
086: }
087:
088: /**
089: * Capsules use of an InputModule. Does all the lookups and so
090: * on. Returns either an Object, an Object[], or an Iterator,
091: * depending on the method called i.e. the op specified. The
092: * second module is preferred and has an non null name. If an
093: * exception is encountered, a warn message is printed and null is
094: * returned.
095: * @param op an <code>int</code> value encoding the desired operation
096: * @param name a <code>String</code> value holding the name of the
097: * InputModule
098: * @param attr a <code>String</code> value holding the name of the
099: * attribute to return. Is disregarded when attribute names is
100: * requested.
101: * @param objectModel a <code>Map</code> value holding the current
102: * ObjectModel
103: * @return an <code>Object</code> value
104: * @exception CascadingRuntimeException if an error occurs. The real
105: * exception can be obtained with <code>getCause</code>.
106: */
107: private Object get(int op, String name, String attr,
108: Map objectModel, Configuration conf)
109: throws CascadingRuntimeException {
110:
111: Object value = null;
112: final InputModule input = this .getInputModule(name);
113:
114: try {
115:
116: switch (op) {
117: case OP_GET:
118: value = input.getAttribute(attr, conf, objectModel);
119: break;
120: case OP_VALUES:
121: value = input.getAttributeValues(attr, conf,
122: objectModel);
123: break;
124: case OP_NAMES:
125: value = input.getAttributeNames(conf, objectModel);
126: break;
127: }
128:
129: } catch (Exception e) {
130: throw new CascadingRuntimeException(
131: "Error accessing attribute '" + attr
132: + "' from input module '" + name + "'. "
133: + e.getMessage(), e);
134: }
135:
136: return value;
137: }
138:
139: private Object get(int op, String name, String attr, Map objectModel)
140: throws RuntimeException {
141: return get(op, name, attr, objectModel, null);
142: }
143:
144: /**
145: * Initializes the instance for first use. Stores references to
146: * component manager and component selector in instance
147: *
148: * @param manager a <code>ComponentManager</code> value
149: * @exception RuntimeException if an error occurs
150: * @deprecated Use the {@link #setup(ServiceManager)} method instead
151: */
152: public void setup(ComponentManager manager) throws RuntimeException {
153:
154: this .inputModules = new HashMap();
155: this .componentManager = manager;
156: try {
157: this .componentInputSelector = (ComponentSelector) this .componentManager
158: .lookup(INPUT_MODULE_SELECTOR);
159: } catch (Exception e) {
160: throw new CascadingRuntimeException(
161: "Could not obtain selector for InputModule.", e);
162: }
163: }
164:
165: /**
166: * Initializes the instance for first use. Stores references to
167: * service manager and service selector in instance
168: *
169: * @param manager a <code>ServiceManager</code> value
170: * @exception RuntimeException if an error occurs
171: */
172: public void setup(ServiceManager manager) throws RuntimeException {
173:
174: this .inputModules = new HashMap();
175: this .serviceManager = manager;
176: try {
177: this .serviceInputSelector = (ServiceSelector) this .serviceManager
178: .lookup(INPUT_MODULE_SELECTOR);
179: } catch (Exception e) {
180: throw new CascadingRuntimeException(
181: "Could not obtain selector for InputModule.", e);
182: }
183: }
184:
185: /**
186: * Get a single attribute value from a module. Uses cached
187: * reference if existing.
188: *
189: * @param objectModel a <code>Map</code> value
190: * @param conf a <code>Configuration</code> containing the module dynamic configuration (aka modeConf)
191: * @param module a <code>String</code> value holding the module name
192: * @param name a <code>String</code> value holding the attribute name
193: * @param deflt an <code>Object</code> value holding a default value
194: * @return an <code>Object</code> value
195: * @exception RuntimeException if an error occurs
196: */
197: public Object getAttribute(Map objectModel, Configuration conf,
198: String module, String name, Object deflt)
199: throws RuntimeException {
200:
201: Object result = this .get(OP_GET, module, name, objectModel,
202: conf);
203: if (result == null)
204: result = deflt;
205: return result;
206: }
207:
208: /**
209: * Get a single attribute value from a module. Same as {@link
210: * #getAttribute(Map, Configuration, String, String, Object)} with a
211: * <code>null</code> configuration.
212: */
213: public Object getAttribute(Map objectModel, String module,
214: String name, Object deflt) throws RuntimeException {
215: return getAttribute(objectModel, null, module, name, deflt);
216: }
217:
218: /**
219: * Get an array of values from a module. Uses cached reference if
220: * existing.
221: *
222: * @param objectModel a <code>Map</code> value
223: * @param conf a <code>Configuration</code> containing the module dynamic configuration (aka modeConf)
224: * @param module a <code>String</code> value holding the module name
225: * @param name a <code>String</code> value holding the attribute name
226: * @param deflt an <code>Object[]</code> value holding a default value
227: * @return an <code>Object[]</code> value
228: * @exception RuntimeException if an error occurs
229: */
230: public Object[] getAttributeValues(Map objectModel,
231: Configuration conf, String module, String name,
232: Object[] deflt) throws RuntimeException {
233:
234: Object[] result = (Object[]) this .get(OP_VALUES, module, name,
235: objectModel, conf);
236: if (result == null)
237: result = deflt;
238: return result;
239: }
240:
241: /**
242: * Get an array of values from a module. Same as
243: * {@link #getAttributeValues(Map, Configuration, String, String, Object[])}
244: * with a <code>null</code> configuration.
245: */
246: public Object[] getAttributeValues(Map objectModel, String module,
247: String name, Object[] deflt) throws RuntimeException {
248: return getAttributeValues(objectModel, null, module, name,
249: deflt);
250: }
251:
252: /**
253: * Get an iterator to a collection of attribute names from a
254: * module.
255: *
256: * @param objectModel a <code>Map</code> value
257: * @param module the module's name
258: * @return an <code>Iterator</code> value
259: * @exception RuntimeException if an error occurs
260: */
261: public Iterator getAttributeNames(Map objectModel,
262: Configuration conf, String module) throws RuntimeException {
263:
264: return (Iterator) this .get(OP_NAMES, module, null, objectModel);
265: }
266:
267: /** Get an iterator to a collection of attribute names from a module. Same
268: * as {@link #getAttributeNames(Map, Configuration, String)} with a
269: * <code>null</code> configuration.
270: */
271: public Iterator getAttributeNames(Map objectModel, String module)
272: throws RuntimeException {
273: return getAttributeNames(objectModel, (Configuration) null,
274: module);
275: }
276:
277: /**
278: * Releases all obtained module references.
279: *
280: * @exception RuntimeException if an error occurs
281: */
282: public void releaseAll() throws RuntimeException {
283:
284: if (this .inputModules != null) {
285: // test for component manager
286: if (this .componentManager != null) {
287: try {
288: Iterator iter = this .inputModules.keySet()
289: .iterator();
290: while (iter.hasNext()) {
291: this .componentInputSelector
292: .release((InputModule) this .inputModules
293: .get(iter.next()));
294: }
295: this .inputModules = null;
296: this .componentManager
297: .release(this .componentInputSelector);
298: this .componentManager = null;
299: this .inputModules = null;
300: } catch (Exception e) {
301: throw new CascadingRuntimeException(
302: "Could not release InputModules.", e);
303: }
304:
305: }
306: if (this .serviceManager != null) {
307: try {
308: Iterator iter = this .inputModules.keySet()
309: .iterator();
310: while (iter.hasNext()) {
311: this .serviceInputSelector
312: .release(this .inputModules.get(iter
313: .next()));
314: }
315: this .inputModules = null;
316: this .serviceManager
317: .release(this .serviceInputSelector);
318: this .serviceManager = null;
319: this .inputModules = null;
320: } catch (Exception e) {
321: throw new CascadingRuntimeException(
322: "Could not release InputModules.", e);
323: }
324:
325: }
326: }
327: }
328:
329: }
|