KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > filebuffers > ExtensionsRegistry


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.core.internal.filebuffers;
12
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet 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.eclipse.core.runtime.Assert;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IConfigurationElement;
26 import org.eclipse.core.runtime.IExtensionPoint;
27 import org.eclipse.core.runtime.ILog;
28 import org.eclipse.core.runtime.IPath;
29 import org.eclipse.core.runtime.IStatus;
30 import org.eclipse.core.runtime.Platform;
31 import org.eclipse.core.runtime.Status;
32 import org.eclipse.core.runtime.content.IContentType;
33 import org.eclipse.core.runtime.content.IContentTypeManager;
34
35 import org.eclipse.core.filebuffers.IAnnotationModelFactory;
36 import org.eclipse.core.filebuffers.IDocumentFactory;
37 import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
38 import org.eclipse.core.filebuffers.LocationKind;
39
40
41 /**
42  * This registry manages sharable document factories and setup
43  * participants that are specified in <code>plugin.xml</code>.
44  */

45 public class ExtensionsRegistry {
46
47     /**
48      * Adapts IContentType with the ability to check
49      * equality. This allows to use them in a collection.
50      */

51     private static class ContentTypeAdapter {
52
53         /** The adapted content type. */
54         private IContentType fContentType;
55
56         /**
57          * Creates a new content type adapter for the
58          * given content type.
59          *
60          * @param contentType the content type to be adapted
61          */

62         public ContentTypeAdapter(IContentType contentType) {
63             Assert.isNotNull(contentType);
64             fContentType= contentType;
65         }
66
67         /**
68          * Return the adapted content type.
69          *
70          * @return the content type
71          */

72         public IContentType getContentType() {
73             return fContentType;
74         }
75
76         /**
77          * Return the Id of the adapted content type.
78          *
79          * @return the Id
80          */

81         public String JavaDoc getId() {
82             return fContentType.getId();
83         }
84
85         /*
86          * @see java.lang.Object#equals(java.lang.Object)
87          */

88         public boolean equals(Object JavaDoc obj) {
89             return obj instanceof ContentTypeAdapter && fContentType.getId().equals(((ContentTypeAdapter)obj).getId());
90         }
91
92         /*
93          * @see java.lang.Object#hashCode()
94          */

95         public int hashCode() {
96             return fContentType.getId().hashCode();
97         }
98     }
99
100     protected final static String JavaDoc WILDCARD= "*"; //$NON-NLS-1$
101

102     /** The mapping between file attributes and configuration elements describing document factories. */
103     private Map JavaDoc fFactoryDescriptors= new HashMap JavaDoc();
104     /** The mapping between configuration elements for document factories and instantiated document factories. */
105     private Map JavaDoc fFactories= new HashMap JavaDoc();
106     /** The mapping between file attributes and configuration elements describing document setup participants. */
107     private Map JavaDoc fSetupParticipantDescriptors= new HashMap JavaDoc();
108     /** The mapping between configuration elements for setup participants and instantiated setup participants. */
109     private Map JavaDoc fSetupParticipants= new HashMap JavaDoc();
110     /** The mapping between file attributes and configuration elements describing annotation model factories. */
111     private Map JavaDoc fAnnotationModelFactoryDescriptors= new HashMap JavaDoc();
112     /** The mapping between configuration elements for annotation model factories */
113     private Map JavaDoc fAnnotationModelFactories= new HashMap JavaDoc();
114     /** The content type manager. */
115     protected IContentTypeManager fContentTypeManager= Platform.getContentTypeManager();
116
117
118     /**
119      * Creates a new document factory registry and initializes it with the information
120      * found in the plug-in registry.
121      */

122     public ExtensionsRegistry() {
123         initialize("documentCreation", "contentTypeId", true, fFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
124
initialize("documentCreation", "fileNames", false, fFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
125
initialize("documentCreation", "extensions", false, fFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
126
initialize("documentSetup", "contentTypeId", true, fSetupParticipantDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
127
initialize("documentSetup", "fileNames", false, fSetupParticipantDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
128
initialize("documentSetup", "extensions", false, fSetupParticipantDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
129
initialize("annotationModelCreation", "contentTypeId", true, fAnnotationModelFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
130
initialize("annotationModelCreation", "fileNames", false, fAnnotationModelFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
131
initialize("annotationModelCreation", "extensions", false, fAnnotationModelFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
132

133     }
134
135     /**
136      * Reads the comma-separated value from the given configuration element for the given attribute name and remembers
137      * the configuration element in the given map under the individual tokens of the attribute value.
138      *
139      * @param attributeName the name of the attribute
140      * @param element the configuration element
141      * @param map the map which remembers the configuration element
142      */

143     private void read(String JavaDoc attributeName, IConfigurationElement element, Map JavaDoc map) {
144         String JavaDoc value= element.getAttribute(attributeName);
145         if (value != null) {
146             StringTokenizer JavaDoc tokenizer= new StringTokenizer JavaDoc(value, ","); //$NON-NLS-1$
147
while (tokenizer.hasMoreTokens()) {
148                 String JavaDoc token= tokenizer.nextToken().trim();
149
150                 Set JavaDoc s= (Set JavaDoc) map.get(token);
151                 if (s == null) {
152                     s= new HashSet JavaDoc();
153                     map.put(token, s);
154                 }
155                 s.add(element);
156             }
157         }
158     }
159
160     /**
161      * Reads the value from the given configuration element for the given attribute name and remembers
162      * the configuration element in the given map under the individual content type of the attribute value.
163      *
164      * @param attributeName the name of the attribute
165      * @param element the configuration element
166      * @param map the map which remembers the configuration element
167      */

168     private void readContentType(String JavaDoc attributeName, IConfigurationElement element, Map JavaDoc map) {
169         String JavaDoc value= element.getAttribute(attributeName);
170         if (value != null) {
171             IContentType contentType= fContentTypeManager.getContentType(value);
172             if (contentType == null) {
173                 log(new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, NLSUtility.format(FileBuffersMessages.ExtensionsRegistry_error_contentTypeDoesNotExist, value), null));
174                 return;
175             }
176             ContentTypeAdapter adapter= new ContentTypeAdapter(contentType);
177             Set JavaDoc s= (Set JavaDoc) map.get(adapter);
178             if (s == null) {
179                 s= new HashSet JavaDoc();
180                 map.put(adapter, s);
181             }
182             s.add(element);
183         }
184     }
185
186     /**
187      * Adds an entry to the log of this plug-in for the given status
188      * @param status the status to log
189      */

190     private void log(IStatus status) {
191         ILog log= FileBuffersPlugin.getDefault().getLog();
192         log.log(status);
193     }
194
195     /**
196      * Initializes this registry. It retrieves all implementers of the given
197      * extension point and remembers those implementers based on the
198      * file name extensions in the given map.
199      *
200      * @param extensionPointName the name of the extension point
201      * @param childElementName the name of the child elements
202      * @param isContentTypeId the child element is a content type id
203      * @param descriptors the map to be filled
204      */

205     private void initialize(String JavaDoc extensionPointName, String JavaDoc childElementName, boolean isContentTypeId, Map JavaDoc descriptors) {
206
207         IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(FileBuffersPlugin.PLUGIN_ID, extensionPointName);
208         if (extensionPoint == null) {
209             log(new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, 0, NLSUtility.format(FileBuffersMessages.ExtensionsRegistry_error_extensionPointNotFound, extensionPointName), null));
210             return;
211         }
212
213         IConfigurationElement[] elements= extensionPoint.getConfigurationElements();
214         for (int i= 0; i < elements.length; i++) {
215             if (isContentTypeId)
216                 readContentType(childElementName, elements[i], descriptors);
217             else
218                 read(childElementName, elements[i], descriptors);
219         }
220     }
221
222     /**
223      * Returns the executable extension for the given configuration element.
224      * If there is no instantiated extension remembered for this
225      * element, a new extension is created and put into the cache if it is of the requested type.
226      *
227      * @param entry the configuration element
228      * @param extensions the map of instantiated extensions
229      * @param extensionType the requested result type
230      * @return the executable extension for the given configuration element.
231      */

232     private Object JavaDoc getExtension(IConfigurationElement entry, Map JavaDoc extensions, Class JavaDoc extensionType) {
233         Object JavaDoc extension= extensions.get(entry);
234         if (extension != null)
235             return extension;
236
237         try {
238             extension= entry.createExecutableExtension("class"); //$NON-NLS-1$
239
} catch (CoreException x) {
240             log(x.getStatus());
241         }
242
243         if (extensionType.isInstance(extension)) {
244             extensions.put(entry, extension);
245             return extension;
246         }
247
248         return null;
249     }
250
251     /**
252      * Returns the first enumerated element of the given set.
253      *
254      * @param set the set from which to choose
255      * @return the selected configuration element
256      */

257     private IConfigurationElement selectConfigurationElement(Set JavaDoc set) {
258         if (set != null && !set.isEmpty()) {
259             Iterator JavaDoc e= set.iterator();
260             return (IConfigurationElement) e.next();
261         }
262         return null;
263     }
264
265     /**
266      * Returns a sharable document factory for the given file name or file extension.
267      *
268      * @param nameOrExtension the name or extension to be used for lookup
269      * @return the sharable document factory or <code>null</code>
270      */

271     protected IDocumentFactory getDocumentFactory(String JavaDoc nameOrExtension) {
272         Set JavaDoc set= (Set JavaDoc) fFactoryDescriptors.get(nameOrExtension);
273         if (set != null) {
274             IConfigurationElement entry= selectConfigurationElement(set);
275             return (IDocumentFactory) getExtension(entry, fFactories, IDocumentFactory.class);
276         }
277         return null;
278     }
279
280     /**
281      * Returns a sharable document factory for the given content types.
282      *
283      * @param contentTypes the content types used to find the factory
284      * @return the sharable document factory or <code>null</code>
285      */

286     protected IDocumentFactory doGetDocumentFactory(IContentType[] contentTypes) {
287         Set JavaDoc set= null;
288         int i= 0;
289         while (i < contentTypes.length && set == null) {
290             set= (Set JavaDoc) fFactoryDescriptors.get(new ContentTypeAdapter(contentTypes[i++]));
291         }
292
293         if (set != null) {
294             IConfigurationElement entry= selectConfigurationElement(set);
295             return (IDocumentFactory) getExtension(entry, fFactories, IDocumentFactory.class);
296         }
297         return null;
298     }
299
300     /**
301      * Returns a sharable document factory for the given content types. This
302      * method considers the base content types of the given set of content
303      * types.
304      *
305      * @param contentTypes the content types used to find the factory
306      * @return the sharable document factory or <code>null</code>
307      */

308     protected IDocumentFactory getDocumentFactory(IContentType[] contentTypes) {
309         IDocumentFactory factory= doGetDocumentFactory(contentTypes);
310         while (factory == null) {
311             contentTypes= computeBaseContentTypes(contentTypes);
312             if (contentTypes == null)
313                 break;
314             factory= doGetDocumentFactory(contentTypes);
315         }
316         return factory;
317     }
318
319     /**
320      * Returns the set of setup participants for the given file name or extension.
321      *
322      * @param nameOrExtension the name or extension to be used for lookup
323      * @return the sharable set of document setup participants
324      */

325     protected List JavaDoc getDocumentSetupParticipants(String JavaDoc nameOrExtension) {
326         Set JavaDoc set= (Set JavaDoc) fSetupParticipantDescriptors.get(nameOrExtension);
327         if (set == null)
328             return null;
329
330         List JavaDoc participants= new ArrayList JavaDoc();
331         Iterator JavaDoc e= set.iterator();
332         while (e.hasNext()) {
333             IConfigurationElement entry= (IConfigurationElement) e.next();
334             Object JavaDoc participant= getExtension(entry, fSetupParticipants, IDocumentSetupParticipant.class);
335             if (participant != null)
336                 participants.add(participant);
337         }
338
339         return participants;
340     }
341
342     /**
343      * Returns the set of setup participants for the given content types.
344      *
345      * @param contentTypes the contentTypes to be used for lookup
346      * @return the sharable set of document setup participants
347      */

348     private List JavaDoc doGetDocumentSetupParticipants(IContentType[] contentTypes) {
349         Set JavaDoc resultSet= new HashSet JavaDoc();
350         int i= 0;
351         while (i < contentTypes.length) {
352             Set JavaDoc set= (Set JavaDoc) fSetupParticipantDescriptors.get(new ContentTypeAdapter(contentTypes[i++]));
353             if (set != null)
354                 resultSet.addAll(set);
355         }
356
357         List JavaDoc participants= new ArrayList JavaDoc();
358         Iterator JavaDoc e= resultSet.iterator();
359         while (e.hasNext()) {
360             IConfigurationElement entry= (IConfigurationElement) e.next();
361             Object JavaDoc participant= getExtension(entry, fSetupParticipants, IDocumentSetupParticipant.class);
362             if (participant != null)
363                 participants.add(participant);
364         }
365
366         return participants.isEmpty() ? null : participants;
367     }
368
369     /**
370      * Returns the set of setup participants for the given content types. This
371      * method considers the base content types of the given set of content
372      * types.
373      *
374      * @param contentTypes the contentTypes to be used for lookup
375      * @return the sharable set of document setup participants
376      */

377     protected List JavaDoc getDocumentSetupParticipants(IContentType[] contentTypes) {
378         List JavaDoc participants= doGetDocumentSetupParticipants(contentTypes);
379         while (participants == null) {
380             contentTypes= computeBaseContentTypes(contentTypes);
381             if (contentTypes == null)
382                 break;
383             participants= doGetDocumentSetupParticipants(contentTypes);
384         }
385         return participants;
386     }
387
388     /**
389      * Returns a sharable annotation model factory for the given content types.
390      *
391      * @param contentTypes the content types used to find the factory
392      * @return the sharable annotation model factory or <code>null</code>
393      */

394     private IAnnotationModelFactory doGetAnnotationModelFactory(IContentType[] contentTypes) {
395         Set JavaDoc set= null;
396         int i= 0;
397         while (i < contentTypes.length && set == null) {
398             set= (Set JavaDoc) fAnnotationModelFactoryDescriptors.get(new ContentTypeAdapter(contentTypes[i++]));
399         }
400
401         if (set != null) {
402             IConfigurationElement entry= selectConfigurationElement(set);
403             return (IAnnotationModelFactory) getExtension(entry, fAnnotationModelFactories, IAnnotationModelFactory.class);
404         }
405         return null;
406     }
407
408     /**
409      * Returns a sharable annotation model factory for the given content types.
410      * This method considers the base content types of the given set of content
411      * types.
412      *
413      * @param contentTypes the content types used to find the factory
414      * @return the sharable annotation model factory or <code>null</code>
415      */

416     protected IAnnotationModelFactory getAnnotationModelFactory(IContentType[] contentTypes) {
417         IAnnotationModelFactory factory= doGetAnnotationModelFactory(contentTypes);
418         while (factory == null) {
419             contentTypes= computeBaseContentTypes(contentTypes);
420             if (contentTypes == null)
421                 break;
422             factory= doGetAnnotationModelFactory(contentTypes);
423         }
424         return factory;
425     }
426
427     /**
428      * Returns a sharable annotation model factory for the given file name or file extension.
429      *
430      * @param extension the name or extension to be used for lookup
431      * @return the sharable document factory or <code>null</code>
432      */

433     protected IAnnotationModelFactory getAnnotationModelFactory(String JavaDoc extension) {
434         Set JavaDoc set= (Set JavaDoc) fAnnotationModelFactoryDescriptors.get(extension);
435         if (set != null) {
436             IConfigurationElement entry= selectConfigurationElement(set);
437             return (IAnnotationModelFactory) getExtension(entry, fAnnotationModelFactories, IAnnotationModelFactory.class);
438         }
439         return null;
440     }
441
442     /**
443      * Returns the set of content types for the given location.
444      *
445      * @param location the location for which to look up the content types
446      * @param locationKind the kind of the given location
447      * @return the set of content types for the location
448      * @since 3.3
449      */

450     protected IContentType[] findContentTypes(IPath location, LocationKind locationKind) {
451         Assert.isLegal(locationKind != LocationKind.IFILE);
452         return fContentTypeManager.findContentTypesFor(location.lastSegment());
453     }
454
455     /**
456      * Returns the set of direct base content types for the given set of content
457      * types. Returns <code>null</code> if non of the given content types has
458      * a direct base content type.
459      *
460      * @param contentTypes the content types
461      * @return the set of direct base content types
462      */

463     private IContentType[] computeBaseContentTypes(IContentType[] contentTypes) {
464         List JavaDoc baseTypes= new ArrayList JavaDoc();
465         for (int i= 0; i < contentTypes.length; i++) {
466             IContentType baseType= contentTypes[i].getBaseType();
467             if (baseType != null)
468                 baseTypes.add(baseType);
469         }
470
471         IContentType[] result= null;
472         int size= baseTypes.size();
473         if (size > 0) {
474             result= new IContentType[size];
475             baseTypes.toArray(result);
476         }
477         return result;
478     }
479
480     /**
481      * Returns the sharable document factory for the given location.
482      *
483      * @param location the location for which to looked up the factory
484      * @param locationKind the kind of the given location
485      * @return the sharable document factory
486      * @since 3.3
487      */

488     public IDocumentFactory getDocumentFactory(IPath location, LocationKind locationKind) {
489         IDocumentFactory factory= getDocumentFactory(findContentTypes(location, locationKind));
490         if (factory == null)
491             factory= getDocumentFactory(location.lastSegment());
492         if (factory == null)
493             factory= getDocumentFactory(location.getFileExtension());
494         if (factory == null)
495             factory= getDocumentFactory(WILDCARD);
496         return factory;
497     }
498
499     /**
500      * Returns the sharable set of document setup participants for the given location.
501      *
502      * @param location the location for which to look up the setup participants
503      * @param locationKind the kind of the given location
504      * @return the sharable set of document setup participants
505      * @since 3.3
506      */

507     public IDocumentSetupParticipant[] getDocumentSetupParticipants(IPath location, LocationKind locationKind) {
508         Set JavaDoc participants= new HashSet JavaDoc();
509
510         List JavaDoc p= getDocumentSetupParticipants(findContentTypes(location, locationKind));
511         if (p != null)
512             participants.addAll(p);
513
514         p= getDocumentSetupParticipants(location.lastSegment());
515         if (p != null)
516             participants.addAll(p);
517
518         p= getDocumentSetupParticipants(location.getFileExtension());
519         if (p != null)
520             participants.addAll(p);
521
522         p= getDocumentSetupParticipants(WILDCARD);
523         if (p != null)
524             participants.addAll(p);
525
526         IDocumentSetupParticipant[] result= new IDocumentSetupParticipant[participants.size()];
527         participants.toArray(result);
528         return result;
529     }
530     
531     /**
532      * Returns the sharable annotation model factory for the given location.
533      *
534      * @param location the location for which to look up the factory
535      * @param locationKind the kind of the given location
536      * @return the sharable annotation model factory
537      * @since 3.3
538      */

539     public IAnnotationModelFactory getAnnotationModelFactory(IPath location, LocationKind locationKind) {
540         IAnnotationModelFactory factory= getAnnotationModelFactory(findContentTypes(location, locationKind));
541         if (factory == null)
542             factory= getAnnotationModelFactory(location.lastSegment());
543         if (factory == null)
544             factory= getAnnotationModelFactory(location.getFileExtension());
545         if (factory == null)
546             factory= getAnnotationModelFactory(WILDCARD);
547         return factory;
548     }
549     
550 }
551
Popular Tags