KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > ejb > DescriptorHandler


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18
19 package org.apache.tools.ant.taskdefs.optional.ejb;
20
21 import java.io.File JavaDoc;
22 import java.io.FileInputStream JavaDoc;
23 import java.io.FileNotFoundException JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.util.Hashtable JavaDoc;
28 import org.apache.tools.ant.Project;
29 import org.apache.tools.ant.Task;
30 import org.xml.sax.AttributeList JavaDoc;
31 import org.xml.sax.InputSource JavaDoc;
32 import org.xml.sax.SAXException JavaDoc;
33
34 /**
35  * Inner class used by EjbJar to facilitate the parsing of deployment
36  * descriptors and the capture of appropriate information. Extends
37  * HandlerBase so it only implements the methods needed. During parsing
38  * creates a hashtable consisting of entries mapping the name it should be
39  * inserted into an EJB jar as to a File representing the file on disk. This
40  * list can then be accessed through the getFiles() method.
41  */

42 public class DescriptorHandler extends org.xml.sax.HandlerBase JavaDoc {
43     private static final int DEFAULT_HASH_TABLE_SIZE = 10;
44     private static final int STATE_LOOKING_EJBJAR = 1;
45     private static final int STATE_IN_EJBJAR = 2;
46     private static final int STATE_IN_BEANS = 3;
47     private static final int STATE_IN_SESSION = 4;
48     private static final int STATE_IN_ENTITY = 5;
49     private static final int STATE_IN_MESSAGE = 6;
50
51     private Task owningTask;
52
53     private String JavaDoc publicId = null;
54
55     /**
56      * Bunch of constants used for storing entries in a hashtable, and for
57      * constructing the filenames of various parts of the ejb jar.
58      */

59     private static final String JavaDoc EJB_REF = "ejb-ref";
60     private static final String JavaDoc EJB_LOCAL_REF = "ejb-local-ref";
61     private static final String JavaDoc HOME_INTERFACE = "home";
62     private static final String JavaDoc REMOTE_INTERFACE = "remote";
63     private static final String JavaDoc LOCAL_HOME_INTERFACE = "local-home";
64     private static final String JavaDoc LOCAL_INTERFACE = "local";
65     private static final String JavaDoc BEAN_CLASS = "ejb-class";
66     private static final String JavaDoc PK_CLASS = "prim-key-class";
67     private static final String JavaDoc EJB_NAME = "ejb-name";
68     private static final String JavaDoc EJB_JAR = "ejb-jar";
69     private static final String JavaDoc ENTERPRISE_BEANS = "enterprise-beans";
70     private static final String JavaDoc ENTITY_BEAN = "entity";
71     private static final String JavaDoc SESSION_BEAN = "session";
72     private static final String JavaDoc MESSAGE_BEAN = "message-driven";
73
74     /**
75      * The state of the parsing
76      */

77     private int parseState = STATE_LOOKING_EJBJAR;
78
79     // CheckStyle:VisibilityModifier OFF - bc
80
/**
81      * Instance variable used to store the name of the current element being
82      * processed by the SAX parser. Accessed by the SAX parser call-back methods
83      * startElement() and endElement().
84      */

85     protected String JavaDoc currentElement = null;
86
87     /**
88      * The text of the current element
89      */

90     protected String JavaDoc currentText = null;
91
92     /**
93      * Instance variable that stores the names of the files as they will be
94      * put into the jar file, mapped to File objects Accessed by the SAX
95      * parser call-back method characters().
96      */

97     protected Hashtable JavaDoc ejbFiles = null;
98
99     /**
100      * Instance variable that stores the value found in the <ejb-name> element
101      */

102     protected String JavaDoc ejbName = null;
103
104     private Hashtable JavaDoc fileDTDs = new Hashtable JavaDoc();
105
106     private Hashtable JavaDoc resourceDTDs = new Hashtable JavaDoc();
107
108     private boolean inEJBRef = false;
109
110     private Hashtable JavaDoc urlDTDs = new Hashtable JavaDoc();
111     // CheckStyle:VisibilityModifier OFF - bc
112

113     /**
114      * The directory containing the bean classes and interfaces. This is
115      * used for performing dependency file lookups.
116      */

117     private File JavaDoc srcDir;
118
119     /**
120      * Constructor for DescriptorHandler.
121      * @param task the task that owns this desciptor
122      * @param srcDir the source directory
123      */

124     public DescriptorHandler(Task task, File JavaDoc srcDir) {
125         this.owningTask = task;
126         this.srcDir = srcDir;
127     }
128
129     /**
130      * Register a dtd with a location.
131      * The location is one of a filename, a resource name in the classpath, or
132      * a URL.
133      * @param publicId the public identity of the dtd
134      * @param location the location of the dtd
135      */

136     public void registerDTD(String JavaDoc publicId, String JavaDoc location) {
137         if (location == null) {
138             return;
139         }
140
141         File JavaDoc fileDTD = new File JavaDoc(location);
142         if (!fileDTD.exists()) {
143             // resolve relative to project basedir
144
fileDTD = owningTask.getProject().resolveFile(location);
145         }
146
147         if (fileDTD.exists()) {
148             if (publicId != null) {
149                 fileDTDs.put(publicId, fileDTD);
150                 owningTask.log("Mapped publicId " + publicId + " to file "
151                     + fileDTD, Project.MSG_VERBOSE);
152             }
153             return;
154         }
155
156         if (getClass().getResource(location) != null) {
157             if (publicId != null) {
158                 resourceDTDs.put(publicId, location);
159                 owningTask.log("Mapped publicId " + publicId + " to resource "
160                     + location, Project.MSG_VERBOSE);
161             }
162         }
163
164         try {
165             if (publicId != null) {
166                 URL JavaDoc urldtd = new URL JavaDoc(location);
167                 urlDTDs.put(publicId, urldtd);
168             }
169         } catch (java.net.MalformedURLException JavaDoc e) {
170             //ignored
171
}
172
173     }
174
175     /**
176      * Resolve the entity.
177      * @see org.xml.sax.EntityResolver#resolveEntity(String, String).
178      * @param publicId The public identifier, or <code>null</code>
179      * if none is available.
180      * @param systemId The system identifier provided in the XML
181      * document. Will not be <code>null</code>.
182      * @return an inputsource for this identifier
183      * @throws SAXException if there is a problem.
184      */

185     public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId)
186         throws SAXException JavaDoc {
187         this.publicId = publicId;
188
189         File JavaDoc dtdFile = (File JavaDoc) fileDTDs.get(publicId);
190         if (dtdFile != null) {
191             try {
192                 owningTask.log("Resolved " + publicId + " to local file "
193                     + dtdFile, Project.MSG_VERBOSE);
194                 return new InputSource JavaDoc(new FileInputStream JavaDoc(dtdFile));
195             } catch (FileNotFoundException JavaDoc ex) {
196                 // ignore
197
}
198         }
199
200         String JavaDoc dtdResourceName = (String JavaDoc) resourceDTDs.get(publicId);
201         if (dtdResourceName != null) {
202             InputStream JavaDoc is = this.getClass().getResourceAsStream(dtdResourceName);
203             if (is != null) {
204                 owningTask.log("Resolved " + publicId + " to local resource "
205                     + dtdResourceName, Project.MSG_VERBOSE);
206                 return new InputSource JavaDoc(is);
207             }
208         }
209
210         URL JavaDoc dtdUrl = (URL JavaDoc) urlDTDs.get(publicId);
211         if (dtdUrl != null) {
212             try {
213                 InputStream JavaDoc is = dtdUrl.openStream();
214                 owningTask.log("Resolved " + publicId + " to url "
215                     + dtdUrl, Project.MSG_VERBOSE);
216                 return new InputSource JavaDoc(is);
217             } catch (IOException JavaDoc ioe) {
218                 //ignore
219
}
220         }
221
222         owningTask.log("Could not resolve ( publicId: " + publicId
223             + ", systemId: " + systemId + ") to a local entity", Project.MSG_INFO);
224
225         return null;
226     }
227
228     /**
229      * Getter method that returns the set of files to include in the EJB jar.
230      * @return the map of files
231      */

