KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > server > ServerConfigParser


1 package com.quadcap.server;
2
3 /* Copyright 2000 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.io.BufferedInputStream JavaDoc;
42 import java.io.BufferedReader JavaDoc;
43 import java.io.FileInputStream JavaDoc;
44 import java.io.FileReader JavaDoc;
45 import java.io.IOException JavaDoc;
46
47 import java.util.ArrayList JavaDoc;
48 import java.util.Collections JavaDoc;
49 import java.util.Comparator JavaDoc;
50 import java.util.HashMap JavaDoc;
51 import java.util.Properties JavaDoc;
52
53 import org.xml.sax.AttributeList JavaDoc;
54 import org.xml.sax.DocumentHandler JavaDoc;
55 import org.xml.sax.ErrorHandler JavaDoc;
56 import org.xml.sax.InputSource JavaDoc;
57 import org.xml.sax.Parser JavaDoc;
58 import org.xml.sax.Locator JavaDoc;
59 import org.xml.sax.SAXException JavaDoc;
60 import org.xml.sax.SAXParseException JavaDoc;
61
62 import org.xml.sax.helpers.ParserFactory JavaDoc;
63
64 import com.quadcap.util.ConfigString;
65 import com.quadcap.util.Debug;
66
67 /*{com.quadcap.server.ServerConfigParser.xml}
68  *
69  * <el><name>server</name>
70  * <p>This document is used to configure and initialize QED services.</p>
71  *
72  * <el><name>service</name>
73  * <p>Each service definition has the following allowed elements.</p>
74  *
75  * <el><name>service-name</name>
76  * <p>The name of the service.</p>
77  * </el>
78  *
79  * <el><name>service-class</name>
80  * <p>The name of the Java class which implements the service.</p>
81  * </el>
82  *
83  * <el><name>service-config</name>
84  * <p>The name of a service configuration file.</p>
85  * </el>
86  *
87  * <el><name>load-on-startup</name>
88  * <p>An integer value used to control the order in which
89  * services are loaded. Lower values are started first.</p>
90  * </el>
91  *
92  * <el><name>init-parameter</name>
93  * <p>String-valued configuration parameters may be supplied to
94  * a service.</p>
95  *
96  * <el><name>param-name</name>
97  * <p>The initialization/configuration parameter name.</p>
98  * </el>
99  *
100  * <el><name>param-value</name>
101  * <p>The initialization/configuration parameter value.</p>
102  * </el>
103  * </el>
104  * </el>
105  * </el>
106  */

107
108 /**
109  * Parser the <code>server.xml</code> file to determine which services
110  * should be loaded on startup.
111  *
112  * @author Stan Bailes
113  */

