KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > deployment > io > DeploymentDescriptorFile


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
24 package com.sun.enterprise.deployment.io;
25
26 import java.io.*;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.logging.Level JavaDoc;
30
31 import javax.xml.parsers.SAXParserFactory JavaDoc;
32 import javax.xml.parsers.SAXParser JavaDoc;
33 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
34 import javax.xml.parsers.DocumentBuilder JavaDoc;
35 import javax.xml.parsers.ParserConfigurationException JavaDoc;
36 import org.xml.sax.SAXException JavaDoc;
37 import org.xml.sax.SAXParseException JavaDoc;
38 import org.xml.sax.SAXNotRecognizedException JavaDoc;
39 import org.xml.sax.InputSource JavaDoc;
40 import org.w3c.dom.Document JavaDoc;
41 import org.w3c.dom.Element JavaDoc;
42
43 import com.sun.enterprise.deployment.node.XMLNode;
44
45 import com.sun.enterprise.deployment.Descriptor;
46 import com.sun.enterprise.deployment.deploy.shared.AbstractArchive;
47
48 import com.sun.enterprise.deployment.node.SaxParserHandler;
49 import com.sun.enterprise.deployment.node.SaxParserHandlerFactory;
50 import com.sun.enterprise.deployment.node.J2EEDocumentBuilder;
51 import com.sun.enterprise.deployment.node.RootXMLNode;
52
53 import com.sun.enterprise.util.LocalStringManagerImpl;
54 import com.sun.enterprise.util.io.FileUtils;
55 import com.sun.enterprise.deployment.util.DOLUtils;
56
57 /**
58  * This abstract class defines common behaviour for classes responsibles
59  * for loading/saving XML deployment descriptors
60  *
61  * @author Jerome Dochez
62  */