232     public Hashtable JavaDoc getFiles() {
233         return (ejbFiles == null) ? new Hashtable JavaDoc() : ejbFiles;
234     }
235
236     /**
237      * Get the publicId of the DTD
238      * @return the public id
239      */

240     public String JavaDoc getPublicId() {
241         return publicId;
242     }
243
244      /**
245      * Getter method that returns the value of the &lt;ejb-name&gt; element.
246      * @return the ejb name
247      */

248     public String JavaDoc getEjbName() {
249         return ejbName;
250     }
251
252     /**
253      * SAX parser call-back method that is used to initialize the values of some
254      * instance variables to ensure safe operation.
255      * @throws SAXException on error
256      */

257     public void startDocument() throws SAXException JavaDoc {
258         this.ejbFiles = new Hashtable JavaDoc(DEFAULT_HASH_TABLE_SIZE, 1);
259         this.currentElement = null;
260         inEJBRef = false;
261     }
262
263
264     /**
265      * SAX parser call-back method that is invoked when a new element is entered
266      * into. Used to store the context (attribute name) in the currentAttribute
267      * instance variable.
268      * @param name The name of the element being entered.
269      * @param attrs Attributes associated to the element.
270      * @throws SAXException on error
271      */

272     public void startElement(String JavaDoc name, AttributeList JavaDoc attrs)
273         throws SAXException JavaDoc {
274         this.currentElement = name;
275         currentText = "";
276         if (name.equals(EJB_REF) || name.equals(EJB_LOCAL_REF)) {
277             inEJBRef = true;
278         } else if (parseState == STATE_LOOKING_EJBJAR && name.equals(EJB_JAR)) {
279             parseState = STATE_IN_EJBJAR;
280         } else if (parseState == STATE_IN_EJBJAR && name.equals(ENTERPRISE_BEANS)) {
281             parseState = STATE_IN_BEANS;
282         } else if (parseState == STATE_IN_BEANS && name.equals(SESSION_BEAN)) {
283             parseState = STATE_IN_SESSION;
284         } else if (parseState == STATE_IN_BEANS && name.equals(ENTITY_BEAN)) {
285             parseState = STATE_IN_ENTITY;
286         } else if (parseState == STATE_IN_BEANS && name.equals(MESSAGE_BEAN)) {
287             parseState = STATE_IN_MESSAGE;
288         }
289     }
290
291
292     /**
293      * SAX parser call-back method that is invoked when an element is exited.
294      * Used to blank out (set to the empty string, not nullify) the name of
295      * the currentAttribute. A better method would be to use a stack as an
296      * instance variable, however since we are only interested in leaf-node
297      * data this is a simpler and workable solution.
298      * @param name The name of the attribute being exited. Ignored
299      * in this implementation.
300      * @throws SAXException on error
301      */

