KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > dd > api > ejb > 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.ejb;
21
22 import org.netbeans.modules.j2ee.metadata.MetadataUnit;
23 import javax.xml.parsers.DocumentBuilder JavaDoc;
24 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
25 import javax.xml.parsers.ParserConfigurationException JavaDoc;
26 import org.netbeans.modules.j2ee.dd.impl.ejb.EjbJarProxy;
27 import org.netbeans.modules.j2ee.dd.impl.common.DDProviderDataObject;
28 import org.netbeans.modules.j2ee.dd.impl.common.DDUtils;
29 import org.netbeans.modules.j2ee.dd.api.common.CommonDDBean;
30 import org.netbeans.modules.schema2beans.BaseBean;
31 import org.netbeans.modules.schema2beans.Common;
32 import org.netbeans.modules.xml.api.EncodingUtil;
33 import org.openide.filesystems.FileChangeAdapter;
34 import org.openide.filesystems.FileEvent;
35 import org.openide.filesystems.FileObject;
36 import org.openide.loaders.DataObject;
37 import org.openide.loaders.DataObjectNotFoundException;
38 import org.openide.ErrorManager;
39 import org.w3c.dom.Document JavaDoc;
40 import org.w3c.dom.DocumentType JavaDoc;
41 import org.xml.sax.EntityResolver JavaDoc;
42 import org.xml.sax.InputSource JavaDoc;
43 import org.xml.sax.SAXException JavaDoc;
44 import org.xml.sax.SAXParseException JavaDoc;
45
46 import java.io.IOException JavaDoc;
47 import java.io.InputStreamReader JavaDoc;
48 import java.io.BufferedInputStream JavaDoc;
49 import java.math.BigDecimal JavaDoc;
50 import java.util.Map JavaDoc;
51 import java.util.HashMap JavaDoc;
52 import java.net.URL JavaDoc;
53 import java.util.ArrayList JavaDoc;
54 import java.util.List JavaDoc;
55 import java.util.WeakHashMap JavaDoc;
56
57 /**
58  * Provides access to Deployment Descriptor root ({@link org.netbeans.modules.j2ee.dd.api.ejb.EjbJar} object)
59  *
60  * @author Milan Kuchtiak
61  */

62
63 public final class DDProvider {
64     private static final String JavaDoc EJB_21_DOCTYPE = "http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"; //NOI18N
65
private static final String JavaDoc EJB_20_DOCTYPE = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"; //NOI18N
66
private static final String JavaDoc EJB_11_DOCTYPE = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN"; //NOI18N
67
private static final DDProvider ddProvider = new DDProvider();
68     private Map JavaDoc ddMap;
69     private Map JavaDoc<MetadataUnit, EjbJar> annotationDDMap;
70
71     /** Creates a new instance of EjbModule */
72     private DDProvider() {
73         //ddMap=new java.util.WeakHashMap(5);
74
ddMap = new HashMap JavaDoc(5);
75         annotationDDMap = new WeakHashMap JavaDoc<MetadataUnit, EjbJar>(5);
76     }
77
78     /**
79     * Accessor method for DDProvider singleton
80     * @return DDProvider object
81     */

82     public static DDProvider getDefault() {
83         return ddProvider;
84     }
85
86     public EjbJar getMergedDDRoot(MetadataUnit mu) throws IOException JavaDoc {
87         if (mu == null) {
88             return null;
89         }
90         EjbJar xmlRoot = getDDRoot(mu.getDeploymentDescriptor());
91         // for J2ee 1.4 and lower delegate to XML-only method
92
if (xmlRoot != null && !xmlRoot.getVersion().equals(new BigDecimal JavaDoc(EjbJar.VERSION_3_0))) {
93             return xmlRoot;
94         }
95         return null;
96     }
97
98     public List JavaDoc<EjbJar> getRoots() {
99         synchronized (this) {
100             return new ArrayList JavaDoc(annotationDDMap.values());
101         }
102     }
103     
104     // used in: ddapi, ddloaders, ejbfreeform
105
/**
106      * Returns the root of deployment descriptor bean graph for given file object.
107      * The method is useful for clints planning to read only the deployment descriptor
108      * or to listen to the changes.
109      * @param fo FileObject representing the ejb-jar.xml file
110      * @return EjbJar object - root of the deployment descriptor bean graph
111      */

112     public synchronized EjbJar getDDRoot(FileObject fo) throws java.io.IOException JavaDoc {
113         if (fo == null) {
114             return null;
115         }
116         try {
117             DataObject dataObject = DataObject.find(fo);
118             if(dataObject instanceof DDProviderDataObject){
119                 return getDDRoot0((DDProviderDataObject) dataObject);
120             }
121         } catch (DataObjectNotFoundException e) {
122             return null; // should not occur
123
}
124         EjbJarProxy ejbJarProxy = null;
125         synchronized (ddMap) {
126             ejbJarProxy = getFromCache(fo);
127             if (ejbJarProxy != null) {
128                 return ejbJarProxy;
129             }
130         }
131         
132         fo.addFileChangeListener(new DDFileChangeListener());
133
134         ejbJarProxy = DDUtils.createEjbJarProxy(fo.getInputStream());
135         putToCache(fo, ejbJarProxy);
136         
137         return ejbJarProxy;
138     }
139
140     private synchronized EjbJar getDDRoot0(final DDProviderDataObject ddProviderDataObject) throws java.io.IOException JavaDoc {
141         EjbJarProxy ejbJarProxy = null;
142         synchronized (ddMap) {
143             ejbJarProxy = getFromCache(ddProviderDataObject) ;
144             if (ejbJarProxy == null) {
145                 ejbJarProxy = DDUtils.createEjbJarProxy(ddProviderDataObject.createReader());
146                 putToCache(ddProviderDataObject, ejbJarProxy);
147             }
148         }
149         return ejbJarProxy;
150     }
151
152     /**
153      * Returns the root of deployment descriptor bean graph for given file object.
154      * The method is useful for clients planning to modify the deployment descriptor.
155      * Finally the {@link org.netbeans.modules.j2ee.dd.api.ejb.EjbJar#write(org.openide.filesystems.FileObject)} should be used
156      * for writing the changes.
157      * @param fo FileObject representing the ejb-jar.xml file
158      * @return EjbJar object - root of the deployment descriptor bean graph
159      */

160     public EjbJar getDDRootCopy(FileObject fo) throws java.io.IOException JavaDoc {
161         return (EjbJar)getDDRoot(fo).clone();
162     }
163
164     private EjbJarProxy getFromCache (Object JavaDoc o) {
165         /* WeakReference wr = (WeakReference) ddMap.get(o);
166        if (wr == null) {
167            return null;
168        }
169        EjbJarProxy ejbJarProxy = (EjbJarProxy) wr.get ();
170        if (ejbJarProxy == null) {
171            ddMap.remove (o);
172        }
173        return ejbJarProxy;*/

174         return (EjbJarProxy) ddMap.get(o);
175     }
176
177     private void putToCache(Object JavaDoc o, EjbJarProxy ejbJarProxy) {
178         ddMap.put(o, /*new WeakReference*/ (ejbJarProxy));
179     }
180
181     /**
182      * Returns the root of deployment descriptor bean graph for java.io.File object.
183      *
184      * @param inputSource source representing the ejb-jar.xml file
185      * @return EjbJar object - root of the deployment descriptor bean graph
186      */

187     public EjbJar getDDRoot(InputSource JavaDoc inputSource) throws IOException JavaDoc, SAXException JavaDoc {
188         ErrorHandler errorHandler = new ErrorHandler();
189         DocumentBuilder JavaDoc parser = createParser(errorHandler);
190         parser.setEntityResolver(DDResolver.getInstance());
191         Document JavaDoc document = parser.parse(inputSource);
192         SAXParseException JavaDoc error = errorHandler.getError();
193         String JavaDoc version = extractVersion(document);
194         EjbJar original = createEjbJar(version, document);
195         EjbJarProxy ejbJarProxy = new EjbJarProxy(original, version);
196         ejbJarProxy.setError(error);
197         if (error != null) {
198             ejbJarProxy.setStatus(EjbJar.STATE_INVALID_PARSABLE);
199         } else {
200             ejbJarProxy.setStatus(EjbJar.STATE_VALID);
201         }
202         return ejbJarProxy;
203     }
204
205     // PENDING j2eeserver needs BaseBean - this is a temporary workaround to avoid dependency of web project on DD impl
206
/** Convenient method for getting the BaseBean object from CommonDDBean object
207      *
208      */

209     public BaseBean getBaseBean(CommonDDBean bean) {
210         if (bean instanceof BaseBean) {
211             return (BaseBean) bean;
212         } else if (bean instanceof EjbJarProxy) {
213             return (BaseBean) ((EjbJarProxy) bean).getOriginal();
214         }
215         return null;
216     }
217
218     private static EjbJar createEjbJar(String JavaDoc version, Document JavaDoc document) {
219         if (EjbJar.VERSION_3_0.equals(version)) {
220             return new org.netbeans.modules.j2ee.dd.impl.ejb.model_3_0.EjbJar(document, Common.USE_DEFAULT_VALUES);
221         } else if (EjbJar.VERSION_2_1.equals(version)) {
222             return new org.netbeans.modules.j2ee.dd.impl.ejb.model_2_1.EjbJar(document, Common.USE_DEFAULT_VALUES);
223         } else if (EjbJar.VERSION_2_0.equals(version)) {
224             return new org.netbeans.modules.j2ee.dd.impl.ejb.model_2_0.EjbJar(document, Common.USE_DEFAULT_VALUES);
225         } else {
226             return null;
227         }
228     }
229
230     /**
231      * Extracts version of deployment descriptor.
232      */

233     private static String JavaDoc extractVersion(Document JavaDoc document) {
234         // first check the doc type to see if there is one
235
String JavaDoc id = null;
236         DocumentType JavaDoc dt = document.getDoctype();
237         if (dt != null) {
238             // it is DTD-based
239
id = dt.getPublicId();
240         } else {
241             // it is XSD-based
242
String JavaDoc schemaLocation = document.getDocumentElement().getAttribute("xsi:schemaLocation");
243             if (schemaLocation != null) {
244                 id = schemaLocation.substring(schemaLocation.lastIndexOf(" ") + 1);
245             }
246         }
247         // This is the default version
248
if (id != null) {
249             if (EJB_21_DOCTYPE.equals(id)) {
250                 return EjbJar.VERSION_2_1;
251             }
252             if (EJB_20_DOCTYPE.equals(id)) {
253                 return EjbJar.VERSION_2_0;
254             }
255             if (EJB_11_DOCTYPE.equals(id)){
256                 return EjbJar.VERSION_1_1;
257             }
258         }
259         return EjbJar.VERSION_3_0;
260
261     }
262
263     private static DocumentBuilder JavaDoc createParser(ErrorHandler errorHandler)
264             throws SAXException JavaDoc {
265         DocumentBuilder JavaDoc parser=null;
266         try {
267             DocumentBuilderFactory JavaDoc fact = DocumentBuilderFactory.newInstance();
268             parser = fact.newDocumentBuilder();
269         } catch (ParserConfigurationException JavaDoc ex) {
270             throw new SAXException JavaDoc(ex.getMessage());
271         }
272         parser.setErrorHandler(errorHandler);
273         return parser;
274     }
275     
276     private static class DDResolver implements EntityResolver JavaDoc {
277         static DDResolver resolver;
278         static synchronized DDResolver getInstance() {
279             if (resolver==null) {
280                 resolver=new DDResolver();
281             }
282             return resolver;
283         }
284
285         public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId) {
286             // return a proper input source
287
String JavaDoc resource;
288             if (EJB_11_DOCTYPE.equals(publicId)) {
289                 resource = "/org/netbeans/modules/j2ee/dd/impl/resources/ejb-jar_1_1.dtd"; //NOI18N
290
} else if (EJB_20_DOCTYPE.equals(publicId)) {
291                 resource = "/org/netbeans/modules/j2ee/dd/impl/resources/ejb-jar_2_0.dtd"; //NOI18N
292
} else if ("http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd".equals(systemId)) {
293                 resource = "/org/netbeans/modules/j2ee/dd/impl/resources/ejb-jar_2_1.xsd"; //NOI18N
294
} else if ("http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd".equals(systemId)) {
295                 resource = "/org/netbeans/modules/j2ee/dd/impl/resources/ejb-jar_3_0.xsd"; //NOI18N
296
} else {
297                 return null;
298             }
299             URL JavaDoc url = this.getClass().getResource(resource);
300             return new InputSource JavaDoc(url.toString());
301         }
302     }
303     
304     private static class ErrorHandler implements org.xml.sax.ErrorHandler JavaDoc {
305         private int errorType=-1;
306         SAXParseException JavaDoc error;
307
308         public void warning(org.xml.sax.SAXParseException JavaDoc sAXParseException) throws org.xml.sax.SAXException JavaDoc {
309             if (errorType<0) {
310                 errorType=0;
311                 error=sAXParseException;
312             }
313             //throw sAXParseException;
314
}
315         public void error(org.xml.sax.SAXParseException JavaDoc sAXParseException) throws org.xml.sax.SAXException JavaDoc {
316             if (errorType<1) {
317                 errorType=1;
318                 error=sAXParseException;
319             }
320             //throw sAXParseException;
321
}
322         public void fatalError(org.xml.sax.SAXParseException JavaDoc sAXParseException) throws org.xml.sax.SAXException JavaDoc {
323             errorType=2;
324             throw sAXParseException;
325         }
326
327         public int getErrorType() {
328             return errorType;
329         }
330         public SAXParseException JavaDoc getError() {
331             return error;
332         }
333     }
334
335     private class DDFileChangeListener extends FileChangeAdapter {
336         public void fileChanged(FileEvent evt) {
337             FileObject fo = evt.getFile();
338             try {
339                 synchronized (ddMap) {
340                     EjbJarProxy ejbJarProxy = getFromCache(fo);
341                     if (ejbJarProxy != null) {
342                         String JavaDoc encoding = EncodingUtil.detectEncoding(new BufferedInputStream JavaDoc(fo.getInputStream()));
343                         if (encoding == null) {
344                             encoding = "UTF8";
345                         }
346                         DDUtils.merge(ejbJarProxy, new InputStreamReader JavaDoc(fo.getInputStream(), encoding));
347                     }
348                 }
349             } catch (IOException JavaDoc ex) {
350                 ErrorManager.getDefault().notify(ex);
351             }
352         }
353     }
354 }
355
Popular Tags