63 public abstract class DeploymentDescriptorFile {
64     
65     public final static String JavaDoc FULL_VALIDATION = "full";
66     public final static String JavaDoc PARSING_VALIDATION = "parsing";
67     
68     // should we validate the XML ?
69
private boolean xmlValidation = true;
70     
71     // error reporting level
72
private String JavaDoc validationLevel=PARSING_VALIDATION;
73     
74     // error reporting string, used for xml validation error
75
private String JavaDoc errorReportingString=null;
76     
77     // for i18N
78
private static LocalStringManagerImpl localStrings=
79         new LocalStringManagerImpl(DeploymentDescriptorFile.class);
80     
81     /** Creates a new instance of DeploymentDescriptorFile */
82     public DeploymentDescriptorFile() {
83     }
84     
85     /**
86      * @return a non validating SAX Parser to read an XML file (containing
87      * Deployment Descriptors) into DOL descriptors
88      */

89     public SAXParser JavaDoc getSAXParser() {
90         return getSAXParser(false);
91     }
92     
93     /**
94      * @return a SAX Parser to read an XML file (containing
95      * Deployment Descriptors) into DOL descriptors
96      *
97      * @param validating true if the parser should excercise DTD validation
98      */

99     public SAXParser JavaDoc getSAXParser (boolean validating) {
100         try {
101             SAXParserFactory JavaDoc spf = SAXParserFactory.newInstance();
102
103             // set the namespace awareness
104
spf.setNamespaceAware(true);
105             
106         // turn validation on for deployment descriptor XML files
107
spf.setValidating(validating);
108
109         // this feature is needed for backward compat with old DDs
110
// constructed by J2EE1.2 which used Java encoding names
111
// such as ISO8859_1 etc.
112

113             // this is a hack for a few days so people can continue runnning
114
// with crimson
115
if (spf.getClass().getName().indexOf("xerces")!=-1) {
116                 spf.setFeature(
117                     "http://apache.org/xml/features/allow-java-encodings", true);
118             } else {
119                 DOLUtils.getDefaultLogger().log(Level.WARNING, "modify your java command line to include the -Djava.endorsed.dirs option");
120             }
121         
122         try {
123         
124         // Validation part 2a: set the schema language if necessary
125
spf.setFeature("http://apache.org/xml/features/validation/schema",validating);
126         
127                 SAXParser JavaDoc sp = spf.newSAXParser();
128                 
129                 // put the default schema for this deployment file type
130
String JavaDoc path = getDefaultSchemaSource();
131                 if (path!=null) {
132                     sp.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation",path);
133                 }
134
135         // Set Xerces feature to allow dynamic validation. This prevents
136
// SAX errors from being reported when no schemaLocation attr
137
// is seen for a DTD based (J2EE1.3) XML descriptor.
138
sp.getXMLReader().setFeature(
139             "http://apache.org/xml/features/validation/dynamic", validating);
140             
141         return sp;
142         
143             } catch (SAXNotRecognizedException JavaDoc x) {
144                 // This can happen if the parser does not support JAXP 1.2
145
DOLUtils.getDefaultLogger().log(Level.SEVERE,
146                     "INFO: JAXP SAXParser property not recognized: "
147                     + SaxParserHandler.JAXP_SCHEMA_LANGUAGE);
148                  DOLUtils.getDefaultLogger().log(Level.SEVERE,
149                     "Check to see if parser conforms to JAXP 1.2 spec.");
150
151             }
152         } catch (Exception JavaDoc e) {
153             e.printStackTrace();
154             DOLUtils.getDefaultLogger().log(Level.SEVERE, "enterprise.deployment.backend.saxParserError",
155                                 new Object JavaDoc[]{e.getMessage()});
156         }
157         return null;
158     }
159     /**
160      * @return a DOM parser to read XML File into a DOM tree
161      * @param true if validation should happen
162      */

163     public DocumentBuilder JavaDoc getDocumentBuilder(boolean validating) {
164         try {
165             DocumentBuilderFactory JavaDoc dbf = DocumentBuilderFactory.newInstance();
166
167             // set the namespace awareness
168
dbf.setNamespaceAware(true);
169             
170         // turn validation on for deployment descriptor XML files
171
dbf.setValidating(validating);
172
173             // Validation part 2a: set the schema language if necessary
174
try {
175                 // put the default schema for this deployment file type
176
String JavaDoc path = getDefaultSchemaSource();
177                 if (path!=null) {
178                     dbf.setAttribute("http://apache.org/xml/properties/schema/external-schemaLocation",path);
179                 }
180                 return dbf.newDocumentBuilder();
181             } catch (ParserConfigurationException JavaDoc x) {
182                 // This can happen if the parser does not support JAXP 1.2
183
DOLUtils.getDefaultLogger().log(Level.SEVERE,
184                     "Error: JAXP DOMParser property not recognized: "
185                     + SaxParserHandler.JAXP_SCHEMA_LANGUAGE);
186                 DOLUtils.getDefaultLogger().log(Level.SEVERE,
187                     "Check to see if parser conforms to JAXP 1.2 spec.");
188
189             }
190         } catch (Exception JavaDoc e) {
191             e.printStackTrace();
192             DOLUtils.getDefaultLogger().log(Level.SEVERE, "enterprise.deployment.backend.saxParserError",
193                                 new Object JavaDoc[]{e.getMessage()});
194         }
195         return null;
196     }
197     
198     /**
199      * read and parse a J2EE Deployment Descriptor input file and
200      * return the constructed DOL descriptors for the J2EE Module
201      *
202      * @param is the input stream for the XML file
203      * @return the DOL descriptor for the J2EE Module
204      */

205     public Descriptor read(InputStream is)
206         throws IOException, SAXParseException JavaDoc {
207         return read(null, is);
208     }
209        
210     /**
211      * read and parse a J2EE Deployment Descriptor input file and
212      * return the constructed DOL descriptors for the J2EE Module
213      *
214      * @param if the read is incremental, the top node to apply the DDs to
215      * @param is the input stream for the XML file
216      * @return the DOL descriptor for the J2EE Module
217      */

218     public Descriptor read(Descriptor descriptor, File in)
219         throws IOException, SAXParseException JavaDoc {
220         
221         FileInputStream fis = new FileInputStream(in);
222         try {
223             return read(descriptor, fis);
224         } finally {
225             fis.close();
226         }
227     }
228     
229     /**
230      * read and parse a J2EE Deployment Descriptor input file and
231      * return the constructed DOL descriptors for the J2EE Module
232      *
233      * @param if the read is incremental, the top node to apply the DDs to
234      * @param is the input archive abstraction for the XML file
235      * @return the DOL descriptor for the J2EE Module
236      */

237     public Descriptor read(Descriptor descriptor, AbstractArchive in)
238         throws IOException, SAXParseException JavaDoc {
239             
240             InputStream is = in.getEntry(getDeploymentDescriptorPath());
241             try {
242                 return read(descriptor, is);
243             } finally {
244                 is.close();
245             }
246     }
247     
248     /**
249      * read and parse a J2EE Deployment Descriptor input file and
250      * return the constructed DOL descriptors for the J2EE Module
251      *
252      * @param if the read is incremental, the top node to apply the DDs to
253      * @param is the input stream for the XML file
254      * @return the DOL descriptor for the J2EE Module
255      */

256     public Descriptor read(Descriptor descriptor, InputStream is)
257         throws IOException, SAXParseException JavaDoc {
258         
259         errorReportingString = FileUtils.revertFriendlyFilenameExtension(errorReportingString);
260         String JavaDoc error = (errorReportingString == null)? errorReportingString:new File(errorReportingString).getName();
261         String JavaDoc errorReporting = localStrings.getLocalString(
262             "enterprise.deployment.io.errorcontext",
263             "archive {0} and deployment descriptor file {1}",
264             new Object JavaDoc []{ error, getDeploymentDescriptorPath()});
265         
266         SAXParser JavaDoc sp = getSAXParser(getXMLValidation());
267         SaxParserHandler dh = SaxParserHandlerFactory.newInstance();
268     if (validationLevel.equals(FULL_VALIDATION)) {
269         dh.setStopOnError(true);
270     }
271         if (descriptor!=null) {
272             dh.setTopNode(getRootXMLNode(descriptor));
273         }
274
275         dh.setErrorReportingString(errorReporting);
276         
277         InputSource JavaDoc input =new InputSource JavaDoc(is);
278         try {
279             sp.parse(input,dh);
280         } catch(SAXParseException JavaDoc e) {
281             DOLUtils.getDefaultLogger().log(Level.SEVERE, "enterprise.deployment.backend.saxParserError",
282                                 new Object JavaDoc[]{e.getMessage()});
283             
284             errorReporting += " " + e.getLocalizedMessage();
285             SAXParseException JavaDoc spe = new SAXParseException JavaDoc(errorReporting,
286                                                         e.getSystemId(),
287                                                         e.getPublicId(),
288                                                         e.getLineNumber(),
289                                                         e.getColumnNumber(),
290                                                         e);
291
292             throw spe;
293         } catch(SAXException JavaDoc e) {
294             if (e.getException()!=null) {
295                 e.getException().printStackTrace();
296             }
297             DOLUtils.getDefaultLogger().log(Level.SEVERE, "enterprise.deployment.backend.saxParserError",
298                                 new Object JavaDoc[]{e.getMessage()});
299             return null;
300         } catch (IOException e) {
301             DOLUtils.getDefaultLogger().log(Level.SEVERE, "enterprise.deployment.backend.saxParserError",
302                                 new Object JavaDoc[]{e.getMessage()});
303
304             // Let's check if the root cause of this IOException is failing to
305
// connect. If yes, it means two things:
306
// 1. The public id declared is not one of the pre-defined ones.
307
// So we need to ask user the check for typo.
308
// 2. If the user does intend to use the system id to go outside.
309
// We need to ask them to check whether they have proper
310
// access to the internet (proxy setting etc).
311
StackTraceElement JavaDoc[] stElements = e.getStackTrace();
312             for (int i = 0; i < stElements.length; i++) {
313                 StackTraceElement JavaDoc stElement = stElements[i];
314                 if (stElement.getClassName().equals("java.net.Socket") &&
315                     stElement.getMethodName().equals("connect")) {
316                     String JavaDoc msg = localStrings.getLocalString(
317                         "enterprise.deployment.can_not_locate_dtd",
318             "Unable to locate the DTD to validate your deployment descriptor file [{1}] in archive [{0}]. Please make sure the DOCTYPE is correct (no typo in public ID or system ID) and you have proper access to the Internet.",
319              new Object JavaDoc []{ error, getDeploymentDescriptorPath()});
320                     IOException ioe = new IOException(msg);
321                     ioe.initCause(e);
322                     throw ioe;
323                 }
324             }
325
326             throw e;
327         }
328         if (dh.getTopNode()!=null) {
329             Object JavaDoc topDesc = dh.getTopNode().getDescriptor();
330             if (topDesc instanceof Descriptor) {
331                 return (Descriptor) topDesc;
332             }
333         }
334         return null;
335     }
336     
337     /**
338      * @return a Document for the passed descriptor
339      * @param descriptor
340      */

341     public Document JavaDoc getDocument(Descriptor descriptor) {
342         return J2EEDocumentBuilder.getDocument(descriptor, getRootXMLNode(descriptor));
343     }
344     
345     /**
346      * writes the descriptor to an output stream
347      *
348      * @param the descriptor
349      * @param the output stream
350      */

351     public void write(Descriptor descriptor, OutputStream os) throws IOException {
352         try {
353             J2EEDocumentBuilder.write(descriptor, getRootXMLNode(descriptor), os);
354         } catch(IOException ioe) {
355             throw ioe;
356         } catch(Exception JavaDoc e) {
357             IOException ioe = new IOException(e.getMessage());
358             ioe.initCause(e);
359             throw ioe;
360         }
361     }
362     
363     /**
364      * writes the descriptor classes into a new XML file
365      *
366      * @param descriptor the DOL descriptor to write
367      * @param path the file to use
368      */

369     public void write(Descriptor descriptor, String JavaDoc path) throws IOException {
370         
371         String JavaDoc dir;
372         String JavaDoc fileName = getDeploymentDescriptorPath();
373         if (fileName.lastIndexOf('/')!=-1) {
374             dir = path + File.separator + fileName.substring(0, fileName.lastIndexOf('/'));
375             fileName = fileName.substring(fileName.lastIndexOf('/')+1);
376         } else {
377             dir = path;
378         }
379         File dirs = new File(dir.replace('/', File.separatorChar));
380         if (!dirs.exists()) {
381             dirs.mkdirs();
382         }
383         File out = new File(dirs, fileName);
384         write(descriptor, out);
385     }
386     
387     /**
388      * writes the descriptor classes into a new XML file
389      *
390      * @param descriptor the DOL descriptor to write
391      * @param out the file to use
392      */

393     public void write(Descriptor descriptor, File out) throws IOException {
394         FileOutputStream fos = new FileOutputStream(out);
395         try {
396             write(descriptor, fos );
397         } catch(Exception JavaDoc e) {
398             IOException ioe = new IOException(e.getMessage());
399             ioe.initCause(e);
400             throw ioe;
401         }
402         fos.close();
403     }
404     
405     /**
406      * @return the location of the DeploymentDescriptor file for a
407      * particular type of J2EE Archive
408      */

409     public abstract String JavaDoc getDeploymentDescriptorPath();
410         
411     /**
412      * @return a RootXMLNode responsible for handling the deployment
413      * descriptors associated with this J2EE module
414      *
415      * @param the descriptor for which we need the node
416      */

417     public abstract RootXMLNode getRootXMLNode(Descriptor descriptor);
418      
419     /**
420      * @return true if XML validation should be performed at load time
421      */

422     protected boolean getXMLValidation() {
423         return xmlValidation;
424     }
425     
426     /**
427      * sets wether XML validation should be performed at load time
428      * @param true to validate
429      */

430     public void setXMLValidation(boolean validate) {
431         xmlValidation = validate;
432     }
433     
434     /**
435     * Sets the xml validation error reporting/recovering level.
436     * The reporting level is active only when xml validation is
437     * turned on @see setXMLValidation.
438     * so far, two values can be passed, medium which reports the
439     * xml validation and continue and full which reports the
440     * xml validation and stop the xml parsing.
441     */

442     public void setXMLValidationLevel(String JavaDoc level) {
443     validationLevel = level;
444     }
445     
446     /**
447     * @return the xml validation reporting level
448     */

449     public String JavaDoc getXMLValidationLevel() {
450     return validationLevel;
451     }
452     
453     /**
454     * @return the default schema source for this deployment descriptors
455     */

456     protected String JavaDoc getDefaultSchemaSource() {
457     RootXMLNode node = getRootXMLNode(null);
458     if (node!=null) {
459         List JavaDoc<String JavaDoc> systemIDs = node.getSystemIDs();
460         if (systemIDs != null) {
461             String JavaDoc path = null;
462             for (int i = 0; i < systemIDs.size(); i++) {
463                 if (path == null) {
464                     path = systemIDs.get(i) + " ";
465                 } else {
466                     path = path + systemIDs.get(i) + " ";
467                 }
468             }
469             return path.trim();
470         }
471     }
472     return null;
473     }
474     
475     /**
476      * Sets the error reporting string
477      */

478     public void setErrorReportingString(String JavaDoc s) {
479         this.errorReportingString = s;
480     }
481     
482 }
483
Popular Tags