KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > kernel > digester > ComponentMetadataConfig


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2003 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64 package com.jcorporate.expresso.kernel.digester;
65
66 import com.jcorporate.expresso.kernel.metadata.ComponentMetadata;
67 import com.jcorporate.expresso.kernel.util.FastStringBuffer;
68 import org.apache.commons.digester.Digester;
69 import org.apache.log4j.Logger;
70 import org.xml.sax.SAXException JavaDoc;
71
72 import javax.xml.parsers.FactoryConfigurationError JavaDoc;
73 import javax.xml.parsers.ParserConfigurationException JavaDoc;
74 import java.io.IOException JavaDoc;
75 import java.io.InputStream JavaDoc;
76 import java.net.URL JavaDoc;
77
78 /**
79  * This class provides a digester interface to the ComponentMetadata
80  * information
81  *
82  * @author Michael Rimov
83  * @since Expresso 5.1
84  */

85
86 public class ComponentMetadataConfig implements java.io.Serializable JavaDoc {
87     /**
88      * This constant tells the limit to which we allow nesting of components.
89      * Thanks to digester not being recursive, and not wanting to write our own
90      * SAX parser, we use this kludge instead.
91      */

92     private static final int MAX_NESTING = 20;
93
94
95     private static final Logger log = Logger.getLogger(ComponentMetadataConfig.class);
96
97     private ComponentMetadata root;
98
99     private SaxParserConfigurer saxParserCoonfig = new SaxParserConfigurer();
100
101
102     /**
103      * Default constructor
104      */

105     public ComponentMetadataConfig() {
106     }
107
108
109     /**
110      * <p>Load component metadata information given a String location.</p>
111      * <p>Code example</p>
112      * <p><code>ComponentMetadataConfig cf = new ComponentMetadataConfig()<br />
113      * cf.loadComponentMetadata("/com/jcorporate/expresso/core/SchemaMetadata.xml"<br/>
114      * </code></p>
115      * The above example would load the component metadata from the
116      * com.jcorporate.expresso.core package.
117      *
118      * @param resourceLocation the location of the xml file to parse
119      */

120     public void loadComponentMetadata(String JavaDoc resourceLocation) {
121         if (resourceLocation == null) {
122             throw new IllegalArgumentException JavaDoc("Parameter resourceLocation must not be null");
123         }
124
125         InputStream JavaDoc is = null;
126         try {
127             if (log.isDebugEnabled()) {
128                 log.debug("Loading metadata from location: " + resourceLocation);
129             }
130
131             saxParserCoonfig.setSAXParser();
132             javax.xml.parsers.SAXParserFactory JavaDoc spf = javax.xml.parsers.SAXParserFactory.newInstance();
133             javax.xml.parsers.SAXParser JavaDoc sp = spf.newSAXParser();
134
135             Digester digester = new Digester(sp);
136             setupResolvers(digester);
137             setDigesterRules(digester);
138
139             is = this.getClass().getResourceAsStream(resourceLocation);
140             digester.parse(is);
141         } catch (FactoryConfigurationError JavaDoc ex) {
142             log.error("Fatal error trying to find a suitable Digester compatible parser.", ex);
143         } catch (SAXException JavaDoc ex) {
144             log.error("Fatal error trying to digest expresso-services.xml file", ex);
145         } catch (ParserConfigurationException JavaDoc ex) {
146             log.error("Fatal error trying to find a suitable Digester compatible parser.", ex);
147         } catch (java.io.IOException JavaDoc ex) {
148             log.error("Fatal IO error parsing input.", ex);
149         } finally {
150             try {
151                 if (is != null) {
152                     is.close();
153                 }
154             } catch (IOException JavaDoc ex) {
155                 log.error("Error closing resource stream: " + resourceLocation, ex);
156             }
157         }
158
159     }
160
161     /**
162      * Sets up the appropriate locations to resolve the Doctypes
163      *
164      * @param digester the Apache digester to register the resolvers with.
165      */

166     private void setupResolvers(Digester digester) {
167         URL JavaDoc url = this.getClass().getResource("/com/jcorporate/expresso/kernel/expresso-metadata_5_1.dtd");
168         if (url != null) {
169             digester.register("-//Jcorporate Ltd//DTD Expresso Component Metadata Configuration 5.1//EN",
170                     url.toString());
171         } else {
172             throw new IllegalArgumentException JavaDoc("Unable to locate " +
173                     "expresso-services_5_1.dtd in component package");
174         }
175     }
176
177     /**
178      * Loads the component metadata given a URL rather than a String location
179      *
180      * @param resourceLocation the URL pointing to the location of the resource
181      * to parse.
182      */

183     public void loadComponentMetadata(URL JavaDoc resourceLocation) {
184         if (resourceLocation == null) {
185             throw new IllegalArgumentException JavaDoc("Parameter resourceLocation must not be null");
186         }
187
188         if (log.isDebugEnabled()) {
189             log.debug("Loading metadata from location: " + resourceLocation.toString());
190         }
191
192         try {
193             saxParserCoonfig.setSAXParser();
194             javax.xml.parsers.SAXParserFactory JavaDoc spf = javax.xml.parsers.SAXParserFactory.newInstance();
195             javax.xml.parsers.SAXParser JavaDoc sp = spf.newSAXParser();
196
197             Digester digester = new Digester(sp);
198             setupResolvers(digester);
199             setDigesterRules(digester);
200
201             digester.parse(resourceLocation.openStream());
202         } catch (FactoryConfigurationError JavaDoc ex) {
203             log.error("Fatal error trying to find a suitable Digester compatible parser.", ex);
204         } catch (SAXException JavaDoc ex) {
205             log.error("Fatal error trying to digest expresso-services.xml file", ex);
206         } catch (ParserConfigurationException JavaDoc ex) {
207             log.error("Fatal error trying to find a suitable Digester compatible parser.", ex);
208         } catch (java.io.IOException JavaDoc ex) {
209             log.error("Fatal IO error parsing input.", ex);
210         }
211     }
212
213
214     /**
215      * <p>Set the rules for the digester<p>
216      * <p><b>TOTAL HACK WARNING!</b> Since Digester doesn't seem to allow recursive
217      * rules, we dynamically write rules for up to a maximum component depth of
218      * 20.</p>
219      *
220      * @param digester the Apache Digester to manipulate
221      */

222     protected void setDigesterRules(Digester digester) {
223         root = new ComponentMetadata();
224
225         digester.push(root);
226         for (int i = 0; i < MAX_NESTING; i++) {
227             String JavaDoc componentDepthString = getComponentDepthString(i);
228             if (i > 0) {
229                 digester.addObjectCreate("component-metadata" + componentDepthString,
230                         com.jcorporate.expresso.kernel.metadata.ComponentMetadata.class);
231             }
232
233             digester.addSetProperties("component-metadata" + componentDepthString);
234
235             digester.addCallMethod("component-metadata" + componentDepthString + "/description", "setDescription", 1);
236             digester.addCallParam("component-metadata" + componentDepthString + "/description", 0);
237
238             digester.addCallMethod("component-metadata" + componentDepthString + "/version-info", "setVersionNumber",
239                     3);
240             digester.addCallParam("component-metadata" + componentDepthString + "/version-info/major-version", 0);
241             digester.addCallParam("component-metadata" + componentDepthString + "/version-info/minor-version", 1);
242             digester.addCallParam("component-metadata" + componentDepthString + "/version-info/micro-version", 2);
243
244             digester.addCallMethod("component-metadata" + componentDepthString + "/message-bundle", "setMessageBundle",
245                     1);
246             digester.addCallParam("component-metadata" + componentDepthString + "/message-bundle", 0);
247
248             digester.addObjectCreate("component-metadata" + componentDepthString + "/property-list/property",
249                     com.jcorporate.expresso.kernel.metadata.SimpleProperty.class);
250
251             digester.addSetProperties("component-metadata" + componentDepthString + "/property-list/property");
252             digester.addCallMethod(
253                     "component-metadata" + componentDepthString + "/property-list/property/property-valid-value",
254                     "addValidValue", 2);
255             digester.addCallParam(
256                     "component-metadata" + componentDepthString + "/property-list/property/property-valid-value", 0,
257                     "name");
258             digester.addCallParam(
259                     "component-metadata" + componentDepthString + "/property-list/property/property-valid-value", 1,
260                     "value");
261             digester.addSetNext("component-metadata" + componentDepthString + "/property-list/property", "addProperty");
262
263
264             digester.addObjectCreate("component-metadata" + componentDepthString + "/property-list/mapped-property",
265                     com.jcorporate.expresso.kernel.metadata.MappedProperty.class);
266             digester.addSetProperties("component-metadata" + componentDepthString + "/property-list/mapped-property");
267             digester.addCallMethod(
268                     "component-metadata" + componentDepthString + "/property-list/mapped-property/mapped-value",
269                     "setMappedValue", 2);
270             digester.addCallParam(
271                     "component-metadata" + componentDepthString + "/property-list/mapped-property/mapped-value", 0,
272                     "key");
273             digester.addCallParam(
274                     "component-metadata" + componentDepthString + "/property-list/mapped-property/mapped-value", 1,
275                     "value");
276             digester.addSetNext("component-metadata" + componentDepthString + "/property-list/mapped-property",
277                     "addProperty");
278
279             digester.addObjectCreate("component-metadata" + componentDepthString + "/property-list/indexed-property",
280                     com.jcorporate.expresso.kernel.metadata.IndexedProperty.class);
281             digester.addSetProperties("component-metadata" + componentDepthString + "/property-list/indexed-property");
282             digester.addCallMethod(
283                     "component-metadata" + componentDepthString + "/property-list/indexed-property/indexed-property-value",
284                     "setIndexedValue", 2);
285             digester.addCallParam(
286                     "component-metadata" + componentDepthString + "/property-list/indexed-property/indexed-property-value",
287                     0, "index");
288             digester.addCallParam(
289                     "component-metadata" + componentDepthString + "/property-list/indexed-property/indexed-property-value",
290                     1, "value");
291             digester.addSetNext("component-metadata" + componentDepthString + "/property-list/indexed-property",
292                     "addProperty");
293
294
295             digester.addObjectCreate("component-metadata" + componentDepthString + "/method-list/method",
296                     com.jcorporate.expresso.kernel.metadata.Method.class);
297             digester.addSetProperties("component-metadata" + componentDepthString + "/method-list/method",
298                     new String JavaDoc[]{"name", "return-type", "description"},
299                     new String JavaDoc[]{"name", "returnType", "description"});
300             digester.addCallMethod("component-metadata" + componentDepthString + "/method-list/method/method-arg",
301                     "addArgument", 2);
302             digester.addCallParam("component-metadata" + componentDepthString + "/method-list/method/method-arg", 0,
303                     "name");
304             digester.addCallParam("component-metadata" + componentDepthString + "/method-list/method/method-arg", 1,
305                     "type");
306             digester.addSetNext("component-metadata" + componentDepthString + "/method-list/method", "addMethod");
307
308
309             //
310
//Schema data
311
//
312
digester.addObjectCreate("component-metadata" + componentDepthString + "/schema",
313                     com.jcorporate.expresso.kernel.metadata.SchemaData.class);
314
315             digester.addObjectCreate("component-metadata" + componentDepthString + "/schema/dbobject",
316                     com.jcorporate.expresso.kernel.metadata.DBObjectData.class);
317             digester.addSetProperties("component-metadata" + componentDepthString + "/schema/dbobject/classname",
318                     new String JavaDoc[]{"name"}, new String JavaDoc[]{"className"});
319             digester.addSetNext("component-metadata" + componentDepthString + "/schema/dbobject", "addDataObject");
320
321             digester.addObjectCreate("component-metadata" + componentDepthString + "/schema/controller",
322                     com.jcorporate.expresso.kernel.metadata.ControllerData.class);
323             digester.addSetProperties("component-metadata" + componentDepthString + "/schema/controller/classname",
324                     new String JavaDoc[]{"name"}, new String JavaDoc[]{"className"});
325             digester.addSetNext("component-metadata" + componentDepthString + "/schema/controller", "addController");
326
327             digester.addObjectCreate("component-metadata" + componentDepthString + "/schema/job",
328                     com.jcorporate.expresso.kernel.metadata.JobData.class);
329             digester.addSetProperties("component-metadata" + componentDepthString + "/schema/job/classname",
330                     new String JavaDoc[]{"name"}, new String JavaDoc[]{"className"});
331             digester.addSetNext("component-metadata" + componentDepthString + "/schema/job", "addJob");
332
333             digester.addObjectCreate("component-metadata" + componentDepthString + "/schema/report",
334                     com.jcorporate.expresso.kernel.metadata.ReportData.class);
335             digester.addSetProperties("component-metadata" + componentDepthString + "/schema/report/classname",
336                     new String JavaDoc[]{"name"}, new String JavaDoc[]{"className"});
337             digester.addSetNext("component-metadata" + componentDepthString + "/schema/report", "addReportObject");
338
339             digester.addSetNext("component-metadata" + componentDepthString + "/schema", "setSchemaData");
340
341             if (i > 0) {
342                 digester.addSetNext("component-metadata" + componentDepthString, "addChildComponent");
343             }
344         }
345
346     }
347
348     /**
349      * Internal string to assist int hacking the digester rules....
350      *
351      * @param index how many times to repeat the rules string
352      * @return java.lang.String
353      */

354     private String JavaDoc getComponentDepthString(int index) {
355         FastStringBuffer fsb = FastStringBuffer.getInstance();
356         for (int i = 0; i < index; i++) {
357             if (i == 0) {
358                 fsb.append("/embedded-components");
359             }
360             fsb.append("/component-metadata");
361         }
362
363         String JavaDoc returnValue = fsb.toString();
364         fsb.release();
365
366         return returnValue;
367     }
368
369
370     /**
371      * Retrieve the componentMetadata that has been built via a call to
372      * loadComponentMetadata
373      *
374      * @return ComponentMetadata
375      */

376     public ComponentMetadata getMetadata() {
377         return root;
378     }
379
380 }
Popular Tags