114 public class ServerConfigParser implements DocumentHandler JavaDoc, ErrorHandler JavaDoc {
115     ServiceContainer container;
116     Parser JavaDoc parser;
117     Locator JavaDoc locator;
118     StringBuffer JavaDoc data = new StringBuffer JavaDoc();
119     ArrayList JavaDoc services = new ArrayList JavaDoc();
120     ServiceWrapper service = null;
121     Properties JavaDoc props = null;
122     String JavaDoc paramName = null;
123     String JavaDoc paramValue = null;
124
125     static final int INIT = 0;
126     static final int SERVER = 1;
127     static final int SERVICE = 2;
128     static final int SERVICE_NAME = 3;
129     static final int SERVICE_CLASS = 4;
130     static final int SERVICE_CONFIG = 5;
131     static final int LOAD_ON_STARTUP = 6;
132     static final int INIT_PARAMETER = 7;
133     static final int PARAM_NAME = 8;
134     static final int PARAM_VALUE = 9;
135
136
137     static HashMap JavaDoc elemMap = new HashMap JavaDoc();
138     static {
139         elemMap.put("server", new Integer JavaDoc(SERVER));
140         elemMap.put("service", new Integer JavaDoc(SERVICE));
141         elemMap.put("service-name", new Integer JavaDoc(SERVICE_NAME));
142         elemMap.put("service-class", new Integer JavaDoc(SERVICE_CLASS));
143         elemMap.put("service-config", new Integer JavaDoc(SERVICE_CONFIG));
144         elemMap.put("load-on-startup", new Integer JavaDoc(LOAD_ON_STARTUP));
145         elemMap.put("init-parameter", new Integer JavaDoc(INIT_PARAMETER));
146         elemMap.put("param-name", new Integer JavaDoc(PARAM_NAME));
147         elemMap.put("param-value", new Integer JavaDoc(PARAM_VALUE));
148     }
149
150     static final int mapElement(String JavaDoc name) {
151         Integer JavaDoc i = (Integer JavaDoc)elemMap.get(name);
152         if (i == null) return -1;
153         return i.intValue();
154     }
155
156     /**
157      * No-argument constructor. The new object needs a database connection
158      * before it can do anything useful.
159      *
160      * @exception Exception may be thrown if there's a problem constructing
161      * the XML parser.
162      */

163     public ServerConfigParser(ServiceContainer c) throws Exception JavaDoc {
164         this.container = c;
165         ConfigString ps = ConfigString.find("xml.sax.parser",
166                                             "com.quadcap.text.sax.Parser");
167
168         try {
169             ClassLoader JavaDoc cl = ClassLoader.getSystemClassLoader();
170             this.parser =
171                 (Parser JavaDoc)(Class.forName(ps.toString(), true, cl).newInstance());
172         } catch (Throwable JavaDoc t) {
173             Debug.print(t);
174         }
175     parser.setDocumentHandler(this);
176     parser.setErrorHandler(this);
177     }
178
179     /**
180      * Parse the specified file
181      *
182      * @exception may be thrown
183      */

184     public void parse(String JavaDoc fileName) throws Exception JavaDoc {
185         FileReader JavaDoc f = new FileReader JavaDoc(fileName);
186         try {
187             BufferedReader JavaDoc r = new BufferedReader JavaDoc(f);
188             InputSource JavaDoc is = new InputSource JavaDoc(r);
189             parser.parse(is);
190         } finally {
191             f.close();
192         }
193     }
194
195     /**
196      * SAX parser callback to handle XML Parser errors.
197      * This implementation just prints them
198      * to System.err.
199      *
200      * @param exception the exception generated by the parser.
201      */

202     public void error(SAXParseException JavaDoc exception) {
203     System.err.println("error");
204     exception.printStackTrace(System.err);
205     }
206
207     /**
208      * SAX parser callback to handle XML Parser fatal errors.
209      * This implementation just prints them
210      * to System.err.
211      *
212      * @param exception the exception generated by the parser.
213      */

214     public void fatalError(SAXParseException JavaDoc exception) {
215     System.err.println("fatal error");
216     exception.printStackTrace(System.err);
217     }
218
219     /**
220      * SAX parser callback to handle XML Parser fatal errors.
221      * This implementation just prints them
222      * to System.err.
223      *
224      * @param exception the exception generated by the parser.
225      */

226     public void warning(SAXParseException JavaDoc exception) {
227     System.err.println("warning");
228     exception.printStackTrace(System.err);
229     }
230
231     /**
232      * SAX parser callback to handle character data found in the
233      * parsed document.
234      *
235      * @param ch the buffer containing the parsed characters.
236      * @param star the buffer position of the first character
237      * @param length the number of characters
238      *
239      * @exception SAXException may be thrown if this data represents
240      * a database value and there's a SQL exception thrown while
241      * trying to update the underlying resultset object with this
242      * data.
243      */

244     public void characters(char[] ch, int start, int length)
245     throws SAXException JavaDoc
246     {
247     data.append(ch, start, length);
248     }
249
250     /**
251      * SAX parser callback function that is called when the end of the
252      * document is reached. This implementation does nothing.
253      */

254     public void endDocument() {
255     }
256
257     /**
258      * SAX parser callback function called for the end of an element.
259      * If this element
260      * represents the <code>&lt;database&gt;</code> element, we finish up
261      * by closing the active statement. If this element represents a table
262      * row element, we insert the current row. Otherwise, we do nothing.
263      *
264      * @param name the name of this element
265      * @exception SAXException may be thrown to wrap any underlying database
266      * exception.
267      */

268     public void endElement(String JavaDoc name) throws SAXException JavaDoc {
269         switch (mapElement(name)) {
270         case SERVER:
271             addServices();
272             break;
273         case SERVICE:
274             if (props != null) {
275                 service.setServiceProperties(props);
276                 props = null;
277             }
278             services.add(service);
279             break;
280         case SERVICE_NAME:
281             service.setServiceName(consume());
282             break;
283         case SERVICE_CLASS:
284             service.setServiceClass(consume());
285             break;
286         case LOAD_ON_STARTUP:
287             service.setLoadOnStartup(Integer.parseInt(consume()));
288             break;
289         case SERVICE_CONFIG:
290         {
291             String JavaDoc cname = consume();
292             getProps().setProperty("service.config", cname);
293             try {
294                 getProps().putAll(parseProps(cname));
295             } catch (IOException JavaDoc ex) {
296             }
297         }
298             break;
299         case PARAM_NAME:
300             paramName = consume();
301             break;
302         case PARAM_VALUE:
303             paramValue = consume();
304             break;
305         case INIT_PARAMETER:
306             if (paramName != null && paramValue != null) {
307                 getProps().put(paramName, paramValue);
308                 paramName = null;
309                 paramValue = null;
310             }
311             break;
312         default:
313             throw new SAXException JavaDoc("endElement: bad element: " + name);
314         }
315     }
316
317     final private Properties JavaDoc getProps() {
318         if (props == null) props = new Properties JavaDoc();
319         return props;
320     }
321     
322     final public static Properties JavaDoc parseProps(String JavaDoc fileName)
323         throws IOException JavaDoc
324     {
325         FileInputStream JavaDoc f = new FileInputStream JavaDoc(fileName);
326         Properties JavaDoc p = new Properties JavaDoc();
327         try {
328             BufferedInputStream JavaDoc b = new BufferedInputStream JavaDoc(f);
329             p.load(b);
330         } finally {
331             f.close();
332         }
333         return p;
334     }
335
336     /**
337      * SAX parser callback for ignorable whitespace. We just ignore it
338      *
339      * @param ch the buffer containing the parsed characters.
340      * @param star the buffer position of the first character
341      * @param length the number of characters
342      */

343     public void ignorableWhitespace(char[] ch, int start, int length) {
344     }
345
346     /**
347      * SAX parser callback for processing instructions. This implementation
348      * does nothing.
349      *
350      * @param target the processing instruction target.
351      * @param data the processing instruction data.
352      */

353     public void processingInstruction(String JavaDoc target, String JavaDoc data) {
354     }
355
356     /**
357      * SAX parser callback used to receive a document locator.
358      *
359      * @param locator the parser's locator object.
360      */

361     public void setDocumentLocator(Locator JavaDoc locator) {
362     this.locator = locator;
363     }
364
365     /**
366      * SAX parser callback for document start.
367      * This implementation does nothing.
368      */

369     public void startDocument() {
370     }
371
372     /**
373      * SAX parser callback for the start of an element. If this element
374      * represents a table row, and the table is different from the last
375      * table seen, we establish an updatable <code>ResultSet</code> for the
376      * new table which can be used to insert new rows into the table.
377      * If this element represents a table row, we move to the insert row.
378      * If this element represents a column, we remember the column name.
379      *
380      * @param name the element name
381      * @param attrs the element's attributes
382      *
383      * @exception SAXException may be thrown to wrap an underlying database
384      * error, or if there is a problem with the XML document itself.
385      */

386     public void startElement(String JavaDoc name, AttributeList JavaDoc attrs)
387     throws SAXException JavaDoc
388     {
389     data.setLength(0);
390         switch (mapElement(name)) {
391         case SERVICE:
392             service = new ServiceWrapper();
393             break;
394         default:
395             break;
396         case -1:
397             throw new SAXException JavaDoc("Unrecognized element: " + name);
398         }
399     }
400
401     /**
402      * Get and return all of the accumulated character data as a String.
403      * Reset the character data buffer to be empty.
404      */

405     final String JavaDoc consume() {
406         String JavaDoc s = data.toString().trim();
407         data.setLength(0);
408         return s;
409     }
410
411     /**
412      * At the end of the file, add the services in the specified order
413      */

414     final void addServices() throws SAXException JavaDoc {
415         Exception JavaDoc ex = null;
416         
417         Collections.sort(services, new Comparator JavaDoc() {
418             public int compare(Object JavaDoc a, Object JavaDoc b) {
419                 ServiceWrapper wa = (ServiceWrapper)a;
420                 ServiceWrapper wb = (ServiceWrapper)b;
421                 if (wa.getLoadOnStartup() < wb.getLoadOnStartup()) return -1;
422                 if (wa.getLoadOnStartup() > wb.getLoadOnStartup()) return 1;
423                 return 0;
424             }
425         });
426         for (int i = 0; i < services.size(); i++) {
427             ServiceWrapper w = (ServiceWrapper)services.get(i);
428             try {
429                 container.addService(w.getServiceName(),
430                                      w.getServiceClass(),
431                                      w.getServiceProperties());
432             } catch (Exception JavaDoc e) {
433                 ex = e;
434                 Debug.print(e);
435             }
436         }
437
438         if (ex != null) throw new SAXException JavaDoc(ex);
439     }
440 }
441
Popular Tags