KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > texteditor > DocumentProviderRegistry


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.texteditor;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Hashtable JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Set JavaDoc;
21 import java.util.StringTokenizer JavaDoc;
22
23 import org.osgi.framework.Bundle;
24
25 import org.eclipse.core.resources.IFile;
26 import org.eclipse.core.runtime.CoreException;
27 import org.eclipse.core.runtime.IConfigurationElement;
28 import org.eclipse.core.runtime.IExtensionPoint;
29 import org.eclipse.core.runtime.ILog;
30 import org.eclipse.core.runtime.IStatus;
31 import org.eclipse.core.runtime.Platform;
32 import org.eclipse.core.runtime.Status;
33
34 import org.eclipse.ui.editors.text.EditorsUI;
35
36 import org.eclipse.ui.IEditorInput;
37 import org.eclipse.ui.PlatformUI;
38 import org.eclipse.ui.internal.editors.text.NLSUtility;
39
40
41 /**
42  * This registry manages shared document providers. Document
43  * providers are specified in <code>plugin.xml</code> either
44  * per name extension or per editor input type. A name extension
45  * rule always overrules an editor input type rule. Editor input
46  * type rules follow the same rules <code>IAdapterManager</code>
47  * used to find object adapters.
48  *
49  * @see org.eclipse.core.runtime.IAdapterManager
50  */

51 public class DocumentProviderRegistry {
52
53     /** The registry singleton. */
54     private static DocumentProviderRegistry fgRegistry;
55
56     /**
57      * Returns the standard document provider registry.
58      *
59      * @return the default document provider registry
60      */

61     public static DocumentProviderRegistry getDefault() {
62         if (fgRegistry == null)
63             fgRegistry= new DocumentProviderRegistry();
64         return fgRegistry;
65     }
66
67
68     /** The mapping between name extensions and configuration elements. */
69     private Map JavaDoc fExtensionMapping= new HashMap JavaDoc();
70     /** The mapping between editor input type names and configuration elements. */
71     private Map JavaDoc fInputTypeMapping= new HashMap JavaDoc();
72     /** The mapping between configuration elements and instantiated document providers. */
73     private Map JavaDoc fInstances= new HashMap JavaDoc();
74
75
76     /**
77      * Creates a new document provider registry and initializes it with the information
78      * found in the plug-in registry.
79      */

80     private DocumentProviderRegistry() {
81         initialize();
82     }
83
84     /**
85      * Reads the comma-separated value of the given configuration element
86      * for the given attribute name and remembers the configuration element
87      * in the given map under the individual tokens of the attribute value.
88      *
89      * @param map the map
90      * @param element the configuration element
91      * @param attributeName the attribute name
92      */

93     private void read(Map JavaDoc map, IConfigurationElement element, String JavaDoc attributeName) {
94         String JavaDoc value= element.getAttribute(attributeName);
95         if (value != null) {
96             StringTokenizer JavaDoc tokenizer= new StringTokenizer JavaDoc(value, ","); //$NON-NLS-1$
97
while (tokenizer.hasMoreTokens()) {
98                 String JavaDoc token= tokenizer.nextToken().trim();
99
100                 Set JavaDoc s= (Set JavaDoc) map.get(token);
101                 if (s == null) {
102                     s= new HashSet JavaDoc();
103                     map.put(token, s);
104                 }
105                 s.add(element);
106             }
107         }
108     }
109
110     /**
111      * Initializes the document provider registry. It retrieves all implementers of the <code>documentProviders</code>
112      * extension point and remembers those implementers based on the name extensions and the editor input
113      * types they are for.
114      */

115     private void initialize() {
116
117         IExtensionPoint extensionPoint;
118         extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(EditorsUI.PLUGIN_ID, "documentProviders"); //$NON-NLS-1$
119

120         if (extensionPoint == null) {
121             String JavaDoc msg= NLSUtility.format(TextEditorMessages.DocumentProviderRegistry_error_extension_point_not_found, PlatformUI.PLUGIN_ID);
122             Bundle bundle = Platform.getBundle(PlatformUI.PLUGIN_ID);
123             ILog log= Platform.getLog(bundle);
124             log.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, msg, null));
125             return;
126         }
127
128         IConfigurationElement[] elements= extensionPoint.getConfigurationElements();
129         for (int i= 0; i < elements.length; i++) {
130             read(fExtensionMapping, elements[i], "extensions"); //$NON-NLS-1$
131
read(fInputTypeMapping, elements[i], "inputTypes"); //$NON-NLS-1$
132
}
133     }
134
135     /**
136      * Returns the document provider for the given configuration element.
137      * If there is no instantiated document provider remembered for this
138      * element, a new document provider is created and put into the cache.
139      *
140      * @param entry the configuration element
141      * @return the document provider for the given entry
142      */

143     private IDocumentProvider getDocumentProvider(IConfigurationElement entry) {
144         IDocumentProvider provider= (IDocumentProvider) fInstances.get(entry);
145         if (provider == null) {
146             try {
147                 provider= (IDocumentProvider) entry.createExecutableExtension("class"); //$NON-NLS-1$
148
fInstances.put(entry, provider);
149             } catch (CoreException x) {
150             }
151         }
152         return provider;
153     }
154
155     /**
156      * Returns the first enumerated element of the given set.
157      *
158      * @param set the set
159      * @return the first configuration element in the set or <code>null</code> if none
160      */

