KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > dd > api > application > DDProvider


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.j2ee.dd.api.application;
21
22 import java.io.IOException JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.ResourceBundle JavaDoc;
27 import javax.xml.parsers.DocumentBuilder JavaDoc;
28 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
29 import javax.xml.parsers.ParserConfigurationException JavaDoc;
30 import org.netbeans.modules.j2ee.dd.api.common.CommonDDBean;
31 import org.netbeans.modules.j2ee.dd.impl.application.ApplicationProxy;
32 import org.netbeans.modules.schema2beans.BaseBean;
33 import org.netbeans.modules.schema2beans.Common;
34 import org.openide.filesystems.FileChangeAdapter;
35 import org.openide.filesystems.FileEvent;
36 import org.openide.filesystems.FileObject;
37 import org.w3c.dom.Document JavaDoc;
38 import org.w3c.dom.DocumentType JavaDoc;
39 import org.w3c.dom.NamedNodeMap JavaDoc;
40 import org.w3c.dom.Node JavaDoc;
41 import org.w3c.dom.NodeList JavaDoc;
42 import org.xml.sax.EntityResolver JavaDoc;
43 import org.xml.sax.InputSource JavaDoc;
44 import org.xml.sax.SAXException JavaDoc;
45 import org.xml.sax.SAXParseException JavaDoc;
46
47 /**
48  * Provides access to Deployment Descriptor root ({@link org.netbeans.modules.j2ee.dd.api.ejb.EjbJar} object)
49  *
50  * @author Milan Kuchtiak
51  */