302     public void endElement(String JavaDoc name) throws SAXException JavaDoc {
303         processElement();
304         currentText = "";
305         this.currentElement = "";
306         if (name.equals(EJB_REF) || name.equals(EJB_LOCAL_REF)) {
307             inEJBRef = false;
308         } else if (parseState == STATE_IN_ENTITY && name.equals(ENTITY_BEAN)) {
309             parseState = STATE_IN_BEANS;
310         } else if (parseState == STATE_IN_SESSION && name.equals(SESSION_BEAN)) {
311             parseState = STATE_IN_BEANS;
312         } else if (parseState == STATE_IN_MESSAGE && name.equals(MESSAGE_BEAN)) {
313             parseState = STATE_IN_BEANS;
314         } else if (parseState == STATE_IN_BEANS && name.equals(ENTERPRISE_BEANS)) {
315             parseState = STATE_IN_EJBJAR;
316         } else if (parseState == STATE_IN_EJBJAR && name.equals(EJB_JAR)) {
317             parseState = STATE_LOOKING_EJBJAR;
318         }
319     }
320
321     /**
322      * SAX parser call-back method invoked whenever characters are located within
323      * an element. currentAttribute (modified by startElement and endElement)
324      * tells us whether we are in an interesting element (one of the up to four
325      * classes of an EJB). If so then converts the classname from the format
326      * org.apache.tools.ant.Parser to the convention for storing such a class,
327      * org/apache/tools/ant/Parser.class. This is then resolved into a file
328      * object under the srcdir which is stored in a Hashtable.
329      * @param ch A character array containing all the characters in
330      * the element, and maybe others that should be ignored.
331      * @param start An integer marking the position in the char
332      * array to start reading from.
333      * @param length An integer representing an offset into the
334      * char array where the current data terminates.
335      * @throws SAXException on error
336      */

337     public void characters(char[] ch, int start, int length)
338         throws SAXException JavaDoc {
339
340         currentText += new String JavaDoc(ch, start, length);
341     }
342
343
344     /**
345      * Called when an endelement is seen.
346      * This may be overridden in derived classes.
347      * This updates the ejbfiles if the element is an interface or a bean class.
348      * This updates the ejbname if the element is an ejb name.
349      */

350     protected void processElement() {
351         if (inEJBRef
352             || (parseState != STATE_IN_ENTITY
353                 && parseState != STATE_IN_SESSION
354                 && parseState != STATE_IN_MESSAGE)) {
355             return;
356         }
357
358         if (currentElement.equals(HOME_INTERFACE)
359             || currentElement.equals(REMOTE_INTERFACE)
360             || currentElement.equals(LOCAL_INTERFACE)
361             || currentElement.equals(LOCAL_HOME_INTERFACE)
362             || currentElement.equals(BEAN_CLASS)
363             || currentElement.equals(PK_CLASS)) {
364
365             // Get the filename into a String object
366
File JavaDoc classFile = null;
367             String JavaDoc className = currentText.trim();
368
369             // If it's a primitive wrapper then we shouldn't try and put
370
// it into the jar, so ignore it.
371
if (!className.startsWith("java.")
372                 && !className.startsWith("javax.")) {
373                 // Translate periods into path separators, add .class to the
374
// name, create the File object and add it to the Hashtable.
375
className = className.replace('.', File.separatorChar);
376                 className += ".class";
377                 classFile = new File JavaDoc(srcDir, className);
378                 ejbFiles.put(className, classFile);
379             }
380         }
381
382         // Get the value of the <ejb-name> tag. Only the first occurrence.
383
if (currentElement.equals(EJB_NAME)) {
384             if (ejbName == null) {
385                 ejbName = currentText.trim();
386             }
387         }
388     }
389 }
390
Popular Tags