KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > ant > DescriptorHandler


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if
20  * any, must include the following acknowlegement:
21  * "This product includes software developed by the
22  * Apache Software Foundation (http://www.apache.org/)."
23  * Alternately, this acknowlegement may appear in the software itself,
24  * if and wherever such third-party acknowlegements normally appear.
25  *
26  * 4. The names "Ant" and "Apache Software
27  * Foundation" must not be used to endorse or promote products derived
28  * from this software without prior written permission. For written
29  * permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache"
32  * nor may "Apache" appear in their names without prior written
33  * permission of the Apache Group.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation. For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  */

54
55 package org.objectweb.jonas.ant;
56
57 import java.io.File JavaDoc;
58 import java.io.FileInputStream JavaDoc;
59 import java.io.FileNotFoundException JavaDoc;
60 import java.io.IOException JavaDoc;
61 import java.io.InputStream JavaDoc;
62 import java.net.URL JavaDoc;
63 import java.util.Hashtable JavaDoc;
64
65 import org.apache.tools.ant.Project;
66 import org.apache.tools.ant.Task;
67 import org.xml.sax.Attributes JavaDoc;
68 import org.xml.sax.InputSource JavaDoc;
69 import org.xml.sax.SAXException JavaDoc;
70
71 /**
72  * Inner class used by EjbJar to facilitate the parsing of deployment
73  * descriptors and the capture of appropriate information. Extends
74  * HandlerBase so it only implements the methods needed. During parsing
75  * creates a hashtable consisting of entries mapping the name it should be
76  * inserted into an EJB jar as to a File representing the file on disk. This
77  * list can then be accessed through the getFiles() method.
78  */

79 public class DescriptorHandler extends org.xml.sax.helpers.DefaultHandler JavaDoc {
80     private static final int STATE_LOOKING_EJBJAR = 1;
81     private static final int STATE_IN_EJBJAR = 2;
82     private static final int STATE_IN_BEANS = 3;
83     private static final int STATE_IN_SESSION = 4;
84     private static final int STATE_IN_ENTITY = 5;
85     private static final int STATE_IN_MESSAGE = 6;
86
87     private static final int STATE_IN_SERVICE_REF = 7;
88     private static final int STATE_IN_PORT_COMPONENT_REF = 8;
89     private static final int STATE_IN_HANDLER = 9;
90
91
92     private Task owningTask;
93
94     private String JavaDoc publicId = null;
95
96     /**
97      * Bunch of constants used for storing entries in a hashtable, and for
98      * constructing the filenames of various parts of the ejb jar.
99      */

100     private static final String JavaDoc EJB_REF = "ejb-ref";
101     private static final String JavaDoc EJB_LOCAL_REF = "ejb-local-ref";
102     private static final String JavaDoc HOME_INTERFACE = "home";
103     private static final String JavaDoc REMOTE_INTERFACE = "remote";
104     private static final String JavaDoc LOCAL_HOME_INTERFACE = "local-home";
105     private static final String JavaDoc LOCAL_INTERFACE = "local";
106     private static final String JavaDoc ENDPOINT_INTERFACE = "service-endpoint";
107     private static final String JavaDoc BEAN_CLASS = "ejb-class";
108     private static final String JavaDoc PK_CLASS = "prim-key-class";
109     private static final String JavaDoc EJB_NAME = "ejb-name";
110     private static final String JavaDoc EJB_JAR = "ejb-jar";
111     private static final String JavaDoc ENTERPRISE_BEANS = "enterprise-beans";
112     private static final String JavaDoc ENTITY_BEAN = "entity";
113     private static final String JavaDoc SESSION_BEAN = "session";
114     private static final String JavaDoc MESSAGE_BEAN = "message-driven";
115
116     /**
117      * Add support for service-ref elements
118      */

119     private static final String JavaDoc SERVICE_REF = "service-ref";
120     private static final String JavaDoc SERVICE_INTERFACE = "service-interface";
121     private static final String JavaDoc WSDL_FILE = "wsdl-file";
122     private static final String JavaDoc JAXRPC_MAPPING_FILE = "jaxrpc-mapping-file";
123     private static final String JavaDoc PORT_COMPONENT_REF = "port-component-ref";
124     private static final String JavaDoc SERVICE_ENDPOINT_INTERFACE = "service-endpoint-interface";
125     private static final String JavaDoc HANDLER = "handler";
126     private static final String JavaDoc HANDLER_CLASS = "handler-class";
127
128     /**
129      * The state of the parsing
130      */

131     private int parseState = STATE_LOOKING_EJBJAR;
132
133     /**
134      * The old state of the parsing (used only for service-ref)
135      */

136     private int oldParseState;
137
138     /**
139      * Instance variable used to store the name of the current element being
140      * processed by the SAX parser. Accessed by the SAX parser call-back methods
141      * startElement() and endElement().
142      */

143     protected String JavaDoc currentElement = null;
144
145     /**
146      * The text of the current element
147      */

148     protected String JavaDoc currentText = null;
149
150     /**
151      * Instance variable that stores the names of the files as they will be
152      * put into the jar file, mapped to File objects Accessed by the SAX
153      * parser call-back method characters().
154      */

155     protected Hashtable JavaDoc ejbFiles = null;
156
157     /**
158      * Instance variable that stores the value found in the &lt;ejb-name&gt; element
159      */

160     protected String JavaDoc ejbName = null;
161
162     private Hashtable JavaDoc fileDTDs = new Hashtable JavaDoc();
163
164     private Hashtable JavaDoc resourceDTDs = new Hashtable JavaDoc();
165
166     private boolean inEJBRef = false;
167
168     private Hashtable JavaDoc urlDTDs = new Hashtable JavaDoc();
169
170     /**
171      * The directory containing the bean classes and interfaces. This is
172      * used for performing dependency file lookups.
173      */

174     private File JavaDoc srcDir;
175
176     public DescriptorHandler(Task task, File JavaDoc srcDir) {
177         this.owningTask = task;
178         this.srcDir = srcDir;
179     }
180
181     public void registerDTD(String JavaDoc publicId, String JavaDoc location) {
182         if (location == null) {
183             return;
184         }
185
186         File JavaDoc fileDTD = new File JavaDoc(location);
187         if (!fileDTD.exists()) {
188             // resolve relative to project basedir
189
fileDTD = owningTask.getProject().resolveFile(location);
190         }
191
192         if (fileDTD.exists()) {
193             if (publicId != null) {
194                 fileDTDs.put(publicId, fileDTD);
195                 owningTask.log("Mapped publicId " + publicId + " to file "
196                     + fileDTD, Project.MSG_VERBOSE);
197             }
198             return;
199         }
200
201         if (getClass().getResource(location) != null) {
202             if (publicId != null) {
203                 resourceDTDs.put(publicId, location);
204                 owningTask.log("Mapped publicId " + publicId + " to resource "
205                     + location, Project.MSG_VERBOSE);
206             }
207         }
208
209         try {
210             if (publicId != null) {
211                 URL JavaDoc urldtd = new URL JavaDoc(location);
212                 urlDTDs.put(publicId, urldtd);
213             }
214         } catch (java.net.MalformedURLException JavaDoc e) {
215             //ignored
216
}
217
218     }
219
220     public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId)
221         throws SAXException JavaDoc {
222         this.publicId = publicId;
223
224         File JavaDoc dtdFile = (File JavaDoc) fileDTDs.get(publicId);
225         if (dtdFile != null) {
226             try {
227                 owningTask.log("Resolved " + publicId + " to local file "
228                     + dtdFile, Project.MSG_VERBOSE);
229                 return new InputSource JavaDoc(new FileInputStream JavaDoc(dtdFile));
230             } catch (FileNotFoundException JavaDoc ex) {
231                 // ignore
232
}
233         }
234
235         String JavaDoc dtdResourceName = (String JavaDoc) resourceDTDs.get(publicId);
236         if (dtdResourceName != null) {
237             InputStream JavaDoc is = this.getClass().getResourceAsStream(dtdResourceName);
238             if (is != null) {
239                 owningTask.log("Resolved " + publicId + " to local resource "
240                     + dtdResourceName, Project.MSG_VERBOSE);
241                 return new InputSource JavaDoc(is);
242             }
243         }
244
245         URL JavaDoc dtdUrl = (URL JavaDoc) urlDTDs.get(publicId);
246         if (dtdUrl != null) {
247             try {
248                 InputStream JavaDoc is = dtdUrl.openStream();
249                 owningTask.log("Resolved " + publicId + " to url "
250                     + dtdUrl, Project.MSG_VERBOSE);
251                 return new InputSource JavaDoc(is);
252             } catch (IOException JavaDoc ioe) {
253                 //ignore
254
}
255         }
256
257         owningTask.log("Could not resolve ( publicId: " + publicId
258             + ", systemId: " + systemId + ") to a local entity", Project.MSG_INFO);
259
260         return null;
261     }
262
263     /**
264      * Getter method that returns the set of files to include in the EJB jar.
265      */

266     public Hashtable JavaDoc getFiles() {
267         return (ejbFiles == null) ? new Hashtable JavaDoc() : ejbFiles;
268     }
269
270     /**
271      * Get the publicId of the DTD
272      */

273     public String JavaDoc getPublicId() {
274         return publicId;
275     }
276
277      /**
278      * Getter method that returns the value of the &lt;ejb-name&gt; element.
279      */

280     public String JavaDoc getEjbName() {
281         return ejbName;
282     }
283
284     /**
285      * SAX parser call-back method that is used to initialize the values of some
286      * instance variables to ensure safe operation.
287      */

288     public void startDocument() throws SAXException JavaDoc {
289         this.ejbFiles = new Hashtable JavaDoc(10, 1);
290         this.currentElement = null;
291         inEJBRef = false;
292     }
293
294
295     /**
296      * SAX parser call-back method that is invoked when a new element is entered
297      * into. Used to store the context (attribute name) in the currentAttribute
298      * instance variable.
299      * @param uri The namespace of the element being entered.
300      * @param localname The name of the element being entered.
301      * @param qname The qname of the element being entered.
302      * @param attrs Attributes associated to the element.
303      */

304     public void startElement(String JavaDoc uri, String JavaDoc localname, String JavaDoc qname, Attributes JavaDoc attrs)
305         throws SAXException JavaDoc {
306
307         String JavaDoc name = qname;
308
309         this.currentElement = name;
310         currentText = "";
311         if (name.equals(EJB_REF) || name.equals(EJB_LOCAL_REF)) {
312             inEJBRef = true;
313         } else if (parseState == STATE_LOOKING_EJBJAR && name.equals(EJB_JAR)) {
314             parseState = STATE_IN_EJBJAR;
315         } else if (parseState == STATE_IN_EJBJAR && name.equals(ENTERPRISE_BEANS)) {
316             parseState = STATE_IN_BEANS;
317         } else if (parseState == STATE_IN_BEANS && name.equals(SESSION_BEAN)) {
318             parseState = STATE_IN_SESSION;
319         } else if (parseState == STATE_IN_BEANS && name.equals(ENTITY_BEAN)) {
320             parseState = STATE_IN_ENTITY;
321         } else if (parseState == STATE_IN_BEANS && name.equals(MESSAGE_BEAN)) {
322             parseState = STATE_IN_MESSAGE;
323         } else if ( ((parseState == STATE_IN_SESSION)
324                      || (parseState == STATE_IN_ENTITY)
325                      || (parseState == STATE_IN_MESSAGE))
326                     && (name.equals(SERVICE_REF))) {
327             oldParseState = parseState;
328             parseState = STATE_IN_SERVICE_REF;
329         } else if ((parseState == STATE_IN_SERVICE_REF)
330                    && (name.equals(PORT_COMPONENT_REF))) {
331             parseState = STATE_IN_PORT_COMPONENT_REF;
332         } else if ((parseState == STATE_IN_SERVICE_REF)
333                    && (name.equals(HANDLER))) {
334             parseState = STATE_IN_HANDLER;
335         }
336     }
337
338
339     /**
340      * SAX parser call-back method that is invoked when an element is exited.
341      * Used to blank out (set to the empty string, not nullify) the name of
342      * the currentAttribute. A better method would be to use a stack as an
343      * instance variable, however since we are only interested in leaf-node
344      * data this is a simpler and workable solution.
345      * @param name The name of the attribute being exited. Ignored
346      * in this implementation.
347      */

348     public void endElement(String JavaDoc uri, String JavaDoc localname, String JavaDoc qname) throws SAXException JavaDoc {
349         String JavaDoc name = qname;
350
351         processElement();
352         currentText = "";
353         this.currentElement = "";
354         if (name.equals(EJB_REF) || name.equals(EJB_LOCAL_REF)) {
355             inEJBRef = false;
356         } else if (parseState == STATE_IN_HANDLER && name.equals(HANDLER)) {
357             parseState = STATE_IN_SERVICE_REF;
358         } else if (parseState == STATE_IN_PORT_COMPONENT_REF && name.equals(PORT_COMPONENT_REF)) {
359             parseState = STATE_IN_SERVICE_REF;
360         } else if (parseState == STATE_IN_SERVICE_REF && name.equals(SERVICE_REF)) {
361             parseState = oldParseState;
362         } else if (parseState == STATE_IN_ENTITY && name.equals(ENTITY_BEAN)) {
363             parseState = STATE_IN_BEANS;
364         } else if (parseState == STATE_IN_SESSION && name.equals(SESSION_BEAN)) {
365             parseState = STATE_IN_BEANS;
366         } else if (parseState == STATE_IN_MESSAGE && name.equals(MESSAGE_BEAN)) {
367             parseState = STATE_IN_BEANS;
368         } else if (parseState == STATE_IN_BEANS && name.equals(ENTERPRISE_BEANS)) {
369             parseState = STATE_IN_EJBJAR;
370         } else if (parseState == STATE_IN_EJBJAR && name.equals(EJB_JAR)) {
371             parseState = STATE_LOOKING_EJBJAR;
372         }
373     }
374
375     /**
376      * SAX parser call-back method invoked whenever characters are located within
377      * an element. currentAttribute (modified by startElement and endElement)
378      * tells us whether we are in an interesting element (one of the up to four
379      * classes of an EJB). If so then converts the classname from the format
380      * org.apache.tools.ant.Parser to the convention for storing such a class,
381      * org/apache/tools/ant/Parser.class. This is then resolved into a file
382      * object under the srcdir which is stored in a Hashtable.
383      * @param ch A character array containing all the characters in
384      * the element, and maybe others that should be ignored.
385      * @param start An integer marking the position in the char
386      * array to start reading from.
387      * @param length An integer representing an offset into the
388      * char array where the current data terminates.
389      */

390     public void characters(char[] ch, int start, int length)
391         throws SAXException JavaDoc {
392
393         currentText += new String JavaDoc(ch, start, length);
394     }
395
396
397     protected void processElement() {
398         if (inEJBRef
399             || (parseState != STATE_IN_ENTITY
400                 && parseState != STATE_IN_SESSION
401                 && parseState != STATE_IN_MESSAGE
402                 && parseState != STATE_IN_SERVICE_REF
403                 && parseState != STATE_IN_PORT_COMPONENT_REF
404                 && parseState != STATE_IN_HANDLER)) {
405             return;
406         }
407
408         if (currentElement.equals(HOME_INTERFACE)
409             || currentElement.equals(REMOTE_INTERFACE)
410             || currentElement.equals(LOCAL_INTERFACE)
411             || currentElement.equals(ENDPOINT_INTERFACE)
412             || currentElement.equals(LOCAL_HOME_INTERFACE)
413             || currentElement.equals(BEAN_CLASS)
414             || currentElement.equals(PK_CLASS)
415             || currentElement.equals(SERVICE_INTERFACE)
416             || currentElement.equals(SERVICE_ENDPOINT_INTERFACE)
417             || currentElement.equals(HANDLER_CLASS)) {
418
419             // Get the filename into a String object
420
File JavaDoc classFile = null;
421             String JavaDoc className = currentText.trim();
422
423             // If it's a primitive wrapper then we shouldn't try and put
424
// it into the jar, so ignore it.
425
if (!className.startsWith("java.")
426                 && !className.startsWith("javax.")) {
427                 // Translate periods into path separators, add .class to the
428
// name, create the File object and add it to the Hashtable.
429
className = className.replace('.', File.separatorChar);
430                 className += ".class";
431                 classFile = new File JavaDoc(srcDir, className);
432                 ejbFiles.put(className, classFile);
433             }
434         }
435
436         // service-ref support for simple file
437
if (currentElement.equals(WSDL_FILE)
438             || currentElement.equals(JAXRPC_MAPPING_FILE)) {
439             //owningTask.log("***** element name : " + currentElement, Project.MSG_VERBOSE);
440
String JavaDoc filename = currentText.trim();
441             File JavaDoc file = new File JavaDoc(srcDir, filename);
442             ejbFiles.put(filename, file);
443         }
444
445         // Get the value of the <ejb-name> tag. Only the first occurrence.
446
if (currentElement.equals(EJB_NAME)) {
447             if (ejbName == null) {
448                 ejbName = currentText.trim();
449             }
450         }
451     }
452 }
453
Popular Tags