source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 13.1 KB
Line 
1/*
2 * Copyright 2000-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18package org.apache.tools.ant.taskdefs.optional.ejb;
19
20import java.io.File;
21import java.io.FileInputStream;
22import java.io.FileNotFoundException;
23import java.io.IOException;
24import java.io.InputStream;
25import java.net.URL;
26import java.util.Hashtable;
27import org.apache.tools.ant.Project;
28import org.apache.tools.ant.Task;
29import org.xml.sax.AttributeList;
30import org.xml.sax.InputSource;
31import org.xml.sax.SAXException;
32
33/**
34 * Inner class used by EjbJar to facilitate the parsing of deployment
35 * descriptors and the capture of appropriate information. Extends
36 * HandlerBase so it only implements the methods needed. During parsing
37 * creates a hashtable consisting of entries mapping the name it should be
38 * inserted into an EJB jar as to a File representing the file on disk. This
39 * list can then be accessed through the getFiles() method.
40 */
41public class DescriptorHandler extends org.xml.sax.HandlerBase {
42 private static final int STATE_LOOKING_EJBJAR = 1;
43 private static final int STATE_IN_EJBJAR = 2;
44 private static final int STATE_IN_BEANS = 3;
45 private static final int STATE_IN_SESSION = 4;
46 private static final int STATE_IN_ENTITY = 5;
47 private static final int STATE_IN_MESSAGE = 6;
48
49 private Task owningTask;
50
51 private String publicId = null;
52
53 /**
54 * Bunch of constants used for storing entries in a hashtable, and for
55 * constructing the filenames of various parts of the ejb jar.
56 */
57 private static final String EJB_REF = "ejb-ref";
58 private static final String EJB_LOCAL_REF = "ejb-local-ref";
59 private static final String HOME_INTERFACE = "home";
60 private static final String REMOTE_INTERFACE = "remote";
61 private static final String LOCAL_HOME_INTERFACE = "local-home";
62 private static final String LOCAL_INTERFACE = "local";
63 private static final String BEAN_CLASS = "ejb-class";
64 private static final String PK_CLASS = "prim-key-class";
65 private static final String EJB_NAME = "ejb-name";
66 private static final String EJB_JAR = "ejb-jar";
67 private static final String ENTERPRISE_BEANS = "enterprise-beans";
68 private static final String ENTITY_BEAN = "entity";
69 private static final String SESSION_BEAN = "session";
70 private static final String MESSAGE_BEAN = "message-driven";
71
72 /**
73 * The state of the parsing
74 */
75 private int parseState = STATE_LOOKING_EJBJAR;
76
77 /**
78 * Instance variable used to store the name of the current element being
79 * processed by the SAX parser. Accessed by the SAX parser call-back methods
80 * startElement() and endElement().
81 */
82 protected String currentElement = null;
83
84 /**
85 * The text of the current element
86 */
87 protected String currentText = null;
88
89 /**
90 * Instance variable that stores the names of the files as they will be
91 * put into the jar file, mapped to File objects Accessed by the SAX
92 * parser call-back method characters().
93 */
94 protected Hashtable ejbFiles = null;
95
96 /**
97 * Instance variable that stores the value found in the <ejb-name> element
98 */
99 protected String ejbName = null;
100
101 private Hashtable fileDTDs = new Hashtable();
102
103 private Hashtable resourceDTDs = new Hashtable();
104
105 private boolean inEJBRef = false;
106
107 private Hashtable urlDTDs = new Hashtable();
108
109 /**
110 * The directory containing the bean classes and interfaces. This is
111 * used for performing dependency file lookups.
112 */
113 private File srcDir;
114
115 public DescriptorHandler(Task task, File srcDir) {
116 this.owningTask = task;
117 this.srcDir = srcDir;
118 }
119
120 public void registerDTD(String publicId, String location) {
121 if (location == null) {
122 return;
123 }
124
125 File fileDTD = new File(location);
126 if (!fileDTD.exists()) {
127 // resolve relative to project basedir
128 fileDTD = owningTask.getProject().resolveFile(location);
129 }
130
131 if (fileDTD.exists()) {
132 if (publicId != null) {
133 fileDTDs.put(publicId, fileDTD);
134 owningTask.log("Mapped publicId " + publicId + " to file "
135 + fileDTD, Project.MSG_VERBOSE);
136 }
137 return;
138 }
139
140 if (getClass().getResource(location) != null) {
141 if (publicId != null) {
142 resourceDTDs.put(publicId, location);
143 owningTask.log("Mapped publicId " + publicId + " to resource "
144 + location, Project.MSG_VERBOSE);
145 }
146 }
147
148 try {
149 if (publicId != null) {
150 URL urldtd = new URL(location);
151 urlDTDs.put(publicId, urldtd);
152 }
153 } catch (java.net.MalformedURLException e) {
154 //ignored
155 }
156
157 }
158
159 public InputSource resolveEntity(String publicId, String systemId)
160 throws SAXException {
161 this.publicId = publicId;
162
163 File dtdFile = (File) fileDTDs.get(publicId);
164 if (dtdFile != null) {
165 try {
166 owningTask.log("Resolved " + publicId + " to local file "
167 + dtdFile, Project.MSG_VERBOSE);
168 return new InputSource(new FileInputStream(dtdFile));
169 } catch (FileNotFoundException ex) {
170 // ignore
171 }
172 }
173
174 String dtdResourceName = (String) resourceDTDs.get(publicId);
175 if (dtdResourceName != null) {
176 InputStream is = this.getClass().getResourceAsStream(dtdResourceName);
177 if (is != null) {
178 owningTask.log("Resolved " + publicId + " to local resource "
179 + dtdResourceName, Project.MSG_VERBOSE);
180 return new InputSource(is);
181 }
182 }
183
184 URL dtdUrl = (URL) urlDTDs.get(publicId);
185 if (dtdUrl != null) {
186 try {
187 InputStream is = dtdUrl.openStream();
188 owningTask.log("Resolved " + publicId + " to url "
189 + dtdUrl, Project.MSG_VERBOSE);
190 return new InputSource(is);
191 } catch (IOException ioe) {
192 //ignore
193 }
194 }
195
196 owningTask.log("Could not resolve ( publicId: " + publicId
197 + ", systemId: " + systemId + ") to a local entity", Project.MSG_INFO);
198
199 return null;
200 }
201
202 /**
203 * Getter method that returns the set of files to include in the EJB jar.
204 */
205 public Hashtable getFiles() {
206 return (ejbFiles == null) ? new Hashtable() : ejbFiles;
207 }
208
209 /**
210 * Get the publicId of the DTD
211 */
212 public String getPublicId() {
213 return publicId;
214 }
215
216 /**
217 * Getter method that returns the value of the <ejb-name> element.
218 */
219 public String getEjbName() {
220 return ejbName;
221 }
222
223 /**
224 * SAX parser call-back method that is used to initialize the values of some
225 * instance variables to ensure safe operation.
226 */
227 public void startDocument() throws SAXException {
228 this.ejbFiles = new Hashtable(10, 1);
229 this.currentElement = null;
230 inEJBRef = false;
231 }
232
233
234 /**
235 * SAX parser call-back method that is invoked when a new element is entered
236 * into. Used to store the context (attribute name) in the currentAttribute
237 * instance variable.
238 * @param name The name of the element being entered.
239 * @param attrs Attributes associated to the element.
240 */
241 public void startElement(String name, AttributeList attrs)
242 throws SAXException {
243 this.currentElement = name;
244 currentText = "";
245 if (name.equals(EJB_REF) || name.equals(EJB_LOCAL_REF)) {
246 inEJBRef = true;
247 } else if (parseState == STATE_LOOKING_EJBJAR && name.equals(EJB_JAR)) {
248 parseState = STATE_IN_EJBJAR;
249 } else if (parseState == STATE_IN_EJBJAR && name.equals(ENTERPRISE_BEANS)) {
250 parseState = STATE_IN_BEANS;
251 } else if (parseState == STATE_IN_BEANS && name.equals(SESSION_BEAN)) {
252 parseState = STATE_IN_SESSION;
253 } else if (parseState == STATE_IN_BEANS && name.equals(ENTITY_BEAN)) {
254 parseState = STATE_IN_ENTITY;
255 } else if (parseState == STATE_IN_BEANS && name.equals(MESSAGE_BEAN)) {
256 parseState = STATE_IN_MESSAGE;
257 }
258 }
259
260
261 /**
262 * SAX parser call-back method that is invoked when an element is exited.
263 * Used to blank out (set to the empty string, not nullify) the name of
264 * the currentAttribute. A better method would be to use a stack as an
265 * instance variable, however since we are only interested in leaf-node
266 * data this is a simpler and workable solution.
267 * @param name The name of the attribute being exited. Ignored
268 * in this implementation.
269 */
270 public void endElement(String name) throws SAXException {
271 processElement();
272 currentText = "";
273 this.currentElement = "";
274 if (name.equals(EJB_REF) || name.equals(EJB_LOCAL_REF)) {
275 inEJBRef = false;
276 } else if (parseState == STATE_IN_ENTITY && name.equals(ENTITY_BEAN)) {
277 parseState = STATE_IN_BEANS;
278 } else if (parseState == STATE_IN_SESSION && name.equals(SESSION_BEAN)) {
279 parseState = STATE_IN_BEANS;
280 } else if (parseState == STATE_IN_MESSAGE && name.equals(MESSAGE_BEAN)) {
281 parseState = STATE_IN_BEANS;
282 } else if (parseState == STATE_IN_BEANS && name.equals(ENTERPRISE_BEANS)) {
283 parseState = STATE_IN_EJBJAR;
284 } else if (parseState == STATE_IN_EJBJAR && name.equals(EJB_JAR)) {
285 parseState = STATE_LOOKING_EJBJAR;
286 }
287 }
288
289 /**
290 * SAX parser call-back method invoked whenever characters are located within
291 * an element. currentAttribute (modified by startElement and endElement)
292 * tells us whether we are in an interesting element (one of the up to four
293 * classes of an EJB). If so then converts the classname from the format
294 * org.apache.tools.ant.Parser to the convention for storing such a class,
295 * org/apache/tools/ant/Parser.class. This is then resolved into a file
296 * object under the srcdir which is stored in a Hashtable.
297 * @param ch A character array containing all the characters in
298 * the element, and maybe others that should be ignored.
299 * @param start An integer marking the position in the char
300 * array to start reading from.
301 * @param length An integer representing an offset into the
302 * char array where the current data terminates.
303 */
304 public void characters(char[] ch, int start, int length)
305 throws SAXException {
306
307 currentText += new String(ch, start, length);
308 }
309
310
311 protected void processElement() {
312 if (inEJBRef
313 || (parseState != STATE_IN_ENTITY
314 && parseState != STATE_IN_SESSION
315 && parseState != STATE_IN_MESSAGE)) {
316 return;
317 }
318
319 if (currentElement.equals(HOME_INTERFACE)
320 || currentElement.equals(REMOTE_INTERFACE)
321 || currentElement.equals(LOCAL_INTERFACE)
322 || currentElement.equals(LOCAL_HOME_INTERFACE)
323 || currentElement.equals(BEAN_CLASS)
324 || currentElement.equals(PK_CLASS)) {
325
326 // Get the filename into a String object
327 File classFile = null;
328 String className = currentText.trim();
329
330 // If it's a primitive wrapper then we shouldn't try and put
331 // it into the jar, so ignore it.
332 if (!className.startsWith("java.")
333 && !className.startsWith("javax.")) {
334 // Translate periods into path separators, add .class to the
335 // name, create the File object and add it to the Hashtable.
336 className = className.replace('.', File.separatorChar);
337 className += ".class";
338 classFile = new File(srcDir, className);
339 ejbFiles.put(className, classFile);
340 }
341 }
342
343 // Get the value of the <ejb-name> tag. Only the first occurrence.
344 if (currentElement.equals(EJB_NAME)) {
345 if (ejbName == null) {
346 ejbName = currentText.trim();
347 }
348 }
349 }
350}
Note: See TracBrowser for help on using the repository browser.