52 public final class DDProvider {
53     
54     private static final String JavaDoc APP_13_DOCTYPE = "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN"; //NOI18N
55
//private static final String EJB_11_DOCTYPE = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN"; //NOI18N
56
private static final DDProvider ddProvider = new DDProvider();
57     
58     private Map JavaDoc ddMap;
59     
60     static ResourceBundle JavaDoc bundle = ResourceBundle.getBundle("org/netbeans/modules/j2ee/dd/Bundle");
61     
62     /** Creates a new instance of EjbModule */
63     private DDProvider() {
64         //ddMap=new java.util.WeakHashMap(5);
65
ddMap = new HashMap JavaDoc(5);
66     }
67     
68     /**
69     * Accessor method for DDProvider singleton
70     * @return DDProvider object
71     */

72     public static DDProvider getDefault() {
73         return ddProvider;
74     }
75     
76     /**
77      * Returns the root of deployment descriptor bean graph for given file object.
78      * The method is useful for clients planning to read only the deployment descriptor
79      * or to listen to the changes.
80      * @param fo FileObject representing the application.xml file
81      * @return Application object - root of the deployment descriptor bean graph
82      */

83     public synchronized Application getDDRoot(FileObject fo) throws IOException JavaDoc {
84         if (fo == null) {
85             return null;
86         }
87         ApplicationProxy ejbJarProxy = null;
88         synchronized (ddMap) {
89             ejbJarProxy = getFromCache (fo);
90             if (ejbJarProxy!=null) {
91                 return ejbJarProxy;
92             }
93         }
94         
95         fo.addFileChangeListener(new FileChangeAdapter() {
96             public void fileChanged(FileEvent evt) {
97                 FileObject fo=evt.getFile();
98                 try {
99                     synchronized (ddMap) {
100                         ApplicationProxy ejbJarProxy = getFromCache (fo);
101                         String JavaDoc version = null;
102                         if (ejbJarProxy!=null) {
103                             try {
104                                 DDParse parseResult = parseDD(fo);
105                                 version = parseResult.getVersion();
106                                 setProxyErrorStatus(ejbJarProxy, parseResult);
107                                 Application newValue = createApplication(parseResult);
108                                 // replacing original file in proxy EjbJar
109
if (!version.equals(ejbJarProxy.getVersion().toString())) {
110                                     ejbJarProxy.setOriginal(newValue);
111                                 } else {// the same version
112
// replacing original file in proxy EjbJar
113
if (ejbJarProxy.getOriginal()==null) {
114                                         ejbJarProxy.setOriginal(newValue);
115                                     } else {
116                                         ejbJarProxy.getOriginal().merge(newValue,Application.MERGE_UPDATE);
117                                     }
118                                 }
119                             } catch (SAXException JavaDoc ex) {
120                                 if (ex instanceof SAXParseException JavaDoc) {
121                                     ejbJarProxy.setError((SAXParseException JavaDoc)ex);
122                                 } else if ( ex.getException() instanceof SAXParseException JavaDoc) {
123                                     ejbJarProxy.setError((SAXParseException JavaDoc)ex.getException());
124                                 }
125                                 ejbJarProxy.setStatus(Application.STATE_INVALID_UNPARSABLE);
126                                 // cbw if the state of the xml file transitions from
127
// parsable to unparsable this could be due to a user
128
// change or cvs change. We would like to still
129
// receive events when the file is restored to normal
130
// so lets not set the original to null here but wait
131
// until the file becomes parsable again to do a merge
132
//ejbJarProxy.setOriginal(null);
133
ejbJarProxy.setProxyVersion(version);
134                             }
135                         }
136                     }
137                 } catch (IOException JavaDoc ex){}
138             }
139         });
140         
141         try {
142             DDParse parseResult = parseDD(fo);
143             SAXParseException JavaDoc error = parseResult.getWarning();
144             Application original = createApplication(parseResult);
145             ejbJarProxy = new ApplicationProxy(original,parseResult.getVersion());
146             setProxyErrorStatus(ejbJarProxy, parseResult);
147         } catch (SAXException JavaDoc ex) {
148             // XXX lets throw an exception here
149
ejbJarProxy = new ApplicationProxy(org.netbeans.modules.j2ee.dd.impl.application.model_1_4.Application.createGraph(),"2.0");
150             ejbJarProxy.setStatus(Application.STATE_INVALID_UNPARSABLE);
151             if (ex instanceof SAXParseException JavaDoc) {
152                 ejbJarProxy.setError((SAXParseException JavaDoc)ex);
153             } else if ( ex.getException() instanceof SAXParseException JavaDoc) {
154                 ejbJarProxy.setError((SAXParseException JavaDoc)ex.getException());
155             }
156         }
157         ddMap.put(fo, /*new WeakReference*/ (ejbJarProxy));
158         return ejbJarProxy;
159     }
160
161     /**
162      * Returns the root of deployment descriptor bean graph for given file object.
163      * The method is useful for clients planning to modify the deployment descriptor.
164      * Finally the {@link org.netbeans.modules.j2ee.dd.api.ejb.EjbJar#write(org.openide.filesystems.FileObject)} should be used
165      * for writing the changes.
166      * @param fo FileObject representing the ejb-jar.xml file
167      * @return EjbJar object - root of the deployment descriptor bean graph
168      */

169     public Application getDDRootCopy(FileObject fo) throws IOException JavaDoc {
170         return (Application)getDDRoot(fo).clone();
171     }
172
173     private ApplicationProxy getFromCache (FileObject fo) {
174  /* WeakReference wr = (WeakReference) ddMap.get(fo);
175         if (wr == null) {
176             return null;
177         }
178         EjbJarProxy ejbJarProxy = (EjbJarProxy) wr.get ();
179         if (ejbJarProxy == null) {
180             ddMap.remove (fo);
181         }
182         return ejbJarProxy;*/

183         return (ApplicationProxy) ddMap.get(fo);
184     }
185     
186     /**
187      * Returns the root of deployment descriptor bean graph for java.io.File object.
188      *
189      * @param is source representing the ejb-jar.xml file
190      * @return EjbJar object - root of the deployment descriptor bean graph
191      */

192     public Application getDDRoot(InputSource JavaDoc is) throws IOException JavaDoc, SAXException JavaDoc {
193         DDParse parse = parseDD(is);
194         Application ejbJar = createApplication(parse);
195         ApplicationProxy proxy = new ApplicationProxy(ejbJar, ejbJar.getVersion().toString());
196         setProxyErrorStatus(proxy, parse);
197         return proxy;
198     }
199     
200     // PENDING j2eeserver needs BaseBean - this is a temporary workaround to avoid dependency of web project on DD impl
201
/**
202      * Convenient method for getting the BaseBean object from CommonDDBean object.
203      */

204     public BaseBean getBaseBean(CommonDDBean bean) {
205         if (bean instanceof BaseBean) {
206             return (BaseBean)bean;
207         } else if (bean instanceof ApplicationProxy) {
208             return (BaseBean) ((ApplicationProxy)bean).getOriginal();
209         }
210         return null;
211     }
212
213     private static void setProxyErrorStatus(ApplicationProxy ejbJarProxy, DDParse parse) {
214         SAXParseException JavaDoc error = parse.getWarning();
215         ejbJarProxy.setError(error);
216         if (error!=null) {
217             ejbJarProxy.setStatus(Application.STATE_INVALID_PARSABLE);
218         } else {
219             ejbJarProxy.setStatus(Application.STATE_VALID);
220         }
221     }
222     
223     private static Application createApplication(DDParse parse) {
224           Application jar = null;
225           String JavaDoc version = parse.getVersion();
226           if (Application.VERSION_1_4.equals(version)) {
227               return new org.netbeans.modules.j2ee.dd.impl.application.model_1_4.Application(parse.getDocument(), Common.USE_DEFAULT_VALUES);
228           } else if (Application.VERSION_1_3.equals(version)) {
229               return new org.netbeans.modules.j2ee.dd.impl.application.model_1_3.Application(parse.getDocument(), Common.USE_DEFAULT_VALUES);
230           } else if (Application.VERSION_5.equals(version)) {
231               return new org.netbeans.modules.j2ee.dd.impl.application.model_5.Application(parse.getDocument(), Common.USE_DEFAULT_VALUES);
232           }
233           
234           return jar;
235     }
236     
237     private static class DDResolver implements EntityResolver JavaDoc {
238         static DDResolver resolver;
239         static synchronized DDResolver getInstance() {
240             if (resolver==null) {
241                 resolver=new DDResolver();
242             }
243             return resolver;
244         }
245         public InputSource JavaDoc resolveEntity (String JavaDoc publicId, String JavaDoc systemId) {
246 // if (EJB_11_DOCTYPE.equals(publicId)) {
247
// return a special input source
248
// return new InputSource("nbres:/org/netbeans/modules/j2ee/dd/impl/resources/ejb-jar_1_1.dtd"); //NOI18N
249
// } else
250
if (APP_13_DOCTYPE.equals(publicId)) {
251                   // return a special input source
252
return new InputSource JavaDoc("nbres:/org/netbeans/modules/j2ee/dd/impl/resources/application_1_3.dtd"); //NOI18N
253
} else if ("http://java.sun.com/xml/ns/j2ee/application_1_4.xsd".equals(systemId)) {
254                 return new InputSource JavaDoc("nbres:/org/netbeans/modules/j2ee/dd/impl/resources/application_1_4.xsd"); //NOI18N
255
} else if ("http://java.sun.com/xml/ns/javaee/application_5.xsd".equals(systemId)) {
256                 return new InputSource JavaDoc("nbres:/org/netbeans/modules/javaee/dd/impl/resources/application_5.xsd"); //NOI18N
257
} else {
258                 // use the default behaviour
259
return null;
260             }
261         }
262     }
263     
264     private static class ErrorHandler implements org.xml.sax.ErrorHandler JavaDoc {
265         private int errorType=-1;
266         SAXParseException JavaDoc error;
267
268         public void warning(SAXParseException JavaDoc sAXParseException) throws SAXException JavaDoc {
269             if (errorType<0) {
270                 errorType=0;
271                 error=sAXParseException;
272             }
273             //throw sAXParseException;
274
}
275         public void error(SAXParseException JavaDoc sAXParseException) throws SAXException JavaDoc {
276             if (errorType<1) {
277                 errorType=1;
278                 error=sAXParseException;
279             }
280             //throw sAXParseException;
281
}
282         public void fatalError(SAXParseException JavaDoc sAXParseException) throws SAXException JavaDoc {
283             errorType=2;
284             throw sAXParseException;
285         }
286         
287         public int getErrorType() {
288             return errorType;
289         }
290         public SAXParseException JavaDoc getError() {
291             return error;
292         }
293     }
294
295     public SAXParseException JavaDoc parse(FileObject fo)
296     throws SAXException JavaDoc, IOException JavaDoc {
297         DDParse parseResult = parseDD(fo);
298         return parseResult.getWarning();
299     }
300     
301     private DDParse parseDD (FileObject fo)
302     throws SAXException JavaDoc, IOException JavaDoc {
303         return parseDD(fo.getInputStream());
304     }
305     
306     private DDParse parseDD (InputStream JavaDoc is)
307     throws SAXException JavaDoc, IOException JavaDoc {
308         return parseDD(new InputSource JavaDoc(is));
309     }
310     
311     private DDParse parseDD (InputSource JavaDoc is)
312     throws SAXException JavaDoc, IOException JavaDoc {
313         DDProvider.ErrorHandler errorHandler = new DDProvider.ErrorHandler();
314         
315         DocumentBuilder JavaDoc parser=null;
316         try {
317             DocumentBuilderFactory JavaDoc fact = DocumentBuilderFactory.newInstance();
318             parser = fact.newDocumentBuilder();
319         } catch (ParserConfigurationException JavaDoc ex) {
320             throw new SAXException JavaDoc(ex.getMessage());
321         }
322         parser.setErrorHandler(errorHandler);
323         parser.setEntityResolver(DDResolver.getInstance());
324         Document JavaDoc d = parser.parse(is);
325         SAXParseException JavaDoc error = errorHandler.getError();
326         return new DDParse(d, error);
327     }
328     
329     /**
330      * This class represents one parse of the deployment descriptor
331      */

332     private static class DDParse {
333         private final Document JavaDoc document;
334         private final SAXParseException JavaDoc saxException;
335         private String JavaDoc version;
336         public DDParse(Document JavaDoc d, SAXParseException JavaDoc saxEx) {
337             document = d;
338             saxException = saxEx;
339             extractVersion();
340         }
341         
342         /**
343          * @return document from last parse
344          */

345         public Document JavaDoc getDocument() {
346             return document;
347         }
348         
349         /**
350          * @return version of deployment descriptor.
351          */

352         private void extractVersion () {
353             // This is the default version
354
version = Application.VERSION_5;
355             
356             // first check the doc type to see if there is one
357
DocumentType JavaDoc dt = document.getDoctype();
358
359             if(dt == null) {
360                 //check application node version attribute
361
NodeList JavaDoc nl = document.getElementsByTagName("application");//NOI18N
362
if(nl != null && nl.getLength() > 0) {
363                     Node JavaDoc appNode = nl.item(0);
364                     NamedNodeMap JavaDoc attrs = appNode.getAttributes();
365                     Node JavaDoc vNode = attrs.getNamedItem("version");//NOI18N
366
if(vNode != null) {
367                         String JavaDoc versionValue = vNode.getNodeValue();
368                         if(Application.VERSION_1_4.equals(versionValue)) {
369                             version = Application.VERSION_1_4;
370                         } else if(Application.VERSION_1_3.equals(versionValue)) {
371                             version = Application.VERSION_1_3;
372                         } else {
373                             version = Application.VERSION_5; //default
374
}
375                     }
376                 }
377             } else {
378                 if (APP_13_DOCTYPE.equals(dt.getPublicId())) {
379                     version = Application.VERSION_1_3;
380                 }
381             }
382         }
383         
384         public String JavaDoc getVersion() {
385             return version;
386         }
387         
388         /**
389          * @return validation error encountered during the parse
390          */

391         public SAXParseException JavaDoc getWarning() {
392             return saxException;
393         }
394     }
395     
396 }
397
Popular Tags