KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.FastStringBuffer;
67 import org.apache.commons.digester.Digester;
68 import org.apache.log4j.Logger;
69 import org.xml.sax.SAXException JavaDoc;
70
71 import javax.xml.parsers.FactoryConfigurationError JavaDoc;
72 import javax.xml.parsers.ParserConfigurationException JavaDoc;
73 import java.io.File JavaDoc;
74 import java.io.FileInputStream JavaDoc;
75 import java.io.InputStream JavaDoc;
76 import java.net.URL JavaDoc;
77
78
79 /**
80  * Digester class representing the entire expresso-services.xml file
81  *
82  * @author Michael Rimov
83  */

84
85 public class ExpressoServicesConfig implements java.io.Serializable JavaDoc {
86
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     /**
96      * The log4j Logger [which is initialized by the time we get here]
97      */

98     private Logger log = Logger.getLogger(ExpressoServicesConfig.class);
99
100     /**
101      * The name of the expresso config file name
102      */

103     private String JavaDoc fileName = null;
104
105     /**
106      * The URL of expresso config file
107      */

108     private URL JavaDoc fileURL = null;
109
110     /**
111      * The root of the Component configuration tree
112      */

113     private ComponentConfig root;
114
115     /**
116      * A utility class to set the configuration of the SAX Parser
117      */

118     SaxParserConfigurer saxParserConfig;
119
120
121     /**
122      * Default Constructor
123      */

124     public ExpressoServicesConfig() {
125         saxParserConfig = new SaxParserConfigurer();
126     }
127
128     public static ExpressoServicesConfig newBlankContainer() {
129         ExpressoServicesConfig esc = new ExpressoServicesConfig();
130         esc.initBlankContainer();
131         return esc;
132     }
133
134     public void initBlankContainer() {
135         root = new ComponentConfig();
136     }
137
138     /**
139      * Loads the ExpressoServices file. When complete, call getRootConfig() to
140      * get the results of the Digesting of the configuration file.
141      */

142     public void loadExpressoServices() {
143         try {
144             javax.xml.parsers.SAXParserFactory JavaDoc spf = javax.xml.parsers.SAXParserFactory.newInstance();
145             javax.xml.parsers.SAXParser JavaDoc sp = spf.newSAXParser();
146
147             Digester digester = new Digester(sp);
148
149
150             URL JavaDoc url = this.getClass().getResource("/com/jcorporate/expresso/kernel/expresso-services_5_1.dtd");
151             if (url != null) {
152                 digester.register("-//Jcorporate Ltd//DTD Expresso Services Configuration 5.1//EN",
153                         url.toString());
154             } else {
155                 throw new IllegalArgumentException JavaDoc("Unable to locate " +
156                         "expresso-services_5_1.dtd in component package");
157             }
158
159
160             setDigesterRules(digester);
161
162             InputStream JavaDoc is;
163
164             if (fileName != null) {
165                 File JavaDoc f = new File JavaDoc(fileName);
166                 is = new FileInputStream JavaDoc(f);
167             } else if (fileURL != null) {
168                 is = fileURL.openStream();
169             } else {
170                 throw new IllegalArgumentException JavaDoc("Must set the filename to parse before loading Expresso Services");
171             }
172
173             digester.parse(is);
174         } catch (FactoryConfigurationError JavaDoc ex) {
175             log.error("Fatal error trying to find a suitable Digester compatible parser.", ex);
176         } catch (SAXException JavaDoc ex) {
177             log.error("Fatal error trying to digest expresso-services.xml file", ex);
178         } catch (ParserConfigurationException JavaDoc ex) {
179             log.error("Fatal error trying to find a suitable Digester compatible parser.", ex);
180         } catch (java.io.IOException JavaDoc ex) {
181             log.error("Fatal IO error parsing input.", ex);
182         }
183
184     }
185
186     /**
187      * Set the filename of the expresso services file to load
188      *
189      * @param fileName the file name to load the Expresso services file from
190      */

191     public void setExpressoServicesFile(String JavaDoc fileName) {
192         if (log.isDebugEnabled()) {
193             log.debug("Setting up to load Expresso Services file from: " + fileName);
194         }
195         this.fileName = fileName;
196     }
197
198     /**
199      * Retrieve the currently set Expresso Services file.
200      *
201      * @return java.lang.String
202      */

203     public String JavaDoc getExpressoServicesFile() {
204         return this.fileName;
205     }
206
207     /**
208      * Set the URL of the ExpressoServices File to load.
209      *
210      * @param url the new URL for the services file.
211      */

212     public void setExpressoServicesFile(URL JavaDoc url) {
213         if (log.isDebugEnabled()) {
214             log.debug("Setting up to load Expresso Services file from: " + url.toString());
215         }
216         this.fileURL = url;
217     }
218
219     /**
220      * Retrieve the URL of the file that currently is set for the Expresso Services
221      * file.
222      *
223      * @return java.net.URL the location of the Expresso services file
224      */

225     public URL JavaDoc getExpressoServicesFileURL() {
226         return this.fileURL;
227     }
228
229
230     /**
231      * <p>Set the rules for the digester<p>
232      * <p><b>TOTAL HACK WARNING!</b> Since Digester doesn't seem to allow recursive
233      * rules, we dynamically write rules for up to a maximum component depth of
234      * 20.</p>
235      *
236      * @param digester the digester instance to use.
237      */

238     protected void setDigesterRules(Digester digester) {
239         root = new ComponentConfig();
240         digester.push(root);
241         digester.addSetProperties("expresso-services");
242         digester.addCallMethod("expresso-services/property", "addProperty", 2);
243         digester.addCallParam("expresso-services/property", 0, "name");
244         digester.addCallParam("expresso-services/property", 1, "value");
245
246         digester.addCallMethod("expresso-services/mapped-property", "addMappedProperty", 3);
247         digester.addCallParam("expresso-services/mapped-property", 0, "name");
248         digester.addCallParam("expresso-services/mapped-property", 1, "key");
249         digester.addCallParam("expresso-services/mapped-property", 2, "value");
250
251         digester.addCallMethod("expresso-services/indexed-property", "addMappedProperty", 3);
252         digester.addCallParam("expresso-services/indexed-property", 0, "name");
253         digester.addCallParam("expresso-services/indexed-property", 1, "index");
254         digester.addCallParam("expresso-services/indexed-property", 2, "value");
255
256
257         for (int i = 0; i < MAX_NESTING; i++) {
258             String JavaDoc componentDepthString = getComponentDepthString(i);
259             digester.addObjectCreate("expresso-services/" + componentDepthString + "component",
260                     com.jcorporate.expresso.kernel.digester.ComponentConfig.class);
261             digester.addSetProperties("expresso-services/" + componentDepthString + "component",
262                     new String JavaDoc[]{"name", "class-name"}, new String JavaDoc[]{"name", "className"});
263             digester.addCallMethod("expresso-services/" + componentDepthString + "component/property", "addProperty",
264                     2);
265             digester.addCallParam("expresso-services/" + componentDepthString + "component/property", 0, "name");
266             digester.addCallParam("expresso-services/" + componentDepthString + "component/property", 1, "value");
267
268             digester.addCallMethod("expresso-services/" + componentDepthString + "component/mapped-property",
269                     "addMappedProperty", 3);
270             digester.addCallParam("expresso-services/" + componentDepthString + "component/mapped-property", 0, "name");
271             digester.addCallParam("expresso-services/" + componentDepthString + "component/mapped-property", 1, "key");
272             digester.addCallParam("expresso-services/" + componentDepthString + "component/mapped-property", 2,
273                     "value");
274
275             digester.addCallMethod("expresso-services/" + componentDepthString + "component/indexed-property",
276                     "addMappedProperty", 3);
277             digester.addCallParam("expresso-services/" + componentDepthString + "component/indexed-property", 0,
278                     "name");
279             digester.addCallParam("expresso-services/" + componentDepthString + "component/indexed-property", 1,
280                     "index");
281             digester.addCallParam("expresso-services/" + componentDepthString + "component/indexed-property", 2,
282                     "value");
283
284             digester.addSetNext("expresso-services/" + componentDepthString + "component", "addChildComponent");
285         }
286
287     }
288
289     private String JavaDoc getComponentDepthString(int index) {
290         FastStringBuffer fsb = FastStringBuffer.getInstance();
291         for (int i = 0; i < index; i++) {
292             fsb.append("component/");
293         }
294
295         String JavaDoc returnValue = fsb.toString();
296         fsb.release();
297
298         return returnValue;
299     }
300
301     /**
302      * Returns the Root of the ComponentConfig tree generated by the Digester.
303      * May be null if there was a complete error
304      *
305      * @return base of the ComponentConfig tree.
306      */

307     public ComponentConfig getRootConfig() {
308         return root;
309     }
310
311     /**
312      * Test for equality... two ExpressoServiceConfig objets are equal if all
313      * the components are the same and each ComponentConfig is completely equal.
314      * The files that are the sources DO NOT have to be equal.
315      *
316      * @param parm1 the object to compare against.
317      * @return boolean true if the two objects are indeed equal
318      */

319     public boolean equals(Object JavaDoc parm1) {
320         if (parm1 == null) {
321             return false;
322         }
323
324         if (!(parm1 instanceof ExpressoServicesConfig)) {
325             return false;
326         }
327
328         ExpressoServicesConfig other = (ExpressoServicesConfig) parm1;
329
330         ComponentConfig root = getRootConfig();
331         ComponentConfig otherRoot = other.getRootConfig();
332
333         if ((root == null) ^ (otherRoot == null)) {
334             return false;
335         }
336
337         if (root == null && otherRoot == null) {
338             return true;
339         }
340
341
342         return root.equals(otherRoot);
343     }
344
345     /**
346      * Retrieve The 'name' of the runtime configuration. This is gleaned
347      * from the root configuration element who's name is set during the
348      * xml digestion.
349      *
350      * @return java.lang.String
351      */

352     public String JavaDoc getName() {
353         return root.getName();
354     }
355
356 }
Popular Tags