161     private IConfigurationElement selectConfigurationElement(Set JavaDoc set) {
162         if (set != null && !set.isEmpty()) {
163             Iterator JavaDoc e= set.iterator();
164             return (IConfigurationElement) e.next();
165         }
166         return null;
167     }
168
169     /**
170      * Returns a shared document provider for the given name extension.
171      *
172      * @param extension the name extension to be used for lookup
173      * @return the shared document provider or <code>null</code>
174      */

175     public IDocumentProvider getDocumentProvider(String JavaDoc extension) {
176
177         Set JavaDoc set= (Set JavaDoc) fExtensionMapping.get(extension);
178         if (set != null) {
179             IConfigurationElement entry= selectConfigurationElement(set);
180             return getDocumentProvider(entry);
181         }
182         return null;
183     }
184
185     /**
186      * Computes the class hierarchy of the given type. The type is
187      * part of the computed hierarchy.
188      *
189      * @param type the type
190      * @return a list containing the super class hierarchy
191      */

192     private List JavaDoc computeClassList(Class JavaDoc type) {
193
194         List JavaDoc result= new ArrayList JavaDoc();
195
196         Class JavaDoc c= type;
197         while (c != null) {
198             result.add(c);
199             c= c.getSuperclass();
200         }
201
202         return result;
203     }
204
205     /**
206      * Computes the list of all interfaces for the given list of
207      * classes. The interface lists of the given classes are
208      * concatenated.
209      *
210      * @param classes a list of {@link java.lang.Class} objects
211      * @return a list with elements of type <code>Class</code>
212      */

213     private List JavaDoc computeInterfaceList(List JavaDoc classes) {
214
215         List JavaDoc result= new ArrayList JavaDoc(4);
216         Hashtable JavaDoc visited= new Hashtable JavaDoc(4);
217
218         Iterator JavaDoc e= classes.iterator();
219         while (e.hasNext()) {
220             Class JavaDoc c= (Class JavaDoc) e.next();
221             computeInterfaceList(c.getInterfaces(), result, visited);
222         }
223
224         return result;
225     }
226
227     /**
228      * Computes the list of all interfaces of the given list of interfaces,
229      * taking a depth-first approach.
230      *
231      * @param interfaces an array of {@link java.lang.Class} objects denoting interfaces
232      * @param result the result list
233      * @param visited map of visited interfaces
234      */

235     private void computeInterfaceList(Class JavaDoc[] interfaces, List JavaDoc result, Hashtable JavaDoc visited) {
236
237         List JavaDoc toBeVisited= new ArrayList JavaDoc(interfaces.length);
238
239         for (int i= 0; i < interfaces.length; i++) {
240             Class JavaDoc iface= interfaces[i];
241             if (visited.get(iface) == null) {
242                 visited.put(iface, iface);
243                 result.add(iface);
244                 toBeVisited.add(iface);
245             }
246         }
247
248         Iterator JavaDoc e= toBeVisited.iterator();
249         while(e.hasNext()) {
250             Class JavaDoc iface= (Class JavaDoc) e.next();
251             computeInterfaceList(iface.getInterfaces(), result, visited);
252         }
253     }
254
255     /**
256      * Returns the configuration elements for the first class in the list
257      * of given classes for which configuration elements have been remembered.
258      *
259      * @param classes a list of {@link java.lang.Class} objects
260      * @return an input type mapping or <code>null</code>
261      */

262     private Object JavaDoc getFirstInputTypeMapping(List JavaDoc classes) {
263         Iterator JavaDoc e= classes.iterator();
264         while (e.hasNext()) {
265             Class JavaDoc c= (Class JavaDoc) e.next();
266             Object JavaDoc mapping= fInputTypeMapping.get(c.getName());
267             if (mapping != null)
268                 return mapping;
269         }
270         return null;
271     }
272
273     /**
274      * Returns the appropriate configuration element for the given type. If
275      * there is no configuration element for the type's name, first the list of
276      * super classes is searched, and if not successful the list of all interfaces.
277      *
278      * @param type a {@link java.lang.Class} object
279      * @return an input type mapping or <code>null</code>
280      */

281     private Object JavaDoc findInputTypeMapping(Class JavaDoc type) {
282
283         if (type == null)
284             return null;
285
286         Object JavaDoc mapping= fInputTypeMapping.get(type.getName());
287         if (mapping != null)
288             return mapping;
289
290         List JavaDoc classList= computeClassList(type);
291         mapping= getFirstInputTypeMapping(classList);
292         if (mapping != null)
293             return mapping;
294
295         return getFirstInputTypeMapping(computeInterfaceList(classList));
296     }
297
298     /**
299      * Returns the shared document for the type of the given editor input.
300      *
301      * @param editorInput the input for whose type the provider is looked up
302      * @return the shared document provider
303      */

304     public IDocumentProvider getDocumentProvider(IEditorInput editorInput) {
305
306         IDocumentProvider provider= null;
307
308         IFile file= (IFile) editorInput.getAdapter(IFile.class);
309         if (file != null)
310             provider= getDocumentProvider(file.getFileExtension());
311
312         if (provider == null) {
313             Set JavaDoc set= (Set JavaDoc) findInputTypeMapping(editorInput.getClass());
314             if (set != null) {
315                 IConfigurationElement entry= selectConfigurationElement(set);
316                 provider= getDocumentProvider(entry);
317             }
318         }
319
320         return provider;
321     }
322 }
323
Popular Tags