KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > deployment > node > SaxParserHandler


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.deployment.node;
24
25
26 import com.sun.enterprise.deployment.xml.ApplicationTagNames;
27 import org.xml.sax.SAXParseException JavaDoc;
28 import org.xml.sax.SAXNotRecognizedException JavaDoc;
29 import org.xml.sax.SAXException JavaDoc;
30 import org.xml.sax.helpers.DefaultHandler JavaDoc;
31 import org.xml.sax.helpers.NamespaceSupport JavaDoc;
32 import org.xml.sax.InputSource JavaDoc;
33 import org.xml.sax.Attributes JavaDoc;
34 import org.xml.sax.XMLReader JavaDoc;
35 import org.xml.sax.Locator JavaDoc;
36
37
38 import java.io.*;
39 import java.util.*;
40 import java.util.logging.Level JavaDoc;
41
42 import javax.xml.parsers.SAXParserFactory JavaDoc;
43 import javax.xml.parsers.SAXParser JavaDoc;
44
45 import com.sun.enterprise.deployment.node.ejb.EjbBundleNode;
46 import com.sun.enterprise.deployment.node.web.WebBundleNode;
47 import com.sun.enterprise.deployment.node.connector.ConnectorNode;
48 import com.sun.enterprise.deployment.node.appclient.AppClientNode;
49 import com.sun.enterprise.deployment.node.runtime.application.ApplicationRuntimeNode;
50 import com.sun.enterprise.deployment.node.runtime.EjbBundleRuntimeNode;
51 import com.sun.enterprise.deployment.node.runtime.web.WebBundleRuntimeNode;
52 import com.sun.enterprise.deployment.node.runtime.AppClientRuntimeNode;
53 import com.sun.enterprise.deployment.xml.DTDRegistry;
54 import com.sun.enterprise.deployment.xml.TagNames;
55 import com.sun.enterprise.deployment.xml.WebTagNames;
56 import com.sun.enterprise.deployment.util.DOLUtils;
57 import com.sun.enterprise.deployment.EnvironmentProperty;
58 import com.sun.enterprise.util.LocalStringManagerImpl;
59
60
61 /**
62  * This class implements all the callbacks for the SAX Parser in JAXP 1.1
63  *
64  * @author Jerome Dochez
65  * @version
66  */

67 public class SaxParserHandler extends DefaultHandler JavaDoc {
68
69
70     public static final String JavaDoc JAXP_SCHEMA_LANGUAGE =
71         "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
72     public static final String JavaDoc JAXP_SCHEMA_SOURCE =
73         "http://java.sun.com/xml/jaxp/properties/schemaSource";
74     public static final String JavaDoc W3C_XML_SCHEMA =
75         "http://www.w3.org/2001/XMLSchema";
76     
77     protected static Hashtable mapping = null;
78     private static Hashtable rootNodes = null;
79     private List nodes = new ArrayList();
80     public XMLNode topNode = null;
81     protected String JavaDoc publicID=null;
82     private StringBuffer JavaDoc elementData=null;
83     private Map prefixMapping=null;
84     
85     private boolean stopOnXMLErrors = false;
86
87     private boolean pushedNamespaceContext=false;
88     private NamespaceSupport JavaDoc namespaces;
89
90     // for i18N
91
private static LocalStringManagerImpl localStrings=
92         new LocalStringManagerImpl(SaxParserHandler.class);
93     
94     public SaxParserHandler() {
95         Init();
96
97         // Create helper class to manage namespace contexts.
98
namespaces = new NamespaceSupport JavaDoc();
99     }
100
101     private static void Init() {
102
103         if (mapping==null) {
104             mapping = new Hashtable();
105             rootNodes= new Hashtable();
106             
107             String JavaDoc rootNode = ApplicationNode.registerBundle(mapping);
108             rootNodes.put(rootNode, ApplicationNode.class);
109             
110             rootNode = EjbBundleNode.registerBundle(mapping);
111             rootNodes.put(rootNode, EjbBundleNode.class);
112
113         rootNode = ConnectorNode.registerBundle(mapping);
114             rootNodes.put(rootNode, ConnectorNode.class);
115             
116             rootNode = WebBundleNode.registerBundle(mapping);
117             rootNodes.put(rootNode, WebBundleNode.class);
118
119         rootNode = AppClientNode.registerBundle(mapping);
120             rootNodes.put(rootNode, AppClientNode.class);
121             
122             rootNode = WebServicesDescriptorNode.ROOT_ELEMENT.getQName();
123             rootNodes.put(rootNode, WebServicesDescriptorNode.class);
124
125             rootNode = JaxrpcMappingDescriptorNode.ROOT_ELEMENT.getQName();
126             rootNodes.put(rootNode, JaxrpcMappingDescriptorNode.class);
127             
128             rootNode = PersistenceNode.ROOT_ELEMENT.getQName();
129             rootNodes.put(rootNode, PersistenceNode.class);
130
131         rootNodes.put(com.sun.enterprise.deployment.xml.RuntimeTagNames.S1AS_APPLICATION_RUNTIME_TAG, ApplicationRuntimeNode.class);
132             ApplicationRuntimeNode.registerBundle(mapping);
133         rootNodes.put(com.sun.enterprise.deployment.xml.RuntimeTagNames.S1AS_WEB_RUNTIME_TAG, WebBundleRuntimeNode.class);
134             WebBundleRuntimeNode.registerBundle(mapping);
135         rootNodes.put(com.sun.enterprise.deployment.xml.RuntimeTagNames.S1AS_EJB_RUNTIME_TAG, EjbBundleRuntimeNode.class);
136             EjbBundleRuntimeNode.registerBundle(mapping);
137         rootNodes.put(com.sun.enterprise.deployment.xml.RuntimeTagNames.S1AS_APPCLIENT_RUNTIME_TAG, AppClientRuntimeNode.class);
138             AppClientRuntimeNode.registerBundle(mapping);
139         rootNodes.put(com.sun.enterprise.deployment.xml.RuntimeTagNames.S1AS_CONNECTOR_RUNTIME_TAG, com.sun.enterprise.deployment.node.runtime.connector.ConnectorNode.class);
140             com.sun.enterprise.deployment.node.runtime.connector.ConnectorNode.registerBundle(mapping);
141             
142             // post treatment, let's remove the URL from the DTD so we use local copies...
143
for (java.util.Enumeration JavaDoc publicIDs=mapping.keys();publicIDs.hasMoreElements();) {
144                 String JavaDoc publicID = (String JavaDoc) publicIDs.nextElement();
145                 String JavaDoc dtd = (String JavaDoc) mapping.get(publicID);
146                 mapping.put(publicID, dtd.substring(dtd.lastIndexOf('/')+1));
147             }
148         }
149     }
150     
151     public static void registerMapping(String JavaDoc publicID, String JavaDoc systemID) {
152         mapping.put(publicID, systemID);
153     }
154     
155                         
156     public InputSource JavaDoc resolveEntity(String JavaDoc publicID, String JavaDoc systemID) throws SAXException JavaDoc {
157         try {
158             if(DOLUtils.getDefaultLogger().isLoggable(Level.FINE)) {
159                 DOLUtils.getDefaultLogger().fine("Asked to resolve " + publicID + " system id = " + systemID);
160             }
161             if (publicID==null) {
162                     // unspecified schema
163
if (systemID==null || systemID.lastIndexOf('/')==systemID.length()) {
164                         return null;
165                     }
166                     
167                     String JavaDoc fileName = getSchemaURLFor(systemID.substring(systemID.lastIndexOf('/')+1));
168                     // if this is not a request for a schema located in our repository,
169
// let's hope that the hint provided by schemaLocation is correct
170
if (fileName==null) {
171                         fileName = systemID;
172                     }
173                     if(DOLUtils.getDefaultLogger().isLoggable(Level.FINE)) {
174                         DOLUtils.getDefaultLogger().fine("Resolved to " + fileName);
175                     }
176                     return new InputSource JavaDoc(fileName);
177             }
178             if (mapping.containsKey(publicID)) {
179                 this.publicID = publicID;
180                 return new InputSource JavaDoc(new BufferedInputStream(getDTDUrlFor((String JavaDoc) mapping.get(publicID))));
181             }
182         } catch(Exception JavaDoc ioe) {
183         ioe.printStackTrace();
184         throw new SAXException JavaDoc(ioe);
185         }
186         return null;
187     }
188     
189     /**
190      * Sets if the parser should stop parsing and generate an SAXPArseException
191      * when the xml parsed contains errors in regards to validation
192      */

193     public void setStopOnError(boolean stop) {
194     stopOnXMLErrors = stop;
195     }
196     
197     
198     public void error(SAXParseException JavaDoc spe) throws SAXParseException JavaDoc {
199         DOLUtils.getDefaultLogger().log(Level.SEVERE, "enterprise.deployment.backend.invalidDescriptorFailure",
200             new Object JavaDoc[] {errorReportingString , String.valueOf(spe.getLineNumber()),
201                           String.valueOf(spe.getColumnNumber()), spe.getLocalizedMessage()});
202      if (stopOnXMLErrors) {
203          throw spe;
204      }
205     }
206     
207     public void warning(SAXParseException JavaDoc spe) throws SAXParseException JavaDoc {
208         String JavaDoc x = spe.getMessage();
209     }
210     
211     public void fatalError(SAXParseException JavaDoc spe) throws SAXParseException JavaDoc {
212         DOLUtils.getDefaultLogger().log(Level.SEVERE, "enterprise.deployment.backend.invalidDescriptorFailure",
213             new Object JavaDoc[] {errorReportingString , String.valueOf(spe.getLineNumber()),
214                           String.valueOf(spe.getColumnNumber()), spe.getLocalizedMessage()});
215     if (stopOnXMLErrors) {
216         throw spe;
217     }
218     }
219     
220     /**
221      * @return the input stream for a DTD public ID
222      */

223      protected InputStream getDTDUrlFor(String JavaDoc dtdFileName) {
224      
225         String JavaDoc dtdLoc = DTDRegistry.DTD_LOCATION.replace('/', File.separatorChar);
226         File f = new File(dtdLoc +File.separatorChar+ dtdFileName);
227
228         try {
229             return new BufferedInputStream(new FileInputStream(f));
230         } catch(FileNotFoundException fnfe) {
231             DOLUtils.getDefaultLogger().fine("Cannot find DTD " + dtdFileName);
232             return null;
233         }
234      }
235     
236     /**
237      * @return an URL for the schema location for a schema indentified by the
238      * passed parameter
239      * @param the system id for the schema
240      */

241     public static String JavaDoc getSchemaURLFor(String JavaDoc schemaSystemID) throws IOException {
242         File f = getSchemaFileFor(schemaSystemID);
243         if (f!=null) {
244             return f.toURI().toURL().toString();
245         } else {
246             return null;
247         }
248     }
249     
250     /**
251      * @return a File pointer to the localtion of the schema indentified by the
252      * passed parameter
253      * @param the system id for the schema
254      */

255     public static File getSchemaFileFor(String JavaDoc schemaSystemID) throws IOException {
256         
257     if(DOLUtils.getDefaultLogger().isLoggable(Level.FINE)) {
258             DOLUtils.getDefaultLogger().fine("Getting Schema " + schemaSystemID);
259     }
260         String JavaDoc schemaLoc = DTDRegistry.SCHEMA_LOCATION.replace('/', File.separatorChar);
261         File f = new File(schemaLoc +File.separatorChar+ schemaSystemID);
262         if (!f.exists()) {
263             DOLUtils.getDefaultLogger().fine("Cannot find schema " + schemaSystemID);
264             return null;
265         }
266     return f;
267     }
268     
269     
270     public void notationDecl(java.lang.String JavaDoc name,
271                          java.lang.String JavaDoc publicId,
272                          java.lang.String JavaDoc systemId)
273                          throws SAXException JavaDoc {
274     if(DOLUtils.getDefaultLogger().isLoggable(Level.FINE)) {
275         DOLUtils.getDefaultLogger().fine("Received notation " + name + " :=: " + publicId + " :=: " + systemId);
276     }
277     }
278     
279
280     public void startPrefixMapping(String JavaDoc prefix,
281                                String JavaDoc uri)
282                         throws SAXException JavaDoc {
283
284         if (prefixMapping==null) {
285             prefixMapping = new HashMap();
286         }
287         
288         // We need one namespace context per element, but any prefix mapping
289
// callbacks occur *before* startElement is called. So, push a
290
// context on the first startPrefixMapping callback per element.
291
if( !pushedNamespaceContext ) {
292             namespaces.pushContext();
293             pushedNamespaceContext = true;
294         }
295         namespaces.declarePrefix(prefix,uri);
296         prefixMapping.put(prefix, uri);
297     }
298
299
300     public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc attributes) {
301         if( !pushedNamespaceContext ) {
302             // We need one namespae context per element, so push a context
303
// if there weren't any prefix mappings defined.
304
namespaces.pushContext();
305         }
306         // Always reset flag since next callback could be startPrefixMapping
307
// OR another startElement.
308
pushedNamespaceContext = false;
309
310         if (DOLUtils.getDefaultLogger().isLoggable(Level.FINER)) {
311             DOLUtils.getDefaultLogger().finer("start of element " + uri + " with local name "+ localName + " and " + qName);
312         }
313         XMLNode node=null;
314         elementData=new StringBuffer JavaDoc();
315         
316         if (nodes.isEmpty()) {
317             // this must be a root element...
318
Class JavaDoc rootNodeClass = (Class JavaDoc) rootNodes.get(localName);
319             if (rootNodeClass==null) {
320                 DOLUtils.getDefaultLogger().log(Level.SEVERE, "enterprise.deployment.backend.invalidDescriptorMappingFailure",
321                         new Object JavaDoc[] {localName , " not supprted !"});
322             } else {
323                 try {
324                     node = (XMLNode) rootNodeClass.newInstance();
325                     if (DOLUtils.getDefaultLogger().isLoggable(Level.FINE)) {
326                         DOLUtils.getDefaultLogger().fine("Instanciating " + node);
327                     }
328                     if (node instanceof RootXMLNode) {
329                         if (publicID!=null) {
330                             ((RootXMLNode) node).setDocType(publicID);
331                         }
332                         addPrefixMapping(node);
333                     }
334                     nodes.add(node);
335                     topNode = node;
336                     node.getDescriptor();
337                 } catch(Exception JavaDoc e) {
338                     e.printStackTrace();
339                     return;
340                 }
341             }
342         } else {
343             node = (XMLNode) nodes.get(nodes.size()-1);
344         }
345         
346         if (node!=null) {
347             XMLElement element = new XMLElement(qName, namespaces);
348             if (node.handlesElement(element)) {
349         node.startElement(element, attributes);
350             } else {
351                 if (DOLUtils.getDefaultLogger().isLoggable(Level.FINE)) {
352                     DOLUtils.getDefaultLogger().fine("Asking for new handler for " + element + " to " + node);
353                 }
354                 XMLNode newNode = node.getHandlerFor(element);
355                 if (DOLUtils.getDefaultLogger().isLoggable(Level.FINE)) {
356                     DOLUtils.getDefaultLogger().fine("Got " + newNode);
357                 }
358                 nodes.add(newNode);
359                 addPrefixMapping(newNode);
360         newNode.startElement(element, attributes);
361             }
362         }
363     }
364     
365     public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName) {
366
367         if(DOLUtils.getDefaultLogger().isLoggable(Level.FINER)) {
368             DOLUtils.getDefaultLogger().finer("End of element " + uri + " local name "+ localName + " and " + qName + " value " + elementData);
369         }
370         if (nodes.size()==0) {
371             // no more nodes to pop
372
elementData=null;
373             return;
374         }
375         XMLElement element = new XMLElement(qName, namespaces);
376         XMLNode topNode = (XMLNode) nodes.get(nodes.size()-1);
377         if (elementData!=null && (elementData.length()!=0 || allowsEmptyValue(element.getQName()))) {
378             if (DOLUtils.getDefaultLogger().isLoggable(Level.FINER)) {
379                 DOLUtils.getDefaultLogger().finer("For element " + element.getQName() + " And value " + elementData);
380             }
381             if (element.getQName().equals(WebTagNames.URL_PATTERN)) {
382                 // we need to preserve white space for url-pattern
383
topNode.setElementValue(element, elementData.toString());
384             } else if (element.getQName().equals(
385                 TagNames.ENVIRONMENT_PROPERTY_VALUE)) {
386                 Object JavaDoc envEntryDesc = topNode.getDescriptor();
387                 if (envEntryDesc != null &&
388                     envEntryDesc instanceof EnvironmentProperty) {
389                     EnvironmentProperty envProp =
390                         (EnvironmentProperty)envEntryDesc;
391                     // we need to preserve white space for env-entry-value
392
// if the env-entry-type is java.lang.String or
393
// java.lang.Character
394
if (envProp.getType() != null &&
395                         (envProp.getType().equals("java.lang.String") ||
396                          envProp.getType().equals("java.lang.Character"))) {
397                         topNode.setElementValue(element,
398                                         elementData.toString());
399                     } else {
400                         topNode.setElementValue(element,
401                                         elementData.toString().trim());
402                     }
403                 } else {
404                     topNode.setElementValue(element,
405                                         elementData.toString().trim());
406                 }
407             } else {
408                 topNode.setElementValue(element,
409                                         elementData.toString().trim());
410             }
411             elementData=null;
412         }
413         if (topNode.endElement(element)) {
414             if (DOLUtils.getDefaultLogger().isLoggable(Level.FINE)) {
415                 DOLUtils.getDefaultLogger().fine("Removing top node " + topNode);
416             }
417             nodes.remove(nodes.size()-1);
418         }
419
420         namespaces.popContext();
421         pushedNamespaceContext=false;
422     }
423     
424     public void characters(char[] ch, int start, int stop) {
425         if (elementData!=null) {
426             elementData = elementData.append(ch,start, stop);
427         }
428     }
429     
430     public XMLNode getTopNode() {
431         return topNode;
432     }
433     
434     public void setTopNode(XMLNode node) {
435         topNode = node;
436         nodes.add(node);
437     }
438     
439     private void addPrefixMapping(XMLNode node) {
440         if (prefixMapping!=null) {
441             for (Iterator itr = prefixMapping.keySet().iterator();itr.hasNext();) {
442                 String JavaDoc prefix = (String JavaDoc) itr.next();
443                 node.addPrefixMapping(prefix, (String JavaDoc) prefixMapping.get(prefix));
444             }
445             prefixMapping=null;
446         }
447     }
448
449     
450     // for test purposes
451
public static void main(String JavaDoc args[]) {
452         
453         if (args.length==0) {
454             return;
455         } else {
456             String JavaDoc fileName = args[0];
457             File inFile = new File(fileName);
458             if (!inFile.exists()) {
459                 return;
460             }
461             try {
462                 com.sun.enterprise.deployment.io.DeploymentDescriptorFile ddFile =
463                     com.sun.enterprise.deployment.io.DeploymentDescriptorFileFactory.getDDFileFor(inFile);
464
465                 long timeStart = System.currentTimeMillis();
466                 InputStream is;
467                 com.sun.enterprise.deployment.RootDeploymentDescriptor desc=null;
468                 ddFile.setXMLValidation(true);
469                 for (int i=0;i<10;i++) {
470                     is = new BufferedInputStream(new FileInputStream(inFile));
471                     desc = (com.sun.enterprise.deployment.RootDeploymentDescriptor) ddFile.read(is);
472                     is.close();
473                 }
474         if (desc!=null && args.length>1) {
475             if (args[1]!="-o") {
476             is = new BufferedInputStream(new FileInputStream(new File(args[1])));
477             ddFile = com.sun.enterprise.deployment.io.runtime.RuntimeDDFileFactory.getDDFileFor(desc);
478             ddFile.read(desc, is);
479             }
480         }
481         
482                 long timeEnd = System.currentTimeMillis();
483         
484         if (args.length>2)
485                 if (args[2].equals("-o")) {
486                     ddFile.write((com.sun.enterprise.deployment.Descriptor) desc, new File(args[3]));
487                 }
488                 
489             } catch (Throwable JavaDoc t) {
490                 t.printStackTrace();
491             }
492         }
493     }
494     
495     private String JavaDoc errorReportingString="";
496     /**
497      * Sets the error reporting context string
498      */

499     public void setErrorReportingString(String JavaDoc s) {
500         errorReportingString = s;
501     }
502        
503     /**
504      * Indicates whether the element name is one for which empty values should
505      * be recorded.
506      * <p>
507      * If there were many tags that support empty values, it might make sense to
508      * have a constant list that contains all those tag names. Then this method
509      * would search the list for the target elementName. Because this code
510      * is potentially invoked for many elements that do not support empty values,
511      * and because the list is very small at the moment, the current
512      * implementation uses an inelegant but fast equals test.
513      * <p>
514      * If the set of tags that should support empty values grows a little,
515      * extending the expression to
516      *
517      * elementName.equals(TAG_1) || elementName.equals(TAG_2) || ...
518      *
519      * might make sense. If the set of such tags grows sufficiently large, then
520      * a list-based approach might make more sense even though it might prove
521      * to be slower.
522      * @param elementName the name of the element
523      * @return boolean indicating whether empty values should be recorded for this element
524      */

525     private boolean allowsEmptyValue(String JavaDoc elementName) {
526         return (elementName.equals(ApplicationTagNames.LIBRARY_DIRECTORY));
527     }
528 }
529
Popular Tags