1 | /******************************************************************************* |
2 | * Copyright (c) 2007, 2009 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.pde.api.tools.internal.provisional; |
12 | |
13 | import java.util.ArrayList; |
14 | import java.util.HashSet; |
15 | import java.util.Iterator; |
16 | import java.util.List; |
17 | |
18 | import org.eclipse.core.resources.IProject; |
19 | import org.eclipse.core.resources.ISaveContext; |
20 | import org.eclipse.core.resources.ISaveParticipant; |
21 | import org.eclipse.core.resources.ProjectScope; |
22 | import org.eclipse.core.resources.ResourcesPlugin; |
23 | import org.eclipse.core.runtime.CoreException; |
24 | import org.eclipse.core.runtime.IStatus; |
25 | import org.eclipse.core.runtime.Platform; |
26 | import org.eclipse.core.runtime.Plugin; |
27 | import org.eclipse.core.runtime.Status; |
28 | import org.eclipse.core.runtime.preferences.DefaultScope; |
29 | import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
30 | import org.eclipse.core.runtime.preferences.IPreferencesService; |
31 | import org.eclipse.core.runtime.preferences.IScopeContext; |
32 | import org.eclipse.core.runtime.preferences.InstanceScope; |
33 | import org.eclipse.pde.api.tools.internal.ApiBaselineManager; |
34 | import org.eclipse.pde.api.tools.internal.ApiDescription; |
35 | import org.eclipse.pde.api.tools.internal.ApiDescriptionManager; |
36 | import org.eclipse.pde.api.tools.internal.ApiFilterStore; |
37 | import org.eclipse.pde.api.tools.internal.JavadocTagManager; |
38 | import org.eclipse.pde.api.tools.internal.SessionManager; |
39 | import org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector; |
40 | import org.eclipse.pde.api.tools.internal.builder.ApiAnalysisBuilder; |
41 | import org.eclipse.pde.api.tools.internal.builder.ReferenceAnalyzer; |
42 | import org.eclipse.pde.api.tools.internal.builder.ReferenceExtractor; |
43 | import org.eclipse.pde.api.tools.internal.builder.ReferenceResolver; |
44 | import org.eclipse.pde.api.tools.internal.comparator.ClassFileComparator; |
45 | import org.eclipse.pde.api.tools.internal.descriptors.ElementDescriptorImpl; |
46 | import org.eclipse.pde.api.tools.internal.model.PluginProjectApiComponent; |
47 | import org.eclipse.pde.api.tools.internal.provisional.comparator.ApiComparator; |
48 | import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemTypes; |
49 | import org.eclipse.pde.api.tools.internal.provisional.scanner.TagScanner; |
50 | import org.eclipse.pde.api.tools.internal.util.FileManager; |
51 | import org.osgi.framework.BundleContext; |
52 | import org.osgi.service.prefs.BackingStoreException; |
53 | |
54 | /** |
55 | * API Tools core plug-in. |
56 | * API tools can be run with or without an OSGi framework. |
57 | * |
58 | * @since 1.0.0 |
59 | */ |
60 | public class ApiPlugin extends Plugin implements ISaveParticipant { |
61 | |
62 | /** |
63 | * Constant representing the name of the javadoc tag extension point. |
64 | * Value is <code>apiJavadocTags</code> |
65 | */ |
66 | public static final String EXTENSION_JAVADOC_TAGS = "apiJavadocTags"; //$NON-NLS-1$ |
67 | /** |
68 | * The plug-in identifier of the PDE API tool support |
69 | * (value <code>"org.eclipse.pde.api.tools"</code>). |
70 | */ |
71 | public static final String PLUGIN_ID = "org.eclipse.pde.api.tools" ; //$NON-NLS-1$ |
72 | /** |
73 | * The API tooling nature id |
74 | * (value <code>"org.eclipse.pde.api.tools.apiAnalysisNature"</code>). |
75 | */ |
76 | public static final String NATURE_ID = PLUGIN_ID + ".apiAnalysisNature" ; //$NON-NLS-1$ |
77 | /** |
78 | * Status code indicating an unexpected internal error. |
79 | */ |
80 | public static final int INTERNAL_ERROR = 120; |
81 | /** |
82 | * Status code indicating an unexpected error |
83 | */ |
84 | public static final int ERROR = 121; |
85 | |
86 | /** |
87 | * Status code indicating a resolution error |
88 | */ |
89 | public static final int REPORT_RESOLUTION_ERRORS = 122; |
90 | |
91 | /** |
92 | * Status code indicating that a baseline is disposed |
93 | */ |
94 | public static final int REPORT_BASELINE_IS_DISPOSED = 123; |
95 | |
96 | /** |
97 | * Constant representing severity levels for error/warning preferences |
98 | * Value is: <code>0</code> |
99 | */ |
100 | public static final int SEVERITY_IGNORE = 0; |
101 | /** |
102 | * Constant representing severity levels for error/warning preferences |
103 | * Value is: <code>1</code> |
104 | */ |
105 | public static final int SEVERITY_WARNING = 1; |
106 | /** |
107 | * Constant representing severity levels for error/warning preferences |
108 | * Value is: <code>2</code> |
109 | */ |
110 | public static final int SEVERITY_ERROR = 2; |
111 | |
112 | /** |
113 | * Constant representing the preference value 'ignore'. |
114 | * Value is: <code>Ignore</code> |
115 | */ |
116 | public static final String VALUE_IGNORE = "Ignore"; //$NON-NLS-1$ |
117 | /** |
118 | * Constant representing the preference value 'warning'. |
119 | * Value is: <code>Warning</code> |
120 | */ |
121 | public static final String VALUE_WARNING = "Warning"; //$NON-NLS-1$ |
122 | /** |
123 | * Constant representing the preference value 'error'. |
124 | * Value is: <code>Error</code> |
125 | */ |
126 | public static final String VALUE_ERROR = "Error"; //$NON-NLS-1$ |
127 | /** |
128 | * Constant representing the preference value 'disabled'. |
129 | * Value is: <code>Disabled</code> |
130 | */ |
131 | public static final String VALUE_DISABLED = "Disabled"; //$NON-NLS-1$ |
132 | /** |
133 | * Constant representing the preference value 'enabled'. |
134 | * Value is: <code>Enabled</code> |
135 | */ |
136 | public static final String VALUE_ENABLED = "Enabled"; //$NON-NLS-1$ |
137 | /** |
138 | * The identifier for the Api builder |
139 | * Value is: <code>"org.eclipse.pde.api.tools.apiAnalysisBuilder"</code> |
140 | */ |
141 | public static final String BUILDER_ID = PLUGIN_ID + ".apiAnalysisBuilder" ; //$NON-NLS-1$ |
142 | |
143 | public static final String BASELINE_IS_DISPOSED = "baseline is disposed"; //$NON-NLS-1$ |
144 | /** |
145 | * Singleton instance of the plugin |
146 | */ |
147 | private static ApiPlugin fgDefault = null; |
148 | /** |
149 | * Singleton instance of the {@link JavadocTagManager} |
150 | */ |
151 | private static JavadocTagManager fgTagManager = null; |
152 | /** |
153 | * Singleton instance of the {@link ISessionManager} |
154 | */ |
155 | private static ISessionManager fgSessionManager = null; |
156 | /** |
157 | * Private debug options |
158 | */ |
159 | private static final String BUILDER_DEBUG = PLUGIN_ID + "/debug/builder" ; //$NON-NLS-1$ |
160 | private static final String DELTA_DEBUG = PLUGIN_ID + "/debug/delta" ; //$NON-NLS-1$ |
161 | private static final String CLASSFILE_VISITOR_DEBUG = PLUGIN_ID + "/debug/classfilevisitor" ; //$NON-NLS-1$ |
162 | private static final String DESCRIPTOR_FRAMEWORK_DEBUG = PLUGIN_ID + "/debug/descriptor/framework" ; //$NON-NLS-1$ |
163 | private static final String TAG_SCANNER_DEBUG = PLUGIN_ID + "/debug/tagscanner" ; //$NON-NLS-1$ |
164 | private static final String PLUGIN_WORKSPACE_COMPONENT_DEBUG = PLUGIN_ID + "/debug/pluginworkspacecomponent"; //$NON-NLS-1$ |
165 | private static final String API_PROFILE_MANAGER_DEBUG = PLUGIN_ID + "/debug/profilemanager"; //$NON-NLS-1$ |
166 | private static final String API_FILTER_STORE_DEBUG = PLUGIN_ID + "/debug/apifilterstore"; //$NON-NLS-1$ |
167 | private static final String API_REFERENCE_ANALYZER_DEBUG = PLUGIN_ID + "/debug/refanalyzer"; //$NON-NLS-1$ |
168 | private static final String PROBLEM_DETECTOR_DEBUG = PLUGIN_ID + "/debug/problemdetector"; //$NON-NLS-1$ |
169 | private static final String REFERENCE_RESOLVER_DEBUG = PLUGIN_ID + "/debug/refresolver"; //$NON-NLS-1$ |
170 | private static final String API_DESCRIPTION = PLUGIN_ID + "/debug/apidescription"; //$NON-NLS-1$ |
171 | |
172 | public final static String TRUE = "true"; //$NON-NLS-1$ |
173 | |
174 | public static String[] AllCompatibilityKeys = new String[] { |
175 | IApiProblemTypes.API_COMPONENT_REMOVED_TYPE, |
176 | IApiProblemTypes.API_COMPONENT_REMOVED_API_TYPE, |
177 | IApiProblemTypes.API_COMPONENT_REMOVED_REEXPORTED_TYPE, |
178 | IApiProblemTypes.API_COMPONENT_REMOVED_REEXPORTED_API_TYPE, |
179 | IApiProblemTypes.ANNOTATION_REMOVED_FIELD, |
180 | IApiProblemTypes.ANNOTATION_REMOVED_METHOD, |
181 | IApiProblemTypes.ANNOTATION_REMOVED_TYPE_MEMBER, |
182 | IApiProblemTypes.ANNOTATION_CHANGED_TYPE_CONVERSION, |
183 | IApiProblemTypes.ANNOTATION_ADDED_METHOD_NO_DEFAULT_VALUE, |
184 | IApiProblemTypes.INTERFACE_ADDED_FIELD, |
185 | IApiProblemTypes.INTERFACE_ADDED_METHOD, |
186 | IApiProblemTypes.INTERFACE_ADDED_RESTRICTIONS, |
187 | IApiProblemTypes.INTERFACE_ADDED_SUPER_INTERFACE_WITH_METHODS, |
188 | IApiProblemTypes.INTERFACE_ADDED_TYPE_PARAMETER, |
189 | IApiProblemTypes.INTERFACE_REMOVED_TYPE_PARAMETER, |
190 | IApiProblemTypes.INTERFACE_REMOVED_FIELD, |
191 | IApiProblemTypes.INTERFACE_REMOVED_METHOD, |
192 | IApiProblemTypes.INTERFACE_REMOVED_TYPE_MEMBER, |
193 | IApiProblemTypes.INTERFACE_CHANGED_TYPE_CONVERSION, |
194 | IApiProblemTypes.INTERFACE_CHANGED_CONTRACTED_SUPERINTERFACES_SET, |
195 | IApiProblemTypes.ENUM_CHANGED_CONTRACTED_SUPERINTERFACES_SET, |
196 | IApiProblemTypes.ENUM_CHANGED_TYPE_CONVERSION, |
197 | IApiProblemTypes.ENUM_REMOVED_FIELD, |
198 | IApiProblemTypes.ENUM_REMOVED_ENUM_CONSTANT, |
199 | IApiProblemTypes.ENUM_REMOVED_METHOD, |
200 | IApiProblemTypes.ENUM_REMOVED_TYPE_MEMBER, |
201 | IApiProblemTypes.CLASS_ADDED_METHOD, |
202 | IApiProblemTypes.CLASS_ADDED_RESTRICTIONS, |
203 | IApiProblemTypes.CLASS_ADDED_TYPE_PARAMETER, |
204 | IApiProblemTypes.CLASS_CHANGED_CONTRACTED_SUPERINTERFACES_SET, |
205 | IApiProblemTypes.CLASS_CHANGED_NON_ABSTRACT_TO_ABSTRACT, |
206 | IApiProblemTypes.CLASS_CHANGED_NON_FINAL_TO_FINAL, |
207 | IApiProblemTypes.CLASS_CHANGED_TYPE_CONVERSION, |
208 | IApiProblemTypes.CLASS_CHANGED_DECREASE_ACCESS, |
209 | IApiProblemTypes.CLASS_REMOVED_FIELD, |
210 | IApiProblemTypes.CLASS_REMOVED_METHOD, |
211 | IApiProblemTypes.CLASS_REMOVED_CONSTRUCTOR, |
212 | IApiProblemTypes.CLASS_REMOVED_SUPERCLASS, |
213 | IApiProblemTypes.CLASS_REMOVED_TYPE_MEMBER, |
214 | IApiProblemTypes.CLASS_REMOVED_TYPE_PARAMETER, |
215 | IApiProblemTypes.FIELD_ADDED_VALUE, |
216 | IApiProblemTypes.FIELD_CHANGED_TYPE, |
217 | IApiProblemTypes.FIELD_CHANGED_VALUE, |
218 | IApiProblemTypes.FIELD_CHANGED_DECREASE_ACCESS, |
219 | IApiProblemTypes.FIELD_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT, |
220 | IApiProblemTypes.FIELD_CHANGED_NON_FINAL_TO_FINAL, |
221 | IApiProblemTypes.FIELD_CHANGED_STATIC_TO_NON_STATIC, |
222 | IApiProblemTypes.FIELD_CHANGED_NON_STATIC_TO_STATIC, |
223 | IApiProblemTypes.FIELD_REMOVED_VALUE, |
224 | IApiProblemTypes.FIELD_REMOVED_TYPE_ARGUMENT, |
225 | IApiProblemTypes.METHOD_ADDED_RESTRICTIONS, |
226 | IApiProblemTypes.METHOD_ADDED_TYPE_PARAMETER, |
227 | IApiProblemTypes.METHOD_CHANGED_VARARGS_TO_ARRAY, |
228 | IApiProblemTypes.METHOD_CHANGED_DECREASE_ACCESS, |
229 | IApiProblemTypes.METHOD_CHANGED_NON_ABSTRACT_TO_ABSTRACT, |
230 | IApiProblemTypes.METHOD_CHANGED_NON_STATIC_TO_STATIC, |
231 | IApiProblemTypes.METHOD_CHANGED_STATIC_TO_NON_STATIC, |
232 | IApiProblemTypes.METHOD_CHANGED_NON_FINAL_TO_FINAL, |
233 | IApiProblemTypes.METHOD_REMOVED_ANNOTATION_DEFAULT_VALUE, |
234 | IApiProblemTypes.METHOD_REMOVED_TYPE_PARAMETER, |
235 | IApiProblemTypes.CONSTRUCTOR_ADDED_TYPE_PARAMETER, |
236 | IApiProblemTypes.CONSTRUCTOR_CHANGED_VARARGS_TO_ARRAY, |
237 | IApiProblemTypes.CONSTRUCTOR_CHANGED_DECREASE_ACCESS, |
238 | IApiProblemTypes.CONSTRUCTOR_REMOVED_TYPE_PARAMETER, |
239 | IApiProblemTypes.TYPE_PARAMETER_ADDED_CLASS_BOUND, |
240 | IApiProblemTypes.TYPE_PARAMETER_CHANGED_CLASS_BOUND, |
241 | IApiProblemTypes.TYPE_PARAMETER_REMOVED_CLASS_BOUND, |
242 | IApiProblemTypes.TYPE_PARAMETER_ADDED_INTERFACE_BOUND, |
243 | IApiProblemTypes.TYPE_PARAMETER_CHANGED_INTERFACE_BOUND, |
244 | IApiProblemTypes.TYPE_PARAMETER_REMOVED_INTERFACE_BOUND, |
245 | IApiProblemTypes.TYPE_PARAMETER_REMOVED_INTERFACE_BOUND, |
246 | IApiProblemTypes.REPORT_API_BREAKAGE_WHEN_MAJOR_VERSION_INCREMENTED, |
247 | // IApiProblemTypes.REPORT_API_CHANGE_WHEN_MINOR_VERSION_INCREMENTED, |
248 | }; |
249 | /** |
250 | * A set of listeners that want to participate in the saving life-cycle of the workbench |
251 | * via this plugin |
252 | */ |
253 | private HashSet savelisteners = new HashSet(); |
254 | |
255 | /** |
256 | * This is used to log resolution errors only once per session |
257 | */ |
258 | private int logBits = 0; |
259 | |
260 | /** |
261 | * This is used to log resolution errors only once per session. |
262 | * This is used outside the workbench. |
263 | */ |
264 | private static int LogBits= 0; |
265 | |
266 | private static final int RESOLUTION_LOG_BIT = 1; |
267 | private static final int BASELINE_DISPOSED_LOG_BIT = 2; |
268 | |
269 | /** |
270 | * Constructor |
271 | */ |
272 | public ApiPlugin() { |
273 | super(); |
274 | fgDefault = this; |
275 | } |
276 | |
277 | /** |
278 | * @return The singleton instance of the plugin |
279 | */ |
280 | public static ApiPlugin getDefault() { |
281 | return fgDefault; |
282 | } |
283 | |
284 | /** |
285 | * Logs the specified status with this plug-in's log. |
286 | * |
287 | * @param status status to log |
288 | */ |
289 | public static void log(IStatus status) { |
290 | ApiPlugin getDefault = getDefault(); |
291 | if (getDefault == null) { |
292 | switch(status.getCode()) { |
293 | case REPORT_RESOLUTION_ERRORS : |
294 | if ((LogBits & RESOLUTION_LOG_BIT) == 0) { |
295 | Throwable exception = status.getException(); |
296 | if (exception != null) { |
297 | exception.printStackTrace(); |
298 | } |
299 | LogBits |= RESOLUTION_LOG_BIT; |
300 | } |
301 | break; |
302 | case REPORT_BASELINE_IS_DISPOSED : |
303 | if ((LogBits & BASELINE_DISPOSED_LOG_BIT) == 0) { |
304 | Throwable exception = status.getException(); |
305 | if (exception != null) { |
306 | exception.printStackTrace(); |
307 | } |
308 | LogBits |= BASELINE_DISPOSED_LOG_BIT; |
309 | } |
310 | break; |
311 | default: |
312 | Throwable exception = status.getException(); |
313 | if (exception != null) { |
314 | exception.printStackTrace(); |
315 | } |
316 | } |
317 | } else { |
318 | switch(status.getCode()) { |
319 | case REPORT_RESOLUTION_ERRORS : |
320 | if ((getDefault.logBits & RESOLUTION_LOG_BIT) == 0) { |
321 | getDefault.getLog().log(status); |
322 | getDefault.logBits |= RESOLUTION_LOG_BIT; |
323 | } |
324 | break; |
325 | case REPORT_BASELINE_IS_DISPOSED : |
326 | if ((getDefault.logBits & BASELINE_DISPOSED_LOG_BIT) == 0) { |
327 | getDefault.getLog().log(status); |
328 | getDefault.logBits |= BASELINE_DISPOSED_LOG_BIT; |
329 | } |
330 | break; |
331 | default: |
332 | getDefault.getLog().log(status); |
333 | } |
334 | } |
335 | } |
336 | |
337 | /** |
338 | * Logs the specified throwable with this plug-in's log. |
339 | * |
340 | * @param t throwable to log |
341 | */ |
342 | public static void log(Throwable t) { |
343 | log(newErrorStatus("Error logged from API Tools Core: ", t)); //$NON-NLS-1$ |
344 | } |
345 | |
346 | /** |
347 | * Logs an internal error with the specified message. |
348 | * |
349 | * @param message the error message to log |
350 | */ |
351 | public static void logErrorMessage(String message) { |
352 | // this message is intentionally not internationalized, as an exception may |
353 | // be due to the resource bundle itself |
354 | log(newErrorStatus("Internal message logged from API Tools Core: " + message, null)); //$NON-NLS-1$ |
355 | } |
356 | |
357 | /** |
358 | * Returns a new error status for this plug-in with the given message |
359 | * @param message the message to be included in the status |
360 | * @param exception the exception to be included in the status or <code>null</code> if none |
361 | * @return a new error status |
362 | */ |
363 | public static IStatus newErrorStatus(String message, Throwable exception) { |
364 | return new Status(IStatus.ERROR, PLUGIN_ID, INTERNAL_ERROR, message, exception); |
365 | } |
366 | |
367 | /** |
368 | * Returns whether the API tools bundle is running inside an OSGi framework. |
369 | * |
370 | * @return whether the API tools bundle is running inside an OSGi framework |
371 | */ |
372 | public static boolean isRunningInFramework() { |
373 | return fgDefault != null; |
374 | } |
375 | |
376 | /** |
377 | * Returns the {@link IApiBaselineManager}, allowing clients to add/remove and search |
378 | * for {@link org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline}s stored in the manager. |
379 | * |
380 | * @return the singleton instance of the {@link IApiProfileManager} |
381 | */ |
382 | public IApiBaselineManager getApiBaselineManager() { |
383 | return ApiBaselineManager.getManager(); |
384 | } |
385 | |
386 | /** |
387 | * @return The singleton instance of the {@link JavadocTagManager} |
388 | */ |
389 | public static JavadocTagManager getJavadocTagManager() { |
390 | if(fgTagManager == null) { |
391 | fgTagManager = new JavadocTagManager(); |
392 | } |
393 | return fgTagManager; |
394 | } |
395 | |
396 | /** |
397 | * Adds the given save participant to the listing of participants to |
398 | * be notified when the workbench saving life-cycle occurs. If the specified |
399 | * participant is <code>null</code> no changes are made. |
400 | * @param participant |
401 | */ |
402 | public void addSaveParticipant(ISaveParticipant participant) { |
403 | if(participant != null) { |
404 | savelisteners.add(participant); |
405 | } |
406 | } |
407 | |
408 | /** |
409 | * Removes the given save participant from the current listing. |
410 | * If the specified participant is <code>null</code> no changes are made. |
411 | * @param participant |
412 | */ |
413 | public void removeSaveParticipant(ISaveParticipant participant) { |
414 | if(participant != null) { |
415 | savelisteners.remove(participant); |
416 | } |
417 | } |
418 | |
419 | /* (non-Javadoc) |
420 | * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext) |
421 | */ |
422 | public void doneSaving(ISaveContext context) { |
423 | ISaveParticipant sp = null; |
424 | for(Iterator iter = savelisteners.iterator(); iter.hasNext();) { |
425 | sp = (ISaveParticipant) iter.next(); |
426 | sp.doneSaving(context); |
427 | } |
428 | } |
429 | |
430 | /* (non-Javadoc) |
431 | * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext) |
432 | */ |
433 | public void prepareToSave(ISaveContext context) throws CoreException { |
434 | ISaveParticipant sp = null; |
435 | for(Iterator iter = savelisteners.iterator(); iter.hasNext();) { |
436 | sp = (ISaveParticipant) iter.next(); |
437 | sp.prepareToSave(context); |
438 | } |
439 | } |
440 | |
441 | /* (non-Javadoc) |
442 | * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext) |
443 | */ |
444 | public void rollback(ISaveContext context) { |
445 | ISaveParticipant sp = null; |
446 | for(Iterator iter = savelisteners.iterator(); iter.hasNext();) { |
447 | sp = (ISaveParticipant) iter.next(); |
448 | sp.rollback(context); |
449 | } |
450 | } |
451 | |
452 | /* (non-Javadoc) |
453 | * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext) |
454 | */ |
455 | public void saving(ISaveContext context) throws CoreException { |
456 | if(context.getKind() == ISaveContext.FULL_SAVE) { |
457 | context.needDelta(); |
458 | } |
459 | ISaveParticipant sp = null; |
460 | for(Iterator iter = savelisteners.iterator(); iter.hasNext();) { |
461 | sp = (ISaveParticipant) iter.next(); |
462 | sp.saving(context); |
463 | } |
464 | IEclipsePreferences node = new InstanceScope().getNode(PLUGIN_ID); |
465 | if(node != null) { |
466 | try { |
467 | node.flush(); |
468 | } catch (BackingStoreException e) { |
469 | log(e); |
470 | } |
471 | } |
472 | } |
473 | |
474 | /* (non-Javadoc) |
475 | * @see org.eclipse.core.runtime.Plugin#start(org.osgi.framework.BundleContext) |
476 | */ |
477 | public void start(BundleContext context) throws Exception { |
478 | try { |
479 | super.start(context); |
480 | } finally { |
481 | ResourcesPlugin.getWorkspace().addSaveParticipant(this, this); |
482 | configurePluginDebugOptions(); |
483 | } |
484 | } |
485 | |
486 | /* (non-Javadoc) |
487 | * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) |
488 | */ |
489 | public void stop(BundleContext context) throws Exception { |
490 | try { |
491 | ApiDescriptionManager.shutdown(); |
492 | ApiBaselineManager.getManager().stop(); |
493 | ResourcesPlugin.getWorkspace().removeSaveParticipant(this); |
494 | FileManager.getManager().deleteFiles(); |
495 | } |
496 | finally { |
497 | super.stop(context); |
498 | } |
499 | } |
500 | |
501 | /** |
502 | * Returns the severity for the specific key from the given {@link IProject}. |
503 | * If the project does not have project specific settings, the workspace preference |
504 | * is returned. If <code>null</code> is passed in as the project the workspace |
505 | * preferences are consulted. |
506 | * |
507 | * @param prefkey the given preference key |
508 | * @param project the given project or <code>null</code> |
509 | * @return the severity level for the given pref key |
510 | */ |
511 | public int getSeverityLevel(String prefkey, IProject project) { |
512 | IPreferencesService service = Platform.getPreferencesService(); |
513 | List scopes = new ArrayList(); |
514 | scopes.add(new InstanceScope()); |
515 | if(project != null) { |
516 | scopes.add(new ProjectScope(project)); |
517 | } |
518 | String value = service.getString(PLUGIN_ID, prefkey, null, (IScopeContext[]) scopes.toArray(new IScopeContext[scopes.size()])); |
519 | if(value == null) { |
520 | value = service.getString(PLUGIN_ID, prefkey, VALUE_IGNORE, new IScopeContext[]{new DefaultScope()}); |
521 | } |
522 | if(VALUE_ERROR.equals(value)) { |
523 | return SEVERITY_ERROR; |
524 | } |
525 | if(VALUE_WARNING.equals(value)) { |
526 | return SEVERITY_WARNING; |
527 | } |
528 | return SEVERITY_IGNORE; |
529 | } |
530 | |
531 | public ISessionManager getSessionManager() { |
532 | if(fgSessionManager == null) { |
533 | fgSessionManager = new SessionManager(); |
534 | } |
535 | return fgSessionManager; |
536 | } |
537 | |
538 | /** |
539 | * Returns the enable state for the specific key from the given {@link IProject}. |
540 | * If the project does not have project specific settings, the workspace preference |
541 | * is returned. If <code>null</code> is passed in as the project the workspace |
542 | * preferences are consulted. |
543 | * |
544 | * @param prefkey the given preference key |
545 | * @param project the given project or <code>null</code> |
546 | * @return the enable state |
547 | */ |
548 | public String getEnableState(String prefkey, IProject project) { |
549 | IPreferencesService service = Platform.getPreferencesService(); |
550 | List scopes = new ArrayList(); |
551 | scopes.add(new InstanceScope()); |
552 | if(project != null) { |
553 | scopes.add(new ProjectScope(project)); |
554 | } |
555 | String value = service.getString(PLUGIN_ID, prefkey, null, (IScopeContext[]) scopes.toArray(new IScopeContext[scopes.size()])); |
556 | if(value == null) { |
557 | value = service.getString(PLUGIN_ID, prefkey, VALUE_DISABLED, new IScopeContext[]{new DefaultScope()}); |
558 | } |
559 | return value; |
560 | } |
561 | /** |
562 | * Method to configure all of the debug options for this plugin |
563 | */ |
564 | public void configurePluginDebugOptions(){ |
565 | if(ApiPlugin.getDefault().isDebugging()){ |
566 | String option = Platform.getDebugOption(BUILDER_DEBUG); |
567 | if(option != null) { |
568 | ApiAnalysisBuilder.setDebug(option.equalsIgnoreCase(TRUE)); |
569 | } |
570 | option = Platform.getDebugOption(DELTA_DEBUG); |
571 | if(option != null) { |
572 | boolean debugValue = option.equalsIgnoreCase(TRUE); |
573 | ClassFileComparator.setDebug(debugValue); |
574 | ApiComparator.setDebug(debugValue); |
575 | } |
576 | option = Platform.getDebugOption(CLASSFILE_VISITOR_DEBUG); |
577 | if(option != null) { |
578 | ReferenceExtractor.setDebug(option.equalsIgnoreCase(TRUE)); |
579 | } |
580 | option = Platform.getDebugOption(DESCRIPTOR_FRAMEWORK_DEBUG); |
581 | if(option != null) { |
582 | ElementDescriptorImpl.setDebug(option.equalsIgnoreCase(TRUE)); |
583 | } |
584 | option = Platform.getDebugOption(TAG_SCANNER_DEBUG); |
585 | if(option != null) { |
586 | TagScanner.setDebug(option.equalsIgnoreCase(TRUE)); |
587 | } |
588 | option = Platform.getDebugOption(PLUGIN_WORKSPACE_COMPONENT_DEBUG); |
589 | if(option != null) { |
590 | PluginProjectApiComponent.setDebug(option.equalsIgnoreCase(TRUE)); |
591 | } |
592 | option = Platform.getDebugOption(API_PROFILE_MANAGER_DEBUG); |
593 | if(option != null) { |
594 | ApiBaselineManager.setDebug(option.equalsIgnoreCase(TRUE)); |
595 | } |
596 | option = Platform.getDebugOption(API_FILTER_STORE_DEBUG); |
597 | if(option != null) { |
598 | ApiFilterStore.setDebug(option.equalsIgnoreCase(TRUE)); |
599 | } |
600 | option = Platform.getDebugOption(API_REFERENCE_ANALYZER_DEBUG); |
601 | if(option != null) { |
602 | ReferenceAnalyzer.setDebug(option.equalsIgnoreCase(TRUE)); |
603 | } |
604 | option = Platform.getDebugOption(REFERENCE_RESOLVER_DEBUG); |
605 | if(option != null) { |
606 | ReferenceResolver.setDebug(option.equalsIgnoreCase(TRUE)); |
607 | } |
608 | option = Platform.getDebugOption(PROBLEM_DETECTOR_DEBUG); |
609 | if(option != null) { |
610 | AbstractProblemDetector.setDebug(option.equals(TRUE)); |
611 | } |
612 | option = Platform.getDebugOption(API_DESCRIPTION); |
613 | if(option != null) { |
614 | ApiDescription.setDebug(option.equals(TRUE)); |
615 | } |
616 | } |
617 | } |
618 | } |