| /******************************************************************************* |
| * 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()]); |
| } |
| |
| |
| } |