blob: 1622bf5d97b35b21ef3c7b73be71763900d8787e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.navigator.extensions;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.internal.navigator.NavigatorContentService;
import org.eclipse.ui.internal.navigator.NavigatorPlugin;
import org.eclipse.ui.navigator.ICommonContentProvider;
import org.eclipse.ui.navigator.ICommonLabelProvider;
import org.eclipse.ui.navigator.IExtensionStateModel;
import org.eclipse.ui.navigator.IMementoAware;
import org.eclipse.ui.navigator.INavigatorContentDescriptor;
import org.eclipse.ui.navigator.INavigatorContentExtension;
/**
* <p>
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as
* part of a work in progress. There is a guarantee neither that this API will
* work nor that it will remain the same. Please do not use this API without
* consulting with the Platform/UI team.
* </p>
*
* @since 3.2
*/
public class NavigatorContentExtension implements IMementoAware,
INavigatorContentExtension {
private static final NavigatorContentExtension[] NO_EXTENSIONS = new NavigatorContentExtension[0];
private NavigatorContentService contentService;
private NavigatorContentDescriptor descriptor;
private ICommonContentProvider contentProvider;
private ICommonLabelProvider labelProvider;
private boolean labelProviderInitializationFailed = false;
private boolean contentProviderInitializationFailed = false;
private boolean isDisposed = false;
private IMemento appliedMemento;
private StructuredViewerManager viewerManager;
/**
* Create an object to manage the instantiated elements from the extension.
*
* @param aDescriptor
* The descriptor that knows how to create elements and knows the
* id of the extension
* @param aContentService
* The content service that will manage this extension
* @param aViewerManager
* The viewer manager that knows how to initialize the content
* provider created by this extension.
*/
public NavigatorContentExtension(NavigatorContentDescriptor aDescriptor,
NavigatorContentService aContentService,
StructuredViewerManager aViewerManager) {
super();
Assert.isNotNull(aDescriptor);
descriptor = aDescriptor;
contentService = aContentService;
viewerManager = aViewerManager;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension#getId()
*/
public String getId() {
return descriptor.getId();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension#getDescriptor()
*/
public INavigatorContentDescriptor getDescriptor() {
return descriptor;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.navigator.INavigatorContentExtension#getContentProvider()
*/
public ITreeContentProvider getContentProvider() {
ITreeContentProvider provider = internalGetContentProvider();
if (provider != SkeletonTreeContentProvider.INSTANCE) {
return ((SafeDelegateTreeContentProvider) provider)
.getDelegateContentProvider();
}
return provider;
}
/**
*
* @return The internal content provider that is wrapped by this extension.
*/
public ITreeContentProvider internalGetContentProvider() {
if (contentProvider != null || contentProviderInitializationFailed) {
return contentProvider;
}
synchronized (this) {
try {
if (contentProvider == null) {
ITreeContentProvider treeContentProvider = descriptor
.createContentProvider();
if (treeContentProvider != null) {
contentProvider = new SafeDelegateTreeContentProvider(
treeContentProvider, descriptor, contentService);
contentProvider.init(new CommonContentExtensionSite(
getId(), contentService, appliedMemento));
viewerManager.initialize(contentProvider);
} else {
contentProvider = SkeletonTreeContentProvider.INSTANCE;
}
}
} catch (CoreException e) {
contentProviderInitializationFailed = true;
e.printStackTrace();
} catch (RuntimeException e) {
contentProviderInitializationFailed = true;
e.printStackTrace();
}
if (contentProviderInitializationFailed) {
contentProvider = SkeletonTreeContentProvider.INSTANCE;
}
}
return contentProvider;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension#getLabelProvider()
*/
public ICommonLabelProvider getLabelProvider() {
if (labelProvider != null || labelProviderInitializationFailed) {
return labelProvider;
}
synchronized (this) {
try {
if (labelProvider == null) {
ILabelProvider tempLabelProvider = descriptor
.createLabelProvider();
if (tempLabelProvider instanceof ICommonLabelProvider) {
labelProvider = (ICommonLabelProvider) tempLabelProvider;
labelProvider.init(new CommonContentExtensionSite(
getId(), contentService, appliedMemento));
} else {
labelProvider = new SafeDelegateCommonLabelProvider(
tempLabelProvider);
}
labelProvider.addListener( (ILabelProviderListener)contentService.createCommonLabelProvider() );
}
} catch (CoreException e) {
labelProviderInitializationFailed = true;
e.printStackTrace();
} catch (RuntimeException e) {
labelProviderInitializationFailed = true;
e.printStackTrace();
}
if (labelProviderInitializationFailed) {
labelProvider = SkeletonLabelProvider.INSTANCE;
}
}
return labelProvider;
}
/**
* Dispose of any resources acquired during the lifecycle of the extension.
*
*/
public void dispose() {
try {
synchronized (this) {
SafeRunner.run(new ISafeRunnable() {
public void handleException(Throwable exception) {
String msg = exception.getMessage() != null ? exception.getMessage() : exception.toString() ;
NavigatorPlugin.logError(0, msg, exception);
}
public void run() throws Exception {
if (contentProvider != null) {
contentProvider.dispose();
}
}
});
SafeRunner.run(new ISafeRunnable() {
public void handleException(Throwable exception) {
String msg = exception.getMessage() != null ? exception.getMessage() : exception.toString() ;
NavigatorPlugin.logError(0, msg, exception);
}
public void run() throws Exception {
if (labelProvider != null) {
labelProvider.removeListener((ILabelProviderListener)contentService.createCommonLabelProvider());
labelProvider.dispose();
}
}
});
}
} finally {
isDisposed = true;
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
*/
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension#getAdapter(java.lang.Class)
*/
public Object getAdapter(Class adapter) {
return null;
}
/**
* @return Returns the contentProviderInitializationFailed.
*/
public boolean hasContentProviderInitializationFailed() {
return contentProviderInitializationFailed;
}
/**
* @return Returns the labelProviderInitializationFailed.
*/
public boolean hasLabelProviderInitializationFailed() {
return labelProviderInitializationFailed;
}
/**
*
* @return True if the loading of the content provider has failed.
*/
public boolean hasLoadingFailed() {
return contentProviderInitializationFailed;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension#isLoaded()
*/
public boolean isLoaded() {
return contentProvider != null;
}
public void restoreState(IMemento aMemento) {
synchronized (this) {
appliedMemento = aMemento;
applyMemento(contentProvider);
applyMemento(labelProvider);
}
}
public void saveState(IMemento aMemento) {
synchronized (this) {
if(contentProvider != null && contentProvider instanceof IMementoAware)
((IMementoAware)contentProvider).saveState(aMemento);
if(labelProvider != null && labelProvider instanceof IMementoAware)
((IMementoAware)labelProvider).saveState(aMemento);
}
}
private void applyMemento(IMementoAware target) {
if (target != null) {
target.restoreState(appliedMemento);
}
}
protected final void complainDisposedIfNecessary() {
if (isDisposed) {
throw new IllegalStateException("INavigatorContentExtension " //$NON-NLS-1$
+ descriptor.getId() + " is disposed!"); //$NON-NLS-1$
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension#getStateModel()
*/
public IExtensionStateModel getStateModel() {
return contentService.getExtensionStateService().getExtensionStateModel(getDescriptor());
}
/**
* @param anElement
* The element for the query.
* @return Returns the overridingExtensions.
*/
public NavigatorContentExtension[] getOverridingExtensionsForTriggerPoint(
Object anElement) {
if (!descriptor.hasOverridingExtensions()) {
return NO_EXTENSIONS;
}
NavigatorContentDescriptor overriddingDescriptor;
Set overridingExtensions = new LinkedHashSet();
for (Iterator contentDescriptorsItr = descriptor
.getOverriddingExtensions().iterator(); contentDescriptorsItr
.hasNext();) {
overriddingDescriptor = (NavigatorContentDescriptor) contentDescriptorsItr
.next();
if (contentService.isActive(overriddingDescriptor.getId())
&& contentService.isVisible(overriddingDescriptor.getId())
&& overriddingDescriptor.isTriggerPoint(anElement)) {
overridingExtensions.add(contentService
.getExtension(overriddingDescriptor));
}
}
if (overridingExtensions.size() == 0) {
return NO_EXTENSIONS;
}
return (NavigatorContentExtension[]) overridingExtensions
.toArray(new NavigatorContentExtension[overridingExtensions
.size()]);
}
/**
*
* @param anElement
* The element for the query.
* @return Returns the overridingExtensions.
*/
public NavigatorContentExtension[] getOverridingExtensionsForPossibleChild(
Object anElement) {
if (!descriptor.hasOverridingExtensions()) {
return NO_EXTENSIONS;
}
NavigatorContentDescriptor overriddingDescriptor;
Set overridingExtensions = new LinkedHashSet();
for (Iterator contentDescriptorsItr = descriptor
.getOverriddingExtensions().iterator(); contentDescriptorsItr
.hasNext();) {
overriddingDescriptor = (NavigatorContentDescriptor) contentDescriptorsItr
.next();
if (contentService.isActive(overriddingDescriptor.getId())
&& contentService.isVisible(overriddingDescriptor.getId())
&& overriddingDescriptor.isPossibleChild(anElement)) {
overridingExtensions.add(contentService
.getExtension(overriddingDescriptor));
}
}
if (overridingExtensions.size() == 0) {
return NO_EXTENSIONS;
}
return (NavigatorContentExtension[]) overridingExtensions
.toArray(new NavigatorContentExtension[overridingExtensions
.size()]);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
public String toString() {
return descriptor.toString() + " Instance"; //$NON-NLS-1$
}
}