KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > apt > core > internal > FactoryPluginManager


1 /*******************************************************************************
2  * Copyright (c) 2007 BEA Systems, Inc.
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  * wharley@bea.com - initial API and implementation
10  *
11  *******************************************************************************/

12
13 package org.eclipse.jdt.apt.core.internal;
14
15 import java.util.HashMap JavaDoc;
16 import java.util.LinkedHashMap JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.TreeMap JavaDoc;
19
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.IConfigurationElement;
22 import org.eclipse.core.runtime.IExtension;
23 import org.eclipse.core.runtime.IExtensionPoint;
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.core.runtime.Platform;
26 import org.eclipse.core.runtime.Status;
27 import org.eclipse.jdt.apt.core.internal.util.FactoryContainer;
28 import org.eclipse.jdt.apt.core.internal.util.FactoryPath;
29
30 import com.sun.mirror.apt.AnnotationProcessorFactory;
31
32 /**
33  * Manages caches of plugins which provide annotation processors.
34  *
35  * @since 3.3
36  */

37 public class FactoryPluginManager {
38     /**
39      * Map of factory names -> factories. A single plugin factory container may
40      * contain multiple annotation processor factories, each with a unique name.
41      * To support lazy initialization, this should only be accessed by calling
42      * @see #getJava5PluginFactoryMap() .
43      */

44     private static final HashMap JavaDoc<String JavaDoc, AnnotationProcessorFactory> PLUGIN_JAVA5_FACTORY_MAP = new HashMap JavaDoc<String JavaDoc, AnnotationProcessorFactory>();
45     
46     /**
47      * Map of factory names -> factories. A single plugin factory container may
48      * contain multiple annotation processor factories, each with a unique name.
49      * To support lazy initialization, this should only be accessed by calling
50      * @see #getJava5PluginFactoryMap() .
51      */

52     private static final HashMap JavaDoc<String JavaDoc, IServiceFactory> PLUGIN_JAVA6_FACTORY_MAP = new HashMap JavaDoc<String JavaDoc, IServiceFactory>();
53
54     /**
55      * Map of plugin names -> plugin factory containers, sorted by plugin name.
56      * A plugin that contains annotation processor factories (and extends the
57      * corresponding extension point) is a "plugin factory container".
58      * To support lazy initialization, this should only be accessed by calling
59      * @see #getPluginFactoryContainerMap() .
60      */

61     private static final TreeMap JavaDoc<String JavaDoc, PluginFactoryContainer> PLUGIN_CONTAINER_MAP = new TreeMap JavaDoc<String JavaDoc, PluginFactoryContainer>();
62
63     /**
64      * true if PLUGIN_FACTORY_MAP and PLUGIN_CONTAINER_MAP have been initialized,
65      * by calling @see #loadPluginFactories() .
66      */

67     private static boolean mapsInitialized = false;
68     
69     /**
70      * Returns an ordered list of all the plugin factory containers that have
71      * been registered as plugins. Note that this may include plugins that have
72      * been disabled by the user's configuration. The 'enabled' attribute in the
73      * returned map reflects the 'enableDefault' attribute in the plugin
74      * manifest, rather than the user configuration.
75      * Ordering is alphabetic by plugin id.
76      */

77     public static synchronized Map JavaDoc<FactoryContainer, FactoryPath.Attributes> getAllPluginFactoryContainers()
78     {
79         Map JavaDoc<FactoryContainer, FactoryPath.Attributes> map =
80             new LinkedHashMap JavaDoc<FactoryContainer, FactoryPath.Attributes>(getPluginContainerMap().size());
81         for (PluginFactoryContainer pfc : getPluginContainerMap().values()) {
82             FactoryPath.Attributes a = new FactoryPath.Attributes(pfc.getEnableDefault(), false);
83             map.put(pfc, a);
84         }
85         return map;
86     }
87     
88     public static synchronized AnnotationProcessorFactory getJava5FactoryFromPlugin( String JavaDoc factoryName )
89     {
90         AnnotationProcessorFactory apf = getJava5PluginFactoryMap().get( factoryName );
91         if ( apf == null )
92         {
93             String JavaDoc s = "could not find AnnotationProcessorFactory " + //$NON-NLS-1$
94
factoryName + " from available factories defined by plugins"; //$NON-NLS-1$
95
AptPlugin.log(new Status(IStatus.WARNING, AptPlugin.PLUGIN_ID, AptPlugin.STATUS_NOTOOLSJAR, s, null));
96         }
97         return apf;
98     }
99
100     public static synchronized IServiceFactory getJava6FactoryFromPlugin( String JavaDoc factoryName )
101     {
102         IServiceFactory isf = getJava6PluginFactoryMap().get( factoryName );
103         if ( isf == null )
104         {
105             String JavaDoc s = "could not find annotation processor " + //$NON-NLS-1$
106
factoryName + " from available factories defined by plugins"; //$NON-NLS-1$
107
AptPlugin.log(new Status(IStatus.WARNING, AptPlugin.PLUGIN_ID, AptPlugin.STATUS_NOTOOLSJAR, s, null));
108         }
109         return isf;
110     }
111
112     /**
113      * Return the factory container corresponding to the specified plugin id.
114      * All plugin factories are loaded at startup time.
115      * @param pluginId the id of a plugin that extends annotationProcessorFactory.
116      * @return a PluginFactoryContainer, or null if the plugin id does not
117      * identify an annotation processor plugin.
118      */

119     public static synchronized FactoryContainer getPluginFactoryContainer(String JavaDoc pluginId) {
120         return getPluginContainerMap().get(pluginId);
121     }
122     
123     /**
124      * Get the alphabetically sorted map of plugin names to plugin factory containers.
125      * Load plugins if the map has not yet been initialized.
126      */

127     private static TreeMap JavaDoc<String JavaDoc, PluginFactoryContainer> getPluginContainerMap() {
128         loadFactoryPlugins();
129         return PLUGIN_CONTAINER_MAP;
130     }
131     
132     /**
133      * Get the map of plugin factory names to plugin factories.
134      * Load plugins if the map has not yet been initialized.
135      */

136     private static HashMap JavaDoc<String JavaDoc, AnnotationProcessorFactory> getJava5PluginFactoryMap() {
137         loadFactoryPlugins();
138         return PLUGIN_JAVA5_FACTORY_MAP;
139     }
140
141     /**
142      * Get the map of plugin factory names to plugin factories.
143      * Load plugins if the map has not yet been initialized.
144      */

145     private static HashMap JavaDoc<String JavaDoc, IServiceFactory> getJava6PluginFactoryMap() {
146         loadFactoryPlugins();
147         return PLUGIN_JAVA6_FACTORY_MAP;
148     }
149
150     /**
151      * Discover and instantiate annotation processor factories by searching for plugins
152      * which contribute to org.eclipse.jdt.apt.core.annotationProcessorFactory.
153      * The first time this method is called, it will load all the plugin factories.
154      * Subsequent calls will be ignored.
155      */

156     private static synchronized void loadFactoryPlugins() {
157         if (mapsInitialized) {
158             return;
159         }
160         IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(
161                 AptPlugin.PLUGIN_ID, // name of plugin that exposes this extension point
162
"annotationProcessorFactory"); //$NON-NLS-1$ - extension id
163

164         // Iterate over all declared extensions of this extension point.
165
// A single plugin may extend the extension point more than once, although it's not recommended.
166
for (IExtension extension : extensionPoint.getExtensions())
167         {
168             // Iterate over the children of the extension to find one named "factories".
169
for(IConfigurationElement factories : extension.getConfigurationElements())
170             {
171                 if ("factories".equals(factories.getName())) { //$NON-NLS-1$ - name of configElement
172
loadJava5Factories(extension, factories);
173                 }
174                 else if ("java6processors".equals(factories.getName())) { //$NON-NLS-1$ - name of configElement
175
loadJava6Factories(extension, factories);
176                 }
177                 
178             }
179         }
180         mapsInitialized = true;
181     }
182
183     private static void loadJava6Factories(IExtension extension, IConfigurationElement factories) {
184         if (!AptPlugin.canRunJava6Processors()) {
185             return;
186         }
187         
188         // Get enableDefault. If the attribute is missing, default to true.
189
String JavaDoc enableDefaultStr = factories.getAttribute("enableDefault"); //$NON-NLS-1$
190
boolean enableDefault = true;
191         if ("false".equals(enableDefaultStr)) { //$NON-NLS-1$
192
enableDefault = false;
193         }
194         
195         // Create and cache a PluginFactoryContainer for this plugin.
196
String JavaDoc pluginId = extension.getNamespaceIdentifier();
197         //TODO: level problem. In the extension point, enableDefault is associated with element, not ext point.
198
PluginFactoryContainer pfc = new PluginFactoryContainer(pluginId, enableDefault);
199         PLUGIN_CONTAINER_MAP.put(pluginId, pfc);
200         
201         // Iterate over the children of the "java6processors" element to find all the ones named "java6processor".
202
for (IConfigurationElement factory : factories.getChildren()) {
203             if (!"java6processor".equals(factory.getName())) { //$NON-NLS-1$
204
continue;
205             }
206             String JavaDoc factoryName = null;
207             try {
208                 factoryName = factory.getAttribute("class"); //$NON-NLS-1$
209
Object JavaDoc execExt = factory.createExecutableExtension("class"); //$NON-NLS-1$ - attribute name
210
Class JavaDoc<?> clazz = execExt.getClass();
211                 if (AptPlugin.getJava6ProcessorClass().isInstance(execExt)){
212                     assert(clazz.getName().equals(factoryName));
213                     IServiceFactory isf = new ClassServiceFactory(clazz);
214                     PLUGIN_JAVA6_FACTORY_MAP.put( factoryName, isf );
215                     pfc.addFactoryName(factoryName, AptPlugin.JAVA6_FACTORY_NAME);
216                 }
217                 else {
218                     reportFailureToLoadProcessor(null, factoryName, extension.getNamespaceIdentifier());
219                 }
220             } catch(CoreException e) {
221                 reportFailureToLoadProcessor(e, factoryName, extension.getNamespaceIdentifier());
222             }
223         }
224     }
225     
226     private static void loadJava5Factories(IExtension extension, IConfigurationElement factories) {
227         // Get enableDefault. If the attribute is missing, default to true.
228
String JavaDoc enableDefaultStr = factories.getAttribute("enableDefault"); //$NON-NLS-1$
229
boolean enableDefault = true;
230         if ("false".equals(enableDefaultStr)) { //$NON-NLS-1$
231
enableDefault = false;
232         }
233         
234         // Create and cache a PluginFactoryContainer for this plugin.
235
String JavaDoc pluginId = extension.getNamespaceIdentifier();
236         PluginFactoryContainer pfc = new PluginFactoryContainer(pluginId, enableDefault);
237         PLUGIN_CONTAINER_MAP.put(pluginId, pfc);
238         
239         // Iterate over the children of the "factories" element to find all the ones named "factory".
240
for (IConfigurationElement factory : factories.getChildren()) {
241             if (!"factory".equals(factory.getName())) { //$NON-NLS-1$
242
continue;
243             }
244             String JavaDoc factoryName = null;
245             try {
246                 factoryName = factory.getAttribute("class"); //$NON-NLS-1$
247
Object JavaDoc execExt = factory.createExecutableExtension("class"); //$NON-NLS-1$ - attribute name
248
if (execExt instanceof AnnotationProcessorFactory){
249                     assert(execExt.getClass().getName().equals(factoryName));
250                     PLUGIN_JAVA5_FACTORY_MAP.put( factoryName, (AnnotationProcessorFactory)execExt );
251                     pfc.addFactoryName(factoryName, AptPlugin.JAVA5_FACTORY_NAME);
252                 }
253                 else {
254                     reportFailureToLoadProcessor(null, factory.getName(), extension.getNamespaceIdentifier());
255                 }
256             } catch(CoreException e) {
257                 reportFailureToLoadProcessor(e, factory.getName(), extension.getNamespaceIdentifier());
258             }
259         }
260     }
261     
262     private static void reportFailureToLoadProcessor(Exception JavaDoc e, String JavaDoc factoryName, String JavaDoc pluginId) {
263         AptPlugin.log(e, "Unable to load annotation processor "+ factoryName + //$NON-NLS-1$
264
" from plug-in " + pluginId); //$NON-NLS-1$
265
}
266     
267     
268 }
269
Popular Tags