KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright 1999-2004 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 package org.apache.cocoon.components.modules.input;
17
18 import org.apache.avalon.framework.configuration.Configuration;
19 import org.apache.avalon.framework.configuration.ConfigurationException;
20 import org.apache.avalon.framework.component.ComponentSelector;
21 import org.apache.avalon.framework.thread.ThreadSafe;
22
23 import java.util.Map JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Arrays JavaDoc;
27 import java.util.Collection JavaDoc;
28 import java.util.Iterator JavaDoc;
29
30 /**
31  * This modules allows to "chain" several other modules. If a module
32  * returns "null" as attribute value, the next module in the chain is
33  * queried until either a value can be obtained or the end of the
34  * chain is reached.
35  *
36  * <p>A typical example would be to "chain" request parameters,
37  * session attributes, and constants in this order. This way, an
38  * application could have a default skin that could be overridden by a
39  * user in her/his profile stored in the session. In addition, the
40  * user could request a different skin through passing a request
41  * parameter.</p>
42  *
43  * <p>Usage:</p>
44  *
45  * <p> Any number of &lt;input-module/&gt; blocks may appear in the
46  * component configuration. The @name attribute is used as the name of
47  * the requested input module. The complete &lt;input-module/&gt;
48  * block is passed at run-time to the module and thus can contain any
49  * configuration data for that particular module.</p>
50  *
51  * <p>Configuration:</p>
52  *
53  * <p>It can be controlled whether it returns a flat or a deep view,
54  * i.e. whether only values from the first module are returned if
55  * non-null or they are merged with values from other modules
56  * <code>&lt;all-values&gt;true&lt;/all-values&gt;</code>. The same is
57  * possible for the attribute names
58  * (<code>&lt;all-names/&gt;</code>). In addition, empty strings could
59  * be treated the same as null values
60  * (<code>&lt;empty-as-null/&gt;</code>).</p>
61  *
62  * @author <a HREF="mailto:haul@apache.org">Christian Haul</a>
63  * @version CVS $Id: ChainMetaModule.java 30932 2004-07-29 17:35:38Z vgritsenko $
64  */

65 public class ChainMetaModule extends AbstractMetaModule implements ThreadSafe {
66
67     private ModuleHolder[] inputs = null;
68
69     private boolean emptyAsNull = false;
70     private boolean allNames = false;
71     private boolean allValues = false;
72
73     public void configure(Configuration config) throws ConfigurationException {
74
75         Configuration[] confs = config.getChildren("input-module");
76         if (confs.length > 0) {
77             this.inputs = new ModuleHolder[confs.length];
78             int j = 0;
79             for (int i=0; i<confs.length; i++) {
80                 ModuleHolder module = new ModuleHolder();
81                 module.name = confs[i].getAttribute("name",null);
82                 if (module.name == null) {
83                     if (getLogger().isErrorEnabled())
84                         getLogger().error("No name attribute for module configuration. Skipping.");
85                     continue;
86                 }
87                 module.config = confs[i];
88                 this.inputs[j]=module;
89                 j++;
90             }
91         }
92         this.emptyAsNull = config.getChild("empty-as-null").getValueAsBoolean(this.emptyAsNull);
93         this.allNames = config.getChild("all-names").getValueAsBoolean(this.allNames);
94         this.allValues = config.getChild("all-values").getValueAsBoolean(this.allValues);
95     }
96
97
98     public synchronized void lazy_initialize() {
99
100         try {
101             // obtain input modules
102
if (!this.initialized) {
103                 this.inputSelector=(ComponentSelector) this.manager.lookup(INPUT_MODULE_SELECTOR);
104                 if (this.inputSelector != null && this.inputSelector instanceof ThreadSafe) {
105                     
106                     for (int i=0; i<this.inputs.length; i++) {
107                         if (this.inputs[i].name != null)
108                             this.inputs[i].input = obtainModule(this.inputs[i].name);
109                     }
110                     
111                 } else if (!(this.inputSelector instanceof ThreadSafe) ) {
112                     this.manager.release(this.inputSelector);
113                     this.inputSelector = null;
114                 }
115                 
116                 this.initialized = true;
117             }
118         } catch (Exception JavaDoc e) {
119             if (getLogger().isWarnEnabled())
120                 getLogger().warn("A problem occurred setting up input modules :'" + e.getMessage());
121         }
122     }
123
124     
125     public void dispose() {
126         
127         if (this.inputSelector != null) {
128             
129             for (int i=0; i<this.inputs.length; i++) {
130                 if (this.inputs[i].input != null)
131                     this.inputSelector.release(this.inputs[i].input);
132             }
133             
134             this.manager.release(this.inputSelector);
135         }
136     }
137
138
139     public Object JavaDoc[] getAttributeValues( String JavaDoc attr, Configuration modeConf, Map JavaDoc objectModel )
140         throws ConfigurationException {
141
142         if (!this.initialized) {
143             this.lazy_initialize();
144         }
145
146         // obtain correct configuration objects
147
// default vs dynamic
148
Configuration[] inputConfigs = null;
149         boolean allValues = this.allValues;
150         boolean emptyAsNull = this.emptyAsNull;
151         if (modeConf!=null && modeConf.getChildren().length > 0) {
152             inputConfigs = modeConf.getChildren("input-module");
153             emptyAsNull = modeConf.getChild("empty-as-null").getValueAsBoolean(emptyAsNull);
154             allValues = modeConf.getChild("all-values").getValueAsBoolean(allValues);
155             if (inputConfigs.length == 0) inputConfigs = null;
156         }
157
158         Object JavaDoc[] value = null;
159         boolean debug = getLogger().isDebugEnabled();
160         List JavaDoc values = null;
161         if (allValues) values = new ArrayList JavaDoc();
162
163         if (inputConfigs == null) {
164             // static configuration branch
165
int i = 0;
166             while (i < this.inputs.length && (value == null || allValues)) {
167                 if (this.inputs[i].name != null) {
168                     value = getValues(attr, objectModel, this.inputs[i].input, this.inputs[i].name, this.inputs[i].config);
169                     if (emptyAsNull && value != null && value.length == 0) value = null;
170                     if (emptyAsNull && value != null && value.length == 1 &&
171                         value[0] instanceof String JavaDoc && value[0].equals("")) value = null;
172                     if (debug) getLogger().debug("read from "+this.inputs[i].name+" attribute "+attr+" as "+value);
173                     if (allValues && value != null) values.addAll(Arrays.asList(value));
174                 }
175                 i++;
176             }
177         } else {
178             // run-time configuration branch
179
int i = 0;
180             while (i < inputConfigs.length && (value == null || allValues)) {
181                 String JavaDoc name = inputConfigs[i].getAttribute("name",null);
182                 if (name != null) {
183                     value = getValues(attr, objectModel, null, name, inputConfigs[i]);
184                     if (emptyAsNull && value != null && value.length == 0) value = null;
185                     if (emptyAsNull && value != null && value.length == 1 &&
186                         value[0] instanceof String JavaDoc && value[0].equals("")) value = null;
187                     if (debug) getLogger().debug("read from "+name+" attribute "+attr+" as "+value);
188                     if (allValues && value != null) values.addAll(Arrays.asList(value));
189                 }
190                 i++;
191             }
192         }
193         if (debug) getLogger().debug("result chaining for "+attr+" is "+(allValues? values.toArray() : value));
194         return (allValues? values.toArray() : value);
195     }
196
197     private void addIterator(Collection JavaDoc col, Iterator JavaDoc iter) {
198         while (iter != null && iter.hasNext())
199             col.add(iter.next());
200     }
201
202
203     public Iterator JavaDoc getAttributeNames( Configuration modeConf, Map JavaDoc objectModel )
204         throws ConfigurationException {
205
206         if (!this.initialized) {
207             this.lazy_initialize();
208         }
209
210         // obtain correct configuration objects
211
// default vs dynamic
212
Configuration[] inputConfigs = null;
213         boolean emptyAsNull = this.emptyAsNull;
214         boolean allNames = this.allNames;
215         if (modeConf!=null && modeConf.getChildren().length > 0) {
216             inputConfigs = modeConf.getChildren("input-module");
217             emptyAsNull = modeConf.getChild("empty-as-null").getValueAsBoolean(emptyAsNull);
218             allNames = modeConf.getChild("all-names").getValueAsBoolean(allNames);
219             if (inputConfigs.length == 0) inputConfigs = null;
220         }
221
222         Iterator JavaDoc value = null;
223         Collection JavaDoc values = null;
224         if (allNames) values = new ArrayList JavaDoc();
225         boolean debug = getLogger().isDebugEnabled();
226
227         if (inputConfigs == null) {
228             // static configuration branch
229
int i = 0;
230             while (i < this.inputs.length && (value == null || allNames)) {
231                 if (this.inputs[i].name != null) {
232                     value = getNames(objectModel, this.inputs[i].input, this.inputs[i].name, this.inputs[i].config);
233                     if (debug) getLogger().debug("read from "+this.inputs[i].name+" AttributeNames as "+value);
234                     if (allNames && value != null) addIterator(values, value);
235                 }
236                 i++;
237             }
238         } else {
239             // run-time configuration branch
240
int i = 0;
241             while (i < inputConfigs.length && value == null) {
242                 String JavaDoc name = inputConfigs[i].getAttribute("name",null);
243                 if (name != null) {
244                     value = getNames(objectModel, null, name, inputConfigs[i]);
245                     if (debug) getLogger().debug("read from "+name+" AttributeNames as "+value);
246                     if (allNames && value != null) addIterator(values, value);
247                 }
248                 i++;
249             }
250         }
251         if (debug) getLogger().debug("result chaining names is "+(allNames? values.iterator() : value));
252         return (allNames? values.iterator() : value);
253      }
254
255
256     public Object JavaDoc getAttribute( String JavaDoc attr, Configuration modeConf, Map JavaDoc objectModel )
257         throws ConfigurationException {
258
259         Object JavaDoc[] values = this.getAttributeValues(attr,modeConf,objectModel);
260         if (getLogger().isDebugEnabled()) getLogger().debug("result chaining single for "+attr+" is "+(values != null? values[0] : "null"));
261         return (values != null? values[0] : null);
262     }
263
264
265 }
266
Popular Tags