KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > modules > input > AbstractMetaModule


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.cocoon.components.modules.input;
18
19 import java.util.Iterator JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.apache.avalon.framework.activity.Disposable;
23 import org.apache.avalon.framework.component.ComponentException;
24 import org.apache.avalon.framework.component.ComponentManager;
25 import org.apache.avalon.framework.component.ComponentSelector;
26 import org.apache.avalon.framework.component.Composable;
27 import org.apache.avalon.framework.configuration.Configuration;
28 import org.apache.avalon.framework.configuration.ConfigurationException;
29 import org.apache.avalon.framework.thread.ThreadSafe;
30
31 /**
32  * AbstractMetaModule gives you the infrastructure for easily
33  * deploying more "meta" InputModules i.e. InputModules that are
34  * composed of other InputModules. In order to get at the Logger, use
35  * getLogger().
36  *
37  * @author <a HREF="mailto:haul@apache.org">Christian Haul</a>
38  * @author <a HREF="mailto:jefft@apache.org">Jeff Turner</a>
39  * @version CVS $Id: AbstractMetaModule.java 149132 2005-01-30 18:24:33Z cziegeler $
40  */

41 public abstract class AbstractMetaModule extends AbstractInputModule
42     implements Composable, Disposable {
43
44     /** The component manager instance */
45     protected ComponentManager manager;
46
47     /** The cached InputModule-Selector */
48     protected ComponentSelector inputSelector = null;
49
50     /** The cached default InputModule */
51     protected InputModule input = null;
52
53     /** The default InputModule name / shorthand. Defaults to 'request-param' */
54     protected String JavaDoc defaultInput = "request-param"; // default to request parameters
55

56     /** The default InputModule configuration */
57     protected Configuration inputConf = null; // will become an empty configuration object
58
// during configure() so why bother here...
59

60     /** Is this instance initialized? */
61     protected boolean initialized = false;
62
63     /* Constants */
64
65     protected final static String JavaDoc INPUT_MODULE_SELECTOR = InputModule.ROLE+"Selector";
66
67     /* Operation codes */
68     private final static int OP_GET = 0;
69     private final static int OP_VALUES = 1;
70     private final static int OP_NAMES = 2;
71     private final static String JavaDoc[] OPNAME = new String JavaDoc[] {"GET_VALUE", "GET_VALUES", "GET_NAMES"};
72
73
74     /**
75      * Set the current <code>ComponentManager</code> instance used by this
76      * <code>Composable</code>.
77      */

78     public void compose(ComponentManager manager) throws ComponentException {
79
80         this.manager=manager;
81     }
82
83
84     /**
85      * Initialize the meta module with exactly one other input
86      * module. Since "meta" modules require references to components
87      * of the same role, initialization cannot be done in initialize()
88      * when also implementing ThreadSafe since at that point the
89      * component selector is not yet initialized it would trigger the
90      * creation of a new one resulting in an endless loop of
91      * initializations. Therefore, every module needs to call this
92      * method when it first requires access to another module if the
93      * module itself has not been initialized. Override this method
94      * and dispose() to keep references to more than one module.
95      */

96     public synchronized void lazy_initialize() {
97
98         try {
99             // obtain input modules
100
if (!this.initialized) {
101                 this.inputSelector=(ComponentSelector) this.manager.lookup(INPUT_MODULE_SELECTOR);
102                 if (this.inputSelector != null && this.inputSelector instanceof ThreadSafe) {
103                     
104                     if (this.defaultInput != null) {
105                         this.input = obtainModule(this.defaultInput);
106                     }
107                     
108                 } else if (!(this.inputSelector instanceof ThreadSafe) ) {
109                     this.manager.release(this.inputSelector);
110                     this.inputSelector = null;
111                 }
112                 
113                 this.initialized = true;
114             }
115         } catch (Exception JavaDoc e) {
116             if (getLogger().isWarnEnabled())
117                 getLogger().error("A problem occurred setting up input modules :'" + e.getMessage(), e);
118         }
119     }
120
121
122     /**
123      * Dispose exactly one cached InputModule. To work on more than
124      * one, override this method and initialize().
125      */

126     public void dispose() {
127
128         if (this.inputSelector != null) {
129             if (this.input != null)
130                 this.inputSelector.release(this.input);
131             this.manager.release(this.inputSelector);
132         }
133     }
134
135
136     /**
137      * Obtain a permanent reference to an InputModule.
138      */

139     protected InputModule obtainModule(String JavaDoc type) {
140         ComponentSelector inputSelector = this.inputSelector;
141         InputModule module = null;
142         try {
143             if (inputSelector == null) {
144                 inputSelector=(ComponentSelector) this.manager.lookup(INPUT_MODULE_SELECTOR);
145             }
146             if (inputSelector.hasComponent(type)) {
147                 if (type != null && inputSelector.hasComponent(type)) {
148                     module = (InputModule) inputSelector.select(type);
149                 }
150                 if (!(module instanceof ThreadSafe) ) {
151                     inputSelector.release(module);
152                     module = null;
153                 }
154             }
155             if (type != null && module == null)
156                 if (getLogger().isWarnEnabled())
157                     getLogger().warn("A problem occurred setting up '" + type
158                                      + "': Selector is not null, Component is "
159                                      + (inputSelector.hasComponent(type)? "known" : "unknown"));
160             
161         } catch (ComponentException ce) {
162             if (getLogger().isWarnEnabled())
163                 getLogger().warn("Could not obtain selector for InputModules: "+ce.getMessage());
164         } finally {
165             if (this.inputSelector == null)
166                 this.manager.release(inputSelector);
167             // FIXME: Is it OK to keep a reference to the module when we release the selector?
168
}
169
170         return module;
171     }
172
173
174     /**
175      * release a permanent reference to an InputModule.
176      */

177     protected void releaseModule(InputModule module) {
178         ComponentSelector inputSelector = this.inputSelector;
179         if (module != null) {
180             try {
181                 // FIXME: Is it OK to release a module when we have released the selector before?
182
if (inputSelector == null)
183                     inputSelector=(ComponentSelector) this.manager.lookup(INPUT_MODULE_SELECTOR);
184                 
185                 inputSelector.release(module);
186                 module = null;
187                 
188             } catch (ComponentException ce) {
189                 if (getLogger().isWarnEnabled())
190                     getLogger().warn("Could not obtain selector for InputModules: "+ce.getMessage());
191             } finally {
192                 if (this.inputSelector == null)
193                     this.manager.release(inputSelector);
194             }
195         }
196     }
197
198     /**
199      * Get names of available attributes in the specified (usually statically
200      * assigned) Input Module.
201      * @see InputModule#getAttributeNames(Configuration, Map)
202      */

203     protected Iterator JavaDoc getNames(Map JavaDoc objectModel,
204                                 InputModule staticMod, String JavaDoc staticModName, Configuration staticModConf)
205         throws ConfigurationException {
206
207         return (Iterator JavaDoc) this.get(OP_NAMES, null, objectModel, staticMod, staticModName, staticModConf, null, null, null);
208     }
209
210     /**
211      * Get names of available attributes in one of the specified Input Modules
212      * (static or dynamic, dynamic preferred). Dynamic IM may be
213      * <code>null</code>.
214      * @see InputModule#getAttributeNames(Configuration, Map)
215      */

216      protected Iterator JavaDoc getNames(Map JavaDoc objectModel,
217                                 InputModule staticMod, String JavaDoc staticModName, Configuration staticModConf,
218                                 InputModule dynamicMod, String JavaDoc dynamicModName, Configuration dynamicModConf)
219         throws ConfigurationException {
220
221         return (Iterator JavaDoc) this.get(OP_NAMES, null, objectModel, staticMod, staticModName, staticModConf, dynamicMod, dynamicModName, dynamicModConf);
222     }
223
224     protected Object JavaDoc getValue(String JavaDoc attr, Map JavaDoc objectModel, ModuleHolder holder) throws ConfigurationException{
225         return this.getValue(attr, objectModel, holder.input, holder.name, holder.config);
226     }
227
228     protected Object JavaDoc getValue(String JavaDoc attr, Map JavaDoc objectModel, ModuleHolder staticHolder, ModuleHolder dynamicHolder) throws ConfigurationException{
229         return this.getValue(attr, objectModel, staticHolder.input, staticHolder.name, dynamicHolder.config);
230     }
231
232     protected Object JavaDoc[] getValues(String JavaDoc attr, Map JavaDoc objectModel, ModuleHolder holder) throws ConfigurationException{
233         return this.getValues(attr, objectModel, holder.input, holder.name, holder.config);
234     }
235
236     protected Object JavaDoc[] getValues(String JavaDoc attr, Map JavaDoc objectModel, ModuleHolder staticHolder, ModuleHolder dynamicHolder) throws ConfigurationException{
237         return this.getValues(attr, objectModel, staticHolder.input, staticHolder.name, dynamicHolder.config);
238     }
239
240     /**
241      * Get an attribute's value from a (usually statically assigned) Input
242      * Module.
243      * @see InputModule#getAttribute(String, Configuration, Map)
244      */

245      protected Object JavaDoc getValue(String JavaDoc attr, Map JavaDoc objectModel,
246                               InputModule staticMod, String JavaDoc staticModName, Configuration staticModConf)
247         throws ConfigurationException {
248
249         return this.get(OP_GET, attr, objectModel, staticMod, staticModName, staticModConf, null, null, null);
250     }
251
252
253     /**
254      * Get attribute's value in one of the specified Input Modules
255      * (static or dynamic, dynamic preferred). Dynamic IM may be
256      * <code>null</code>.
257      * @see InputModule#getAttribute(String, Configuration, Map)
258      */

259      protected Object JavaDoc getValue(String JavaDoc attr, Map JavaDoc objectModel,
260                               InputModule staticMod, String JavaDoc staticModName, Configuration staticModConf,
261                               InputModule dynamicMod, String JavaDoc dynamicModName, Configuration dynamicModConf)
262         throws ConfigurationException {
263
264         return this.get(OP_GET, attr, objectModel, staticMod, staticModName, staticModConf, dynamicMod, dynamicModName, dynamicModConf);
265     }
266
267     /**
268      * Get an attribute's values from a (usually statically assigned) Input
269      * Module.
270      * @see InputModule#getAttributeValues(String, Configuration, Map)
271      */

272      protected Object JavaDoc[] getValues(String JavaDoc attr, Map JavaDoc objectModel,
273                                  InputModule staticMod, String JavaDoc staticModName, Configuration staticModConf)
274         throws ConfigurationException {
275
276         return (Object JavaDoc[]) this.get(OP_VALUES, attr, objectModel, staticMod, staticModName, staticModConf, null, null, null);
277     }
278
279     /**
280      * Get attribute's values in one of the specified Input Modules
281      * (static or dynamic, dynamic preferred). Dynamic IM may be
282      * <code>null</code>.
283      * @see InputModule#getAttributeValues(String, Configuration, Map)
284      */

285      protected Object JavaDoc[] getValues(String JavaDoc attr, Map JavaDoc objectModel,
286                                  InputModule staticMod, String JavaDoc staticModName, Configuration staticModConf,
287                                  InputModule dynamicMod, String JavaDoc dynamicModName, Configuration dynamicModConf)
288         throws ConfigurationException {
289
290         return (Object JavaDoc[]) this.get(OP_VALUES, attr, objectModel, staticMod, staticModName, staticModConf, dynamicMod, dynamicModName, dynamicModConf);
291     }
292
293
294     /**
295      * Encapsulates use of an InputModule. Does all the lookups and so on.
296      * The second module (dynamic) is preferred if it has an non null name. If
297      * an exception is encountered, a warn message is printed and null is
298      * returned.
299      * @param op Operation to perform ({@link #OP_GET}, {@link #OP_NAMES}, {@link #OP_VALUES}).
300      *
301      * @return Either an Object, an Object[], or an Iterator, depending on <code>op</code> param.
302      */

303     private Object JavaDoc get(int op, String JavaDoc attr, Map JavaDoc objectModel,
304                          InputModule staticMod, String JavaDoc staticModName, Configuration staticModConf,
305                          InputModule dynamicMod, String JavaDoc dynamicModName, Configuration dynamicModConf)
306         throws ConfigurationException {
307
308         ComponentSelector cs = this.inputSelector;
309         Object JavaDoc value = null;
310         String JavaDoc name = null;
311         InputModule input = null;
312         Configuration conf = null;
313         boolean release = false;
314
315         try {
316             if (cs == null) {
317                 try {
318                 cs = (ComponentSelector) this.manager.lookup(INPUT_MODULE_SELECTOR);
319                 } catch (ComponentException e) {
320                     throw new ConfigurationException("Could not find MetaModule's module selector", e);
321                 }
322             }
323
324             boolean useDynamic;
325             if (dynamicMod == null && dynamicModName == null) {
326                 useDynamic = false;
327                 input = staticMod;
328                 name = staticModName;
329                 conf = staticModConf;
330             } else {
331                 useDynamic = true;
332                 input = dynamicMod;
333                 name = dynamicModName;
334                 conf = dynamicModConf;
335             }
336         
337             if (getLogger().isDebugEnabled()) {
338                 getLogger().debug("MetaModule performing op "+OPNAME[op]+" on " +
339                         (useDynamic?"dynamically":"statically") + " " +
340                         (input==null?"created":"assigned") +
341                         " module '"+name+"', using config "+dynamicModConf);
342             }
343
344             if (input == null) {
345                 if (cs.hasComponent(name)) {
346                     release = true;
347                     try {
348                         input = (InputModule) cs.select(name);
349                     } catch (ComponentException e) {
350                         throw new ConfigurationException(
351                                 "MetaModule unable to create "+
352                                 (useDynamic ? "dynamically" : "statically")+
353                                 " specified internal module '"+name+"'", e);
354                     }
355                 } else {
356                     throw new ConfigurationException("MetaModule: No such InputModule: "+name);
357                 }
358             }
359
360             switch (op) {
361             case OP_GET:
362                 value = input.getAttribute(attr, conf, objectModel);
363                 break;
364             case OP_VALUES:
365                 value = input.getAttributeValues(attr, conf, objectModel);
366                 break;
367             case OP_NAMES:
368                 value = input.getAttributeNames(conf, objectModel);
369                 break;
370             }
371
372             if (getLogger().isDebugEnabled())
373                 getLogger().debug("using "+name+" as "+input+" for "+op+" ("+attr+") and "+conf+" gives "+value);
374             
375         } finally {
376             if (release)
377                 cs.release(input);
378
379             if (this.inputSelector == null)
380                 this.manager.release(cs);
381         }
382
383         return value;
384     }
385                               
386 }
387
Popular Tags