KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > convertor > ConvertorsPool


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.convertor;
21
22 import java.io.IOException JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.net.URL JavaDoc;
25 import java.util.Enumeration JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Set JavaDoc;
30 import java.util.jar.Attributes JavaDoc;
31 import java.util.jar.Manifest JavaDoc;
32 import org.netbeans.api.convertor.ConvertorDescriptor;
33 import org.netbeans.api.convertor.ConvertorException;
34 import org.netbeans.api.convertor.Convertors;
35 import org.netbeans.spi.convertor.Convertor;
36 import org.openide.ErrorManager;
37 import org.openide.modules.ModuleInfo;
38 import org.openide.util.Lookup;
39 import org.openide.util.LookupEvent;
40 import org.openide.util.LookupListener;
41 import org.w3c.dom.Document JavaDoc;
42 import org.w3c.dom.Element JavaDoc;
43
44 /**
45  *
46  * @author David Konecny
47  */

48 public class ConvertorsPool implements LookupListener {
49
50     public static final String JavaDoc NETBEANS_CONVERTOR = "NetBeans-Convertor"; // NOI18N
51
public static final String JavaDoc NETBEANS_SIMPLY_CONVERTIBLE = "NetBeans-Simply-Convertible"; // NOI18N
52
public static final String JavaDoc PROPERTIES_CONVERTOR = "PropertiesConvertor"; // NOI18N
53

54     private static final ConvertorsPool DEFAULT = new ConvertorsPool();
55     
56     private Set JavaDoc convertorDescriptors = new HashSet JavaDoc();
57     
58     private boolean initialized = false;
59
60     private Lookup.Result modules;
61     
62     private ConvertorsPool() {
63         modules = Lookup.getDefault().lookup(new Lookup.Template(ModuleInfo.class));
64         modules.allItems();
65         modules.addLookupListener(this);
66     }
67
68     public static ConvertorsPool getDefault() {
69         return DEFAULT;
70     }
71     
72     public ConvertorDescriptor getReadConvertor(String JavaDoc namespace, String JavaDoc element) {
73         assert namespace != null && element != null;
74         initConvertors();
75         Iterator JavaDoc it = convertorDescriptors.iterator();
76         while (it.hasNext()) {
77             ConvertorDescriptor cd = (ConvertorDescriptor)it.next();
78             if (namespace.equals(cd.getNamespace()) &&
79                 element.equals(cd.getElementName())) {
80                 return cd;
81             }
82         }
83         return null;
84     }
85
86     public ConvertorDescriptor getWriteConvertor(Object JavaDoc o) {
87         initConvertors();
88         Convertor convertor = null;
89         Class JavaDoc clazz = o.getClass();
90         Iterator JavaDoc it = convertorDescriptors.iterator();
91         while (it.hasNext()) {
92             ConvertorDescriptor cd = (ConvertorDescriptor)it.next();
93             if (cd.getClassName() == null || (!cd.getClassName().equals(o.getClass().getName()))) {
94                 continue;
95             }
96             Class JavaDoc cls;
97             try {
98                 cls = InstanceUtils.findClass(cd.getClassName());
99                 
100                 // ClassLoader can be null for primitive types (e.g. java.lang.Integer)
101
// No idea why, but if it is we will just skip the ClassLoader test.
102
ClassLoader JavaDoc clsLoader = cls.getClassLoader();
103                 if (clsLoader != null && !(clsLoader.loadClass(o.getClass().getName()) == o.getClass())) {
104                     ErrorManager.getDefault().log(ErrorManager.WARNING, "Object "+o+" cannot be stored by convertor "+cd+", because of classloader mismatch. Skipping convertor."); // NOI18N
105
continue;
106                 }
107             } catch (Exception JavaDoc e) {
108                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
109                 continue;
110             }
111             
112             if (clazz.equals(cls)) {
113                 return cd;
114             }
115         }
116         return null;
117     }
118     
119     public Set JavaDoc getDescriptors() {
120         initConvertors();
121         return new HashSet JavaDoc(convertorDescriptors);
122     }
123     
124     private synchronized void initConvertors() {
125         if (initialized) {
126             return;
127         }
128         loadConvertors();
129         initialized = true;
130     }
131     
132     public synchronized void resultChanged(LookupEvent ev) {
133         loadConvertors();
134     }
135     
136     private void loadConvertors() {
137         Set JavaDoc old = convertorDescriptors;
138             
139         ClassLoader JavaDoc currentClassLoader = (ClassLoader JavaDoc)Lookup.getDefault().lookup(ClassLoader JavaDoc.class);
140         Set JavaDoc convs = new HashSet JavaDoc();
141         Enumeration JavaDoc en = null;
142         try {
143             en = currentClassLoader.getResources("META-INF/MANIFEST.MF"); // NOI18N
144
} catch (IOException JavaDoc ex) {
145             ex.printStackTrace();
146             ErrorManager.getDefault().notify(ErrorManager.ERROR, ex);
147             return;
148         }
149         while (en.hasMoreElements ()) {
150             URL JavaDoc u = (URL JavaDoc)en.nextElement();
151             Manifest JavaDoc mf;
152
153             try {
154                 InputStream JavaDoc is = u.openStream();
155                 try {
156                     mf = new Manifest JavaDoc(is);
157                     loadConvertors(mf, convs);
158                 } finally {
159                     is.close();
160                 }
161             } catch (IOException JavaDoc ex) {
162                 ErrorManager.getDefault().log(ErrorManager.ERROR, "Cannot read file "+u+". The file will be ignored."); // NOI18N
163
}
164
165         }
166         convertorDescriptors = convs;
167             
168         Accessor.DEFAULT.firePropertyChange(Convertors.CONVERTOR_DESCRIPTORS, old, new HashSet JavaDoc(convertorDescriptors));
169     }
170
171     private void loadConvertors(Manifest JavaDoc m, Set JavaDoc convs) {
172         Iterator JavaDoc it = m.getEntries().entrySet().iterator(); // Iterator<Map.Entry<String,Attributes>>
173
while (it.hasNext()) {
174             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
175             String JavaDoc name = (String JavaDoc)entry.getKey();
176             Attributes JavaDoc attrs = (Attributes JavaDoc)entry.getValue();
177             if (attrs.getValue(NETBEANS_CONVERTOR) != null) {
178                 String JavaDoc convertor = getClassName(name);
179                 String JavaDoc conv;
180                 int index = 0;
181                 while (null != (conv = attrs.getValue(appendNumber(NETBEANS_CONVERTOR, index)))) {
182                     // parse following format: "{namespace}element, class"
183
int endOfNamespace = conv.indexOf('}');
184                     if (endOfNamespace == -1) {
185                         ErrorManager.getDefault().log(ErrorManager.WARNING, "Attribute "+ // NOI18N
186
appendNumber(NETBEANS_CONVERTOR, index)+
187                             " of convertor "+convertor+ // NOI18N
188
" does not contain namespace: "+conv); // NOI18N
189
break;
190                     }
191                     int startOfClass = conv.indexOf(',');
192                     String JavaDoc namespace = conv.substring(1, endOfNamespace);
193                     String JavaDoc rootElement;
194                     if (startOfClass == -1) {
195                         rootElement = conv.substring(endOfNamespace+1);
196                     } else {
197                         rootElement = conv.substring(endOfNamespace+1, startOfClass);
198                     }
199                     rootElement = rootElement.trim();
200                     if (rootElement.length() == 0) {
201                         ErrorManager.getDefault().log(ErrorManager.WARNING, "Attribute "+ // NOI18N
202
appendNumber(NETBEANS_CONVERTOR, index)+
203                             " of convertor "+convertor+ // NOI18N
204
" does not contain element: "+conv); // NOI18N
205
break;
206                     }
207                     String JavaDoc writes = null;
208                     if (startOfClass != -1) {
209                         writes = conv.substring(startOfClass+1).trim();
210                     }
211
212                     convs.add(Accessor.DEFAULT.createConvertorDescriptor(
213                         new ProxyConvertor(convertor, namespace, rootElement, writes), namespace, rootElement, writes));
214                     index++;
215                 }
216             }
217             if (attrs.getValue(NETBEANS_SIMPLY_CONVERTIBLE) != null) {
218                 String JavaDoc conv = attrs.getValue(NETBEANS_SIMPLY_CONVERTIBLE);
219                 String JavaDoc convertor = PROPERTIES_CONVERTOR;
220                 // parse following format: "{namespace}element"
221
int endOfNamespace = conv.indexOf('}');
222                 if (endOfNamespace == -1) {
223                     ErrorManager.getDefault().log(ErrorManager.WARNING, "Attribute "+ // NOI18N
224
NETBEANS_SIMPLY_CONVERTIBLE+
225                         " for class "+name+ // NOI18N
226
" does not contain namespace: "+conv); // NOI18N
227
continue;
228                 }
229                 String JavaDoc namespace = conv.substring(1, endOfNamespace);
230                 String JavaDoc rootElement = conv.substring(endOfNamespace+1);
231                 rootElement = rootElement.trim();
232                 if (rootElement.length() == 0) {
233                     ErrorManager.getDefault().log(ErrorManager.WARNING, "Attribute "+ // NOI18N
234
NETBEANS_SIMPLY_CONVERTIBLE+
235                         " for class "+name+ // NOI18N
236
" does not contain element: "+conv); // NOI18N
237
continue;
238                 }
239                 String JavaDoc writes = getClassName(name);
240                 convs.add(Accessor.DEFAULT.createConvertorDescriptor(
241                     new ProxyConvertor(convertor, namespace, rootElement, writes), namespace, rootElement, writes));
242             }
243         }
244     }
245     
246     private String JavaDoc getClassName(String JavaDoc className) {
247         className = className.replace('/', '.');
248         // this will remove ".class" and everything behind it
249
className = className.substring(0, className.indexOf(".class")); // NOI18N
250
return className;
251     }
252     
253     private String JavaDoc appendNumber(String JavaDoc name, int number) {
254         if (number == 0) {
255             return name;
256         } else {
257             return name + "-" + Integer.toString(number+1);
258         }
259     }
260     
261     private static class ProxyConvertor implements Convertor {
262         
263         private String JavaDoc convertor;
264         private String JavaDoc namespace;
265         private String JavaDoc rootElement;
266         private String JavaDoc writes;
267
268         private Convertor delegate;
269         
270         public ProxyConvertor(String JavaDoc convertor, String JavaDoc namespace, String JavaDoc rootElement, String JavaDoc writes) {
271             this.convertor = convertor;
272             this.namespace = namespace;
273             this.rootElement = rootElement;
274             this.writes = writes;
275         }
276         
277         public Object JavaDoc read(Element JavaDoc e) {
278             loadRealConvertor();
279             if (delegate == null) {
280                 throw new ConvertorException("Cannot read element. The convertor class "+convertor+" cannot be instantiated."); // NOI18N
281
}
282             return delegate.read(e);
283         }
284         
285         public Element JavaDoc write(Document JavaDoc doc, Object JavaDoc inst) {
286             loadRealConvertor();
287             if (delegate == null) {
288                 throw new ConvertorException("Cannot persist object. The convertor class "+convertor+" cannot be instantiated."); // NOI18N
289
}
290             return delegate.write(doc, inst);
291         }
292         
293         private synchronized void loadRealConvertor() {
294             if (delegate == null) {
295                 if (convertor.equals(PROPERTIES_CONVERTOR)) {
296                     delegate = new PropertiesConvertor(namespace, rootElement, writes);
297                 } else {
298                     try {
299                         Class JavaDoc c = InstanceUtils.findClass(convertor);
300                         delegate = (Convertor)c.newInstance();
301                     } catch (Exception JavaDoc e) {
302                         ErrorManager.getDefault().log(ErrorManager.WARNING, e.toString());
303                     }
304                 }
305             }
306         }
307         
308         public String JavaDoc toString() {
309             return "ProxyConvertor[convertor="+convertor+", namespace="+namespace+", rootElement="+ // NOI18N
310
rootElement+", writes="+writes+", delegate="+delegate+"] " + super.toString(); // NOI18N
311
}
312         
313     }
314     
315 }
316
Popular Tags