blob: c88a3c5fad19ab56a591900b1d0e2fc54fc5c465 [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;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.ui.internal.navigator.extensions.NavigatorContentDescriptor;
import org.eclipse.ui.internal.navigator.extensions.NavigatorContentDescriptorManager;
import org.eclipse.ui.navigator.IExtensionActivationListener;
import org.eclipse.ui.navigator.INavigatorActivationService;
import org.eclipse.ui.navigator.INavigatorContentDescriptor;
import org.eclipse.ui.navigator.INavigatorContentService;
/**
*
* The activation service determines if an extension is <i>active</i> within the
* context of a given viewer. If an extension is <i>active</i> then the extension
* will contribute functionality to the viewer. If an extension is not <i>active</i>,
* then the extension will not be given opportunities to contribute
* functionality to the given viewer. See {@link INavigatorContentService} for
* more detail on what states are associated with a content extension.
*
*
* @since 3.2
*/
public final class NavigatorActivationService implements
INavigatorActivationService {
private static final String ACTIVATED_EXTENSIONS = ".activatedExtensions"; //$NON-NLS-1$
private static final NavigatorContentDescriptorManager CONTENT_DESCRIPTOR_REGISTRY = NavigatorContentDescriptorManager
.getInstance();
private static final INavigatorContentDescriptor[] NO_DESCRIPTORS = new INavigatorContentDescriptor[0];
private static final String DELIM = ";"; //$NON-NLS-1$
private static final char EQUALS = '=';
/*
* Set of ids of activated extensions.
*/
//private final Set activatedExtensions = new HashSet();
/*
* Set of ids of activated extensions.
*/
private final Map/*<String, Boolean>*/ activatedExtensionsMap = new HashMap();
/*
* IExtensionActivationListeners
*/
private final ListenerList listeners = new ListenerList();
private INavigatorContentService contentService;
/**
* Create an instance of the service.
*
* @param aContentService
* The associated content service.
*/
public NavigatorActivationService(INavigatorContentService aContentService) {
contentService = aContentService;
revertExtensionActivations();
}
/**
*
* Checks the known activation state for the given viewer id to determine if
* the given navigator extension is 'active'.
*
* @param aNavigatorExtensionId
* The unique identifier associated with a given extension.
*
* @return True if the extension is active in the context of the viewer id.
*/
public boolean isNavigatorExtensionActive(String aNavigatorExtensionId) {
Boolean b = (Boolean) activatedExtensionsMap.get(aNavigatorExtensionId);
if(b != null)
return b.booleanValue();
synchronized (activatedExtensionsMap) {
NavigatorContentDescriptor descriptor = CONTENT_DESCRIPTOR_REGISTRY.getContentDescriptor(aNavigatorExtensionId);
if(descriptor.isActiveByDefault())
activatedExtensionsMap.put(aNavigatorExtensionId, Boolean.TRUE);
else
activatedExtensionsMap.put(aNavigatorExtensionId, Boolean.FALSE);
return descriptor.isActiveByDefault();
}
//return activatedExtensions.contains(aNavigatorExtensionId);
}
/**
* Set the activation state for the given extension in the context of the
* given viewer id. Each instance of an INavigatorContentService listens for
* the activation service to update; and if those instances were created
* with viewers, they will issue a refresh. Otherwise, clients are
* responsible for refreshing the viewers.
*
* <p>
* Clients must call {@link #persistExtensionActivations()} to save
* the the activation state.
* </p>
*
* <p>
* When clients are updating a batch of extensions, consider using
* {@link #setActive(String[], boolean)} when
* possible to avoid unnecessary notifications.
* </p>
*
* @param aNavigatorExtensionId
* The unique identifier associated with a given extension.
* @param toEnable
* True indicates the extension should be enabled; False
* indicates otherwise.
*
*/
public void setActive(
String aNavigatorExtensionId, boolean toEnable) {
boolean currentlyActive = isNavigatorExtensionActive(aNavigatorExtensionId);
if (currentlyActive == toEnable) {
return;
}
if (toEnable) {
//activatedExtensions.add(aNavigatorExtensionId);
activatedExtensionsMap.put(aNavigatorExtensionId, Boolean.TRUE);
} else {
//activatedExtensions.remove(aNavigatorExtensionId);
activatedExtensionsMap.put(aNavigatorExtensionId, Boolean.FALSE);
}
notifyListeners(new String[] { aNavigatorExtensionId }, toEnable);
}
/**
* Set the activation state for the given extension in the context of the
* given viewer id. Each instance of an INavigatorContentService listens for
* the activation service to update; and if those instances were created
* with viewers, they will issue a refresh. Otherwise, clients are
* responsible for refreshing the viewers.
*
* <p>
* Clients must call {@link #persistExtensionActivations()} to save
* the the activation state.
* </p>
*
* @param aNavigatorExtensionIds
* An array of unique identifiers associated with existing
* extension.
* @param toEnable
* True indicates the extension should be enabled; False
* indicates otherwise.
*
*/
public void setActive(String[] aNavigatorExtensionIds,
boolean toEnable) {
if (toEnable) {
for (int i = 0; i < aNavigatorExtensionIds.length; i++) {
//activatedExtensions.add(aNavigatorExtensionIds[i]);
activatedExtensionsMap.put(aNavigatorExtensionIds[i], Boolean.TRUE);
}
} else {
for (int i = 0; i < aNavigatorExtensionIds.length; i++) {
//activatedExtensions.remove(aNavigatorExtensionIds[i]);
activatedExtensionsMap.put(aNavigatorExtensionIds[i], Boolean.FALSE);
}
}
notifyListeners(aNavigatorExtensionIds, toEnable);
}
/**
* Save the activation state for the given viewer.
*
*/
public void persistExtensionActivations() {
Preferences preferences = NavigatorPlugin.getDefault()
.getPluginPreferences();
//synchronized (activatedExtensions) {
synchronized (activatedExtensionsMap) {
//Iterator activatedExtensionsIterator = activatedExtensions.iterator();
Iterator activatedExtensionsIterator = activatedExtensionsMap.keySet().iterator();
/* ensure that the preference will be non-empty */
StringBuffer preferenceValue = new StringBuffer();
String navigatorExtensionId = null;
boolean isActive = false;
while (activatedExtensionsIterator.hasNext()) {
navigatorExtensionId = (String) activatedExtensionsIterator.next();
isActive = isNavigatorExtensionActive(navigatorExtensionId);
preferenceValue.append(navigatorExtensionId)
.append(EQUALS)
.append( isActive ? Boolean.TRUE : Boolean.FALSE )
.append(DELIM);
}
preferences.setValue(getPreferenceKey(), preferenceValue.toString());
}
NavigatorPlugin.getDefault().savePluginPreferences();
}
/**
* Request notification when the activation state changes for the given
* viewer id.
*
* @param aListener
* An implementation of {@link IExtensionActivationListener}
*/
public void addExtensionActivationListener(
IExtensionActivationListener aListener) {
listeners.add(aListener);
}
/**
* No longer receive notification when activation state changes.
*
* @param aListener
* An implementation of {@link IExtensionActivationListener}
*/
public void removeExtensionActivationListener(
IExtensionActivationListener aListener) {
listeners.remove(aListener);
}
private void notifyListeners(String[] navigatorExtensionIds,
boolean toEnable) {
if(navigatorExtensionIds != null) { // should really never be null, but just in case
if(navigatorExtensionIds.length > 1)
Arrays.sort(navigatorExtensionIds);
Object[] listenerArray = listeners.getListeners();
for (int i = 0; i < listenerArray.length; i++) {
((IExtensionActivationListener) listenerArray[i])
.onExtensionActivation(contentService.getViewerId(),
navigatorExtensionIds, toEnable);
}
}
}
private void revertExtensionActivations() {
Preferences preferences = NavigatorPlugin.getDefault()
.getPluginPreferences();
String activatedExtensionsString = preferences
.getString(getPreferenceKey());
if (activatedExtensionsString != null
&& activatedExtensionsString.length() > 0) {
String[] contentExtensionIds = activatedExtensionsString
.split(DELIM);
String id = null;
String booleanString = null;
int indx=0;
for (int i = 0; i < contentExtensionIds.length; i++) {
//activatedExtensions.add(contentExtensionIds[i]);
if( (indx = contentExtensionIds[i].indexOf(EQUALS)) > -1) {
// up to but not including the equals
id = contentExtensionIds[i].substring(0, indx);
booleanString = contentExtensionIds[i].substring(indx+1, contentExtensionIds[i].length());
activatedExtensionsMap.put(id, Boolean.valueOf(booleanString));
} else {
// IS THIS THE RIGHT WAY TO HANDLE THIS CASE?
NavigatorContentDescriptor descriptor = CONTENT_DESCRIPTOR_REGISTRY.getContentDescriptor(contentExtensionIds[i]);
if(descriptor != null)
activatedExtensionsMap.put(id, Boolean.valueOf(descriptor.isActiveByDefault()));
}
}
} else {
/*
* We add the default activation of every known extension, even
* though some may not be bound to the associated content service;
* this is because they could be bound at a later time through the
* programmatic binding mechanism in INavigatorContentService.
*/
INavigatorContentDescriptor[] contentDescriptors = CONTENT_DESCRIPTOR_REGISTRY
.getAllContentDescriptors();
for (int i = 0; i < contentDescriptors.length; i++) {
if (contentDescriptors[i].isActiveByDefault()) {
//activatedExtensions.add(contentDescriptors[i].getId());
activatedExtensionsMap.put(contentDescriptors[i].getId(), Boolean.TRUE);
}
}
}
}
private String getPreferenceKey() {
return contentService.getViewerId() + ACTIVATED_EXTENSIONS;
}
public INavigatorContentDescriptor[] activateExtensions(
String[] extensionIds, boolean toDeactivateAllOthers) {
Set activatedDescriptors = new HashSet();
setActive(extensionIds, true);
for (int extId = 0; extId < extensionIds.length; extId++) {
activatedDescriptors.add(CONTENT_DESCRIPTOR_REGISTRY
.getContentDescriptor(extensionIds[extId]));
}
if (toDeactivateAllOthers) {
NavigatorContentDescriptor[] descriptors = CONTENT_DESCRIPTOR_REGISTRY
.getAllContentDescriptors();
List descriptorList = new ArrayList(Arrays.asList(descriptors));
for (int descriptorIndx = 0; descriptorIndx < descriptors.length; descriptorIndx++) {
for (int extId = 0; extId < extensionIds.length; extId++) {
if (descriptors[descriptorIndx].getId().equals(
extensionIds[extId])) {
descriptorList.remove(descriptors[descriptorIndx]);
}
}
}
String[] deactivatedExtensions = new String[descriptorList.size()];
for (int i = 0; i < descriptorList.size(); i++) {
INavigatorContentDescriptor descriptor = (INavigatorContentDescriptor) descriptorList
.get(i);
deactivatedExtensions[i] = descriptor.getId();
}
setActive(deactivatedExtensions, false);
}
if (activatedDescriptors.size() == 0) {
return NO_DESCRIPTORS;
}
return (INavigatorContentDescriptor[]) activatedDescriptors
.toArray(new NavigatorContentDescriptor[activatedDescriptors
.size()]);
}
public INavigatorContentDescriptor[] deactivateExtensions(
String[] extensionIds, boolean toEnableAllOthers) {
Set activatedDescriptors = new HashSet();
setActive(extensionIds, false);
if (toEnableAllOthers) {
NavigatorContentDescriptor[] descriptors = CONTENT_DESCRIPTOR_REGISTRY
.getAllContentDescriptors();
List descriptorList = new ArrayList(Arrays.asList(descriptors));
for (int descriptorIndx = 0; descriptorIndx < descriptors.length; descriptorIndx++) {
for (int extId = 0; extId < extensionIds.length; extId++) {
if (descriptors[descriptorIndx].getId().equals(
extensionIds[extId])) {
descriptorList.remove(descriptors[descriptorIndx]);
}
}
}
String[] activatedExtensions = new String[descriptorList.size()];
for (int i = 0; i < descriptorList.size(); i++) {
NavigatorContentDescriptor descriptor = (NavigatorContentDescriptor) descriptorList
.get(i);
activatedExtensions[i] = descriptor.getId();
activatedDescriptors.add(descriptor);
}
setActive(activatedExtensions, true);
}
if (activatedDescriptors.size() == 0) {
return NO_DESCRIPTORS;
}
return (INavigatorContentDescriptor[]) activatedDescriptors
.toArray(new NavigatorContentDescriptor[activatedDescriptors
.size()]);
}
}