KickJava   Java API By Example, From Geeks To Geeks.

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


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 java.util.HashMap JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.SortedSet JavaDoc;
22 import java.util.TreeSet JavaDoc;
23 import java.util.Vector JavaDoc;
24
25 import org.apache.avalon.framework.component.Component;
26 import org.apache.avalon.framework.component.ComponentException;
27 import org.apache.avalon.framework.component.ComponentManager;
28 import org.apache.avalon.framework.configuration.Configuration;
29 import org.apache.avalon.framework.configuration.ConfigurationException;
30 import org.apache.avalon.framework.thread.ThreadSafe;
31
32 import org.apache.cocoon.environment.ObjectModelHelper;
33 import org.apache.cocoon.environment.Request;
34 import org.apache.cocoon.xml.dom.DOMUtil;
35 import org.apache.cocoon.xml.dom.DocumentWrapper;
36 import org.apache.excalibur.xml.xpath.XPathProcessor;
37
38 import org.w3c.dom.Document JavaDoc;
39 import org.w3c.dom.Element JavaDoc;
40 import org.w3c.dom.Node JavaDoc;
41
42 /**
43  * Meta module that obtains values from other module and returns all
44  * parameters as XML.
45  *
46  * <p>Config</p>
47  * <pre>
48  * &lt;!-- in cocoon.xconf --&gt;
49  * &lt;ignore&gt;do-&lt;/ignore&gt;
50  * &lt;strip&gt;user.&lt;/strip&gt;
51  * &lt;input-module name="request-param"/&gt;
52  *
53  * &lt;!-- e.g. in database.xml --&gt;
54  * &lt;mode type="all" name="xmlmeta"/&gt;
55  * &lt;ignore&gt;foo.&lt;/ignore&gt;
56  * &lt;strip&gt;f&lt;/strip&gt;
57  * &lt;use&gt;foo&lt;/use&gt;
58  * &lt;root&gt;my-root&lt;/root&gt;
59  * &lt;input-module name="request-param"/&gt;
60  * &lt;/mode&gt;
61  * </pre>
62  *
63  * <p>If present, "ignore" gives a prefix of parameters to ignore,
64  * ignore has precedence over the "use" attribute, "strip" a prefix
65  * that will be removed from the final parameter names in the produced
66  * XML, "use" is a prefix for parameters to include in the XML, and
67  * "root" is the name of the root element in the created XML.</p>
68  *
69  * <p>Input</p>
70  * <pre>
71  * foo.one = ['abc']
72  * foo.two = ['def']
73  * foo1 = ['bar']
74  * foo2 = ['one','two','three']
75  * bar = ['rubber duck']
76  * </pre>
77  *
78  * <p>Output</p>
79  * <pre>
80  * &lt;my-root&gt;
81  * &lt;item name="oo1"&gt;bar&lt;/item&gt;
82  * &lt;item name="oo2"&gt;
83  * &lt;value&gt;one&lt;/value&gt;
84  * &lt;value&gt;two&lt;/value&gt;
85  * &lt;value&gt;three&lt;/value&gt;
86  * &lt;/item&gt;
87  * &lt;/my-root&gt;
88  * </pre>
89  *
90  * <p>Produces Objects of type {@link org.apache.cocoon.xml.dom.DocumentWrapper DocumentWrapper}</p>
91  *
92  * @author <a HREF="mailto:haul@apache.org">Christian Haul</a>
93  * @version CVS $Id: XMLMetaModule.java 30932 2004-07-29 17:35:38Z vgritsenko $
94  */

95 public class XMLMetaModule extends AbstractMetaModule implements ThreadSafe {
96
97     protected String JavaDoc rootName = "root";
98     protected String JavaDoc ignore;
99     protected String JavaDoc use;
100     protected String JavaDoc strip;
101     protected Object JavaDoc config;
102     protected XPathProcessor xpathProcessor;
103     
104     protected static final String JavaDoc CACHE_OBJECT_NAME = "org.apache.cocoon.component.modules.input.XMLMetaModule";
105
106     final static Vector JavaDoc returnNames;
107     static {
108         Vector JavaDoc tmp = new Vector JavaDoc();
109         tmp.add("XML");
110         returnNames = tmp;
111     }
112
113
114     
115     public void configure(Configuration config) throws ConfigurationException {
116
117         this.inputConf = config.getChild("input-module");
118         this.defaultInput = this.inputConf.getAttribute("name", this.defaultInput);
119         this.rootName = this.inputConf.getAttribute("root",this.rootName);
120         this.ignore = this.inputConf.getAttribute("ignore",this.ignore);
121         this.use = this.inputConf.getAttribute("use",this.use);
122         this.strip = this.inputConf.getAttribute("strip",this.strip);
123         this.config = config;
124
125         // preferred
126
this.rootName = config.getChild("root").getValue(this.rootName);
127         this.ignore = config.getChild("ignore").getValue(this.ignore);
128         this.use = config.getChild("use").getValue(this.use);
129         this.strip = config.getChild("strip").getValue(this.strip);
130     }
131
132
133
134
135     public Object JavaDoc getAttribute( String JavaDoc name, Configuration modeConf, Map JavaDoc objectModel )
136         throws ConfigurationException {
137
138         if (!this.initialized) {
139             this.lazy_initialize();
140         }
141         if (this.defaultInput == null) {
142             if (getLogger().isWarnEnabled())
143                 getLogger().warn("No input module given. FAILING");
144             return null;
145         }
146
147
148         // obtain correct configuration objects
149
// default vs dynamic
150
Configuration inputConfig = null;
151         String JavaDoc inputName=null;
152         String JavaDoc rootName = this.rootName;
153         String JavaDoc ignore = this.ignore;
154         String JavaDoc use = this.use;
155         String JavaDoc strip = this.strip;
156         if (modeConf!=null) {
157             inputName = modeConf.getChild("input-module").getAttribute("name",null);
158             rootName = modeConf.getAttribute("root",this.rootName);
159             ignore = modeConf.getAttribute("ignore" ,this.ignore );
160             use = modeConf.getAttribute("use" ,this.use );
161             strip = modeConf.getAttribute("strip" ,this.strip );
162
163             // preferred
164
rootName = modeConf.getChild("root").getValue(rootName);
165             ignore = modeConf.getChild("ignore").getValue(ignore );
166             use = modeConf.getChild("use").getValue(use );
167             strip = modeConf.getChild("strip").getValue(strip );
168             if (inputName != null) {
169                 inputConfig = modeConf.getChild("input-module");
170             }
171         }
172
173         // see whether the Document is already stored as request
174
// attribute and return that
175
Request request = ObjectModelHelper.getRequest(objectModel);
176         Map JavaDoc cache = (Map JavaDoc) request.getAttribute(CACHE_OBJECT_NAME);
177         Object JavaDoc key = (modeConf != null ? modeConf : this.config);
178         Document JavaDoc doc = null;
179
180         if (cache != null && cache.containsKey(key)) {
181             doc = (Document JavaDoc) cache.get(key);
182             if (getLogger().isDebugEnabled())
183                 getLogger().debug("using cached copy "+doc);
184             return doc;
185         }
186         if (getLogger().isDebugEnabled())
187             getLogger().debug("no cached copy "+cache+" / "+key);
188
189
190         // get InputModule and all attribute names
191
InputModule input = null;
192         if (inputName != null) input = obtainModule(inputName);
193
194         Iterator JavaDoc names = getNames(objectModel,
195                                   this.input, this.defaultInput, this.inputConf,
196                                   input, inputName, inputConfig);
197
198         // first, sort all attribute names that the DOM can be created in one go
199
// while doing so, remove unwanted attributes
200
SortedSet JavaDoc set = new TreeSet JavaDoc();
201         String JavaDoc aName = null;
202         while (names.hasNext()){
203             aName = (String JavaDoc) names.next();
204             if ((use == null || aName.startsWith(use)) &&
205                 (ignore == null || !aName.startsWith(ignore))) {
206                 set.add(aName);
207             }
208         }
209
210         try {
211             names = set.iterator();
212             
213             // create new document and append root node
214
doc = DOMUtil.createDocument();
215             Element JavaDoc elem = doc.createElement(rootName);
216             doc.appendChild(elem);
217
218             while (names.hasNext()){
219                 aName = (String JavaDoc) names.next();
220                 // obtain values from input module
221
Object JavaDoc[] value = getValues(aName, objectModel,
222                                            this.input, this.defaultInput, this.inputConf,
223                                            input, inputName, inputConfig);
224
225                 // strip unwanted prefix from attribute name if present
226
if (strip != null && aName.startsWith(strip))
227                     aName = aName.substring(strip.length());
228
229                 if (value.length > 0) {
230                     // add new node from xpath
231
// (since the names are in a set, the node cannot exist already)
232
Node JavaDoc node = DOMUtil.selectSingleNode(doc.getDocumentElement(), aName, this.xpathProcessor);
233                     node.appendChild( node.getOwnerDocument().createTextNode(value[0].toString()));
234
235                     if (value.length > 1) {
236                         // if more than one value was obtained, append
237
// further nodes (same name)
238

239                         // isolate node name, selection expressions
240
// "[...]" may not be part of it
241
int endPos = aName.length() - (aName.endsWith("/") ? 1 : 0);
242                         int startPos = aName.lastIndexOf("/", endPos) +1;
243                         String JavaDoc nodeName = aName.substring(startPos, endPos);
244                         if (nodeName.indexOf("[") != -1) {
245                             endPos = nodeName.lastIndexOf("]");
246                             startPos = nodeName.indexOf("[") +1;
247                             nodeName = nodeName.substring(startPos, endPos);
248                         }
249
250                         // append more nodes
251
Node JavaDoc parent = node.getParentNode();
252                         for (int i = 1; i < value.length; i++) {
253                             Node JavaDoc newNode = parent.getOwnerDocument().createElementNS(null, nodeName);
254                             parent.appendChild( newNode );
255                             newNode.appendChild( newNode.getOwnerDocument().createTextNode(value[i].toString()));
256                         }
257                     }
258                 }
259             }
260         } catch (Exception JavaDoc e) {
261             throw new ConfigurationException(e.getMessage());
262         }
263
264         if (input != null) releaseModule(input);
265
266         // create a wrapped instance that is XMLizable
267
doc = new DocumentWrapper(doc);
268
269         // store Document as request attribute
270
if (cache == null)
271             cache = new HashMap JavaDoc();
272         if (getLogger().isDebugEnabled())
273             getLogger().debug("no cached copy "+cache+" / "+key);
274         cache.put(key, doc);
275         request.setAttribute(CACHE_OBJECT_NAME,cache);
276         
277         
278         if (getLogger().isDebugEnabled())
279             getLogger().debug("returning "+doc.toString());
280         return doc;
281     }
282
283
284
285
286
287     public Iterator JavaDoc getAttributeNames( Configuration modeConf, Map JavaDoc objectModel )
288         throws ConfigurationException {
289
290          if (!this.initialized) {
291              this.lazy_initialize();
292         }
293         if (this.defaultInput == null) {
294             if (getLogger().isWarnEnabled())
295                 getLogger().warn("No input module given. FAILING");
296             return null;
297         }
298
299         return XMLMetaModule.returnNames.iterator();
300    }
301
302
303
304
305     public Object JavaDoc[] getAttributeValues( String JavaDoc name, Configuration modeConf, Map JavaDoc objectModel )
306         throws ConfigurationException {
307
308         if (!this.initialized) {
309             this.lazy_initialize();
310         }
311         if (this.defaultInput == null) {
312             if (getLogger().isWarnEnabled())
313                 getLogger().warn("No input module given. FAILING");
314             return null;
315         }
316         
317         Object JavaDoc[] values = new Object JavaDoc[1];
318         values[0] = this.getAttribute(name, modeConf, objectModel);
319         return values;
320     }
321
322     /* (non-Javadoc)
323      * @see org.apache.avalon.framework.component.Composable#compose(org.apache.avalon.framework.component.ComponentManager)
324      */

325     public void compose(ComponentManager manager) throws ComponentException {
326         super.compose(manager);
327         this.xpathProcessor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE);
328     }
329
330     /* (non-Javadoc)
331      * @see org.apache.avalon.framework.activity.Disposable#dispose()
332      */

333     public void dispose() {
334         if ( this.manager != null ) {
335             this.manager.release((Component)this.xpathProcessor);
336             this.xpathProcessor = null;
337         }
338         super.dispose();
339     }
340
341 }
342
Popular Tags