001: /*******************************************************************************
002: * Copyright (c) 2003, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.navigator.extensions;
011:
012: import java.util.Iterator;
013: import java.util.LinkedHashSet;
014: import java.util.Set;
015:
016: import org.eclipse.core.runtime.Assert;
017: import org.eclipse.core.runtime.CoreException;
018: import org.eclipse.core.runtime.ISafeRunnable;
019: import org.eclipse.core.runtime.SafeRunner;
020: import org.eclipse.jface.viewers.ILabelProvider;
021: import org.eclipse.jface.viewers.ILabelProviderListener;
022: import org.eclipse.jface.viewers.ITreeContentProvider;
023: import org.eclipse.ui.IMemento;
024: import org.eclipse.ui.internal.navigator.NavigatorContentService;
025: import org.eclipse.ui.internal.navigator.NavigatorPlugin;
026: import org.eclipse.ui.navigator.ICommonContentProvider;
027: import org.eclipse.ui.navigator.ICommonLabelProvider;
028: import org.eclipse.ui.navigator.IExtensionStateModel;
029: import org.eclipse.ui.navigator.IMementoAware;
030: import org.eclipse.ui.navigator.INavigatorContentDescriptor;
031: import org.eclipse.ui.navigator.INavigatorContentExtension;
032:
033: /**
034: * <p>
035: * <strong>EXPERIMENTAL</strong>. This class or interface has been added as
036: * part of a work in progress. There is a guarantee neither that this API will
037: * work nor that it will remain the same. Please do not use this API without
038: * consulting with the Platform/UI team.
039: * </p>
040: *
041: * @since 3.2
042: */
043: public class NavigatorContentExtension implements IMementoAware,
044: INavigatorContentExtension {
045:
046: private static final NavigatorContentExtension[] NO_EXTENSIONS = new NavigatorContentExtension[0];
047:
048: private NavigatorContentService contentService;
049:
050: private NavigatorContentDescriptor descriptor;
051:
052: private ICommonContentProvider contentProvider;
053:
054: private ICommonLabelProvider labelProvider;
055:
056: private boolean labelProviderInitializationFailed = false;
057:
058: private boolean contentProviderInitializationFailed = false;
059:
060: private boolean isDisposed = false;
061:
062: private IMemento appliedMemento;
063:
064: private StructuredViewerManager viewerManager;
065:
066: /**
067: * Create an object to manage the instantiated elements from the extension.
068: *
069: * @param aDescriptor
070: * The descriptor that knows how to create elements and knows the
071: * id of the extension
072: * @param aContentService
073: * The content service that will manage this extension
074: * @param aViewerManager
075: * The viewer manager that knows how to initialize the content
076: * provider created by this extension.
077: */
078: public NavigatorContentExtension(
079: NavigatorContentDescriptor aDescriptor,
080: NavigatorContentService aContentService,
081: StructuredViewerManager aViewerManager) {
082: super ();
083: Assert.isNotNull(aDescriptor);
084:
085: descriptor = aDescriptor;
086: contentService = aContentService;
087: viewerManager = aViewerManager;
088: }
089:
090: /*
091: * (non-Javadoc)
092: *
093: * @see org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension#getId()
094: */
095: public String getId() {
096: return descriptor.getId();
097: }
098:
099: /*
100: * (non-Javadoc)
101: *
102: * @see org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension#getDescriptor()
103: */
104: public INavigatorContentDescriptor getDescriptor() {
105: return descriptor;
106: }
107:
108: /*
109: * (non-Javadoc)
110: *
111: * @see org.eclipse.ui.navigator.INavigatorContentExtension#getContentProvider()
112: */
113: public ITreeContentProvider getContentProvider() {
114:
115: ITreeContentProvider provider = internalGetContentProvider();
116: if (provider != SkeletonTreeContentProvider.INSTANCE) {
117: return ((SafeDelegateTreeContentProvider) provider)
118: .getDelegateContentProvider();
119: }
120: return provider;
121: }
122:
123: /**
124: *
125: * @return The internal content provider that is wrapped by this extension.
126: */
127: public ITreeContentProvider internalGetContentProvider() {
128: if (contentProvider != null
129: || contentProviderInitializationFailed) {
130: return contentProvider;
131: }
132: synchronized (this ) {
133: try {
134: if (contentProvider == null) {
135: ITreeContentProvider treeContentProvider = descriptor
136: .createContentProvider();
137: if (treeContentProvider != null) {
138: contentProvider = new SafeDelegateTreeContentProvider(
139: treeContentProvider, descriptor,
140: contentService);
141: contentProvider
142: .init(new CommonContentExtensionSite(
143: getId(), contentService,
144: appliedMemento));
145: viewerManager.initialize(contentProvider);
146: } else {
147: contentProvider = SkeletonTreeContentProvider.INSTANCE;
148: }
149: }
150: } catch (CoreException e) {
151: contentProviderInitializationFailed = true;
152: e.printStackTrace();
153: } catch (RuntimeException e) {
154: contentProviderInitializationFailed = true;
155: e.printStackTrace();
156: }
157: if (contentProviderInitializationFailed) {
158: contentProvider = SkeletonTreeContentProvider.INSTANCE;
159: }
160: }
161: return contentProvider;
162: }
163:
164: /*
165: * (non-Javadoc)
166: *
167: * @see org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension#getLabelProvider()
168: */
169: public ICommonLabelProvider getLabelProvider() {
170: if (labelProvider != null || labelProviderInitializationFailed) {
171: return labelProvider;
172: }
173: synchronized (this ) {
174: try {
175:
176: if (labelProvider == null) {
177: ILabelProvider tempLabelProvider = descriptor
178: .createLabelProvider();
179:
180: if (tempLabelProvider instanceof ICommonLabelProvider) {
181: labelProvider = (ICommonLabelProvider) tempLabelProvider;
182: labelProvider
183: .init(new CommonContentExtensionSite(
184: getId(), contentService,
185: appliedMemento));
186: } else {
187: labelProvider = new SafeDelegateCommonLabelProvider(
188: tempLabelProvider);
189: }
190:
191: labelProvider
192: .addListener((ILabelProviderListener) contentService
193: .createCommonLabelProvider());
194: }
195: } catch (CoreException e) {
196: labelProviderInitializationFailed = true;
197: e.printStackTrace();
198: } catch (RuntimeException e) {
199: labelProviderInitializationFailed = true;
200: e.printStackTrace();
201: }
202:
203: if (labelProviderInitializationFailed) {
204: labelProvider = SkeletonLabelProvider.INSTANCE;
205: }
206: }
207: return labelProvider;
208: }
209:
210: /**
211: * Dispose of any resources acquired during the lifecycle of the extension.
212: *
213: */
214: public void dispose() {
215: try {
216: synchronized (this ) {
217:
218: SafeRunner.run(new ISafeRunnable() {
219:
220: public void handleException(Throwable exception) {
221: String msg = exception.getMessage() != null ? exception
222: .getMessage()
223: : exception.toString();
224: NavigatorPlugin.logError(0, msg, exception);
225:
226: }
227:
228: public void run() throws Exception {
229: if (contentProvider != null) {
230: contentProvider.dispose();
231: }
232:
233: }
234:
235: });
236:
237: SafeRunner.run(new ISafeRunnable() {
238:
239: public void handleException(Throwable exception) {
240: String msg = exception.getMessage() != null ? exception
241: .getMessage()
242: : exception.toString();
243: NavigatorPlugin.logError(0, msg, exception);
244:
245: }
246:
247: public void run() throws Exception {
248: if (labelProvider != null) {
249: labelProvider
250: .removeListener((ILabelProviderListener) contentService
251: .createCommonLabelProvider());
252: labelProvider.dispose();
253: }
254:
255: }
256:
257: });
258:
259: }
260: } finally {
261: isDisposed = true;
262: }
263: }
264:
265: /*
266: * (non-Javadoc)
267: *
268: * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
269: */
270: /*
271: * (non-Javadoc)
272: *
273: * @see org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension#getAdapter(java.lang.Class)
274: */
275: public Object getAdapter(Class adapter) {
276: return null;
277: }
278:
279: /**
280: * @return Returns the contentProviderInitializationFailed.
281: */
282: public boolean hasContentProviderInitializationFailed() {
283: return contentProviderInitializationFailed;
284: }
285:
286: /**
287: * @return Returns the labelProviderInitializationFailed.
288: */
289: public boolean hasLabelProviderInitializationFailed() {
290: return labelProviderInitializationFailed;
291: }
292:
293: /**
294: *
295: * @return True if the loading of the content provider has failed.
296: */
297: public boolean hasLoadingFailed() {
298: return contentProviderInitializationFailed;
299: }
300:
301: /*
302: * (non-Javadoc)
303: *
304: * @see org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension#isLoaded()
305: */
306: public boolean isLoaded() {
307: return contentProvider != null;
308: }
309:
310: public void restoreState(IMemento aMemento) {
311: synchronized (this ) {
312: appliedMemento = aMemento;
313: applyMemento(contentProvider);
314: applyMemento(labelProvider);
315:
316: }
317: }
318:
319: public void saveState(IMemento aMemento) {
320: synchronized (this ) {
321: if (contentProvider != null
322: && contentProvider instanceof IMementoAware)
323: ((IMementoAware) contentProvider).saveState(aMemento);
324: if (labelProvider != null
325: && labelProvider instanceof IMementoAware)
326: ((IMementoAware) labelProvider).saveState(aMemento);
327:
328: }
329: }
330:
331: private void applyMemento(IMementoAware target) {
332: if (target != null) {
333: target.restoreState(appliedMemento);
334: }
335:
336: }
337:
338: protected final void complainDisposedIfNecessary() {
339: if (isDisposed) {
340: throw new IllegalStateException(
341: "INavigatorContentExtension " //$NON-NLS-1$
342: + descriptor.getId() + " is disposed!"); //$NON-NLS-1$
343: }
344: }
345:
346: /*
347: * (non-Javadoc)
348: *
349: * @see org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension#getStateModel()
350: */
351: public IExtensionStateModel getStateModel() {
352: return contentService.getExtensionStateService()
353: .getExtensionStateModel(getDescriptor());
354: }
355:
356: /**
357: * @param anElement
358: * The element for the query.
359: * @return Returns the overridingExtensions.
360: */
361: public NavigatorContentExtension[] getOverridingExtensionsForTriggerPoint(
362: Object anElement) {
363: if (!descriptor.hasOverridingExtensions()) {
364: return NO_EXTENSIONS;
365: }
366:
367: NavigatorContentDescriptor overriddingDescriptor;
368: Set overridingExtensions = new LinkedHashSet();
369: for (Iterator contentDescriptorsItr = descriptor
370: .getOverriddingExtensions().iterator(); contentDescriptorsItr
371: .hasNext();) {
372: overriddingDescriptor = (NavigatorContentDescriptor) contentDescriptorsItr
373: .next();
374:
375: if (contentService.isActive(overriddingDescriptor.getId())
376: && contentService.isVisible(overriddingDescriptor
377: .getId())
378: && overriddingDescriptor.isTriggerPoint(anElement)) {
379: overridingExtensions.add(contentService
380: .getExtension(overriddingDescriptor));
381: }
382: }
383: if (overridingExtensions.size() == 0) {
384: return NO_EXTENSIONS;
385: }
386: return (NavigatorContentExtension[]) overridingExtensions
387: .toArray(new NavigatorContentExtension[overridingExtensions
388: .size()]);
389: }
390:
391: /**
392: *
393: * @param anElement
394: * The element for the query.
395: * @return Returns the overridingExtensions.
396: */
397: public NavigatorContentExtension[] getOverridingExtensionsForPossibleChild(
398: Object anElement) {
399: if (!descriptor.hasOverridingExtensions()) {
400: return NO_EXTENSIONS;
401: }
402:
403: NavigatorContentDescriptor overriddingDescriptor;
404: Set overridingExtensions = new LinkedHashSet();
405: for (Iterator contentDescriptorsItr = descriptor
406: .getOverriddingExtensions().iterator(); contentDescriptorsItr
407: .hasNext();) {
408: overriddingDescriptor = (NavigatorContentDescriptor) contentDescriptorsItr
409: .next();
410:
411: if (contentService.isActive(overriddingDescriptor.getId())
412: && contentService.isVisible(overriddingDescriptor
413: .getId())
414: && overriddingDescriptor.isPossibleChild(anElement)) {
415: overridingExtensions.add(contentService
416: .getExtension(overriddingDescriptor));
417: }
418: }
419: if (overridingExtensions.size() == 0) {
420: return NO_EXTENSIONS;
421: }
422: return (NavigatorContentExtension[]) overridingExtensions
423: .toArray(new NavigatorContentExtension[overridingExtensions
424: .size()]);
425: }
426:
427: /*
428: * (non-Javadoc)
429: *
430: * @see java.lang.Object#toString()
431: */
432: public String toString() {
433: return descriptor.toString() + " Instance"; //$NON-NLS-1$
434: }
435: }
|