/******************************************************************************* * Copyright (c) 2004, 2013 Tasktop Technologies 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: * Tasktop Technologies - initial API and implementation *******************************************************************************/ package org.eclipse.mylyn.internal.team.ui; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.mylyn.commons.core.StatusHandler; import org.eclipse.mylyn.context.core.IInteractionContext; import org.eclipse.mylyn.context.core.IInteractionElement; import org.eclipse.mylyn.tasks.core.ITask; import org.eclipse.mylyn.tasks.ui.TasksUi; import org.eclipse.mylyn.team.ui.AbstractActiveChangeSetProvider; import org.eclipse.mylyn.team.ui.AbstractContextChangeSetManager; import org.eclipse.mylyn.team.ui.IContextChangeSet; import org.eclipse.team.internal.core.subscribers.ActiveChangeSet; import org.eclipse.team.internal.core.subscribers.ActiveChangeSetManager; import org.eclipse.team.internal.core.subscribers.ChangeSet; import org.eclipse.team.internal.core.subscribers.IChangeSetChangeListener; /** * NOTE: this class contains several work-arounds for change set limitations in the Platform/Team support. * * @author Mik Kersten */ public class ContextActiveChangeSetManager extends AbstractContextChangeSetManager { private final List<ActiveChangeSetManager> changeSetManagers = new ArrayList<ActiveChangeSetManager>(); private final List<IContextChangeSet> activeChangeSets = new ArrayList<IContextChangeSet>(); private final Map<ActiveChangeSetManager, ChangeSetChangeListener> listenerByManager = new HashMap<ActiveChangeSetManager, ChangeSetChangeListener>(); /** * Used to restore change sets managed with task context when platform deletes them, bug 168129 */ private class ChangeSetChangeListener implements IChangeSetChangeListener { private final ActiveChangeSetManager manager; public ChangeSetChangeListener(ActiveChangeSetManager manager) { this.manager = manager; } public void setRemoved(ChangeSet set) { if (set instanceof IContextChangeSet) { IContextChangeSet contextChangeSet = (IContextChangeSet) set; // never matches the noTask change set: its task is never active if (contextChangeSet.getTask() != null && contextChangeSet.getTask().isActive()) { // put it back manager.add((ActiveChangeSet) contextChangeSet); } } } public void setAdded(ChangeSet set) { // ignore } public void defaultSetChanged(ChangeSet previousDefault, ChangeSet set) { // ignore } public void nameChanged(ChangeSet set) { // ignore } public void resourcesChanged(ChangeSet set, IPath[] paths) { // ignore } }; public ContextActiveChangeSetManager() { Collection<AbstractActiveChangeSetProvider> providerList = FocusedTeamUiPlugin.getDefault() .getActiveChangeSetProviders(); for (AbstractActiveChangeSetProvider provider : providerList) { ActiveChangeSetManager changeSetManager = provider.getActiveChangeSetManager(); if (changeSetManager != null) { changeSetManagers.add(changeSetManager); } } } @Override protected void updateChangeSetLabel(ITask task) { for (ActiveChangeSetManager collector : changeSetManagers) { ChangeSet[] sets = collector.getSets(); for (ChangeSet set : sets) { if (set instanceof IContextChangeSet) { IContextChangeSet contextChangeSet = (IContextChangeSet) set; if (contextChangeSet.getTask().equals(task)) { contextChangeSet.updateLabel(); } } } } } @Override public void enable() { super.enable(); for (ActiveChangeSetManager collector : changeSetManagers) { ChangeSetChangeListener listener = listenerByManager.get(collector); if (listener == null) { listener = new ChangeSetChangeListener(collector); listenerByManager.put(collector, listener); collector.addListener(listener); } } } @Override public void disable() { super.disable(); for (ActiveChangeSetManager collector : changeSetManagers) { ChangeSetChangeListener listener = listenerByManager.get(collector); if (listener != null) { collector.removeListener(listener); listenerByManager.remove(collector); } } } @Override protected void initContextChangeSets() { // replace existing change sets with IContextChangeSet for (ActiveChangeSetManager manager : changeSetManagers) { ChangeSet[] sets = manager.getSets(); for (ChangeSet restoredSet : sets) { if (!(restoredSet instanceof IContextChangeSet)) { String encodedTitle = restoredSet.getName(); String taskHandle = ContextChangeSet.getHandleFromPersistedTitle(encodedTitle); ITask task = TasksUi.getRepositoryModel().getTask(taskHandle); if (task != null) { try { IContextChangeSet contextChangeSet = getOrCreateSet(manager, task); if (contextChangeSet instanceof ActiveChangeSet) { contextChangeSet.restoreResources(restoredSet.getResources()); manager.remove(restoredSet); manager.add((ActiveChangeSet) contextChangeSet); } } catch (Exception e) { StatusHandler.log(new Status(IStatus.ERROR, FocusedTeamUiPlugin.ID_PLUGIN, "Could not restore change set", e)); //$NON-NLS-1$ } } } } } } /** * For testing. */ public void clearActiveChangeSets() { activeChangeSets.clear(); } public IResource[] getResources(ITask task) { for (ActiveChangeSetManager collector : changeSetManagers) { ChangeSet[] sets = collector.getSets(); for (ChangeSet set : sets) { if (set instanceof IContextChangeSet) { IContextChangeSet contextChangeSet = (IContextChangeSet) set; if (contextChangeSet.getTask().equals(task) && contextChangeSet instanceof ActiveChangeSet) { return ((ActiveChangeSet) contextChangeSet).getResources(); } } } } return null; } // TODO m4.0 remove deprecated method that is needed maintain backwards compatibility @SuppressWarnings({ "deprecation" }) @Override public void contextActivated(IInteractionContext context) { try { ITask task = getTask(context); if (task != null) { for (ActiveChangeSetManager manager : changeSetManagers) { IContextChangeSet contextChangeSet = getOrCreateSet(manager, task); if (contextChangeSet instanceof ActiveChangeSet) { ActiveChangeSet activeChangeSet = (ActiveChangeSet) contextChangeSet; // List<IResource> interestingResources = ResourcesUiBridgePlugin.getDefault() // .getInterestingResources(context); // activeChangeSet.add(interestingResources.toArray(new IResource[interestingResources.size()])); activeChangeSets.add(contextChangeSet); // makeDefault() will add the change set // if (!manager.contains(activeChangeSet)) { // manager.add(activeChangeSet); // } manager.makeDefault(activeChangeSet); } } } } catch (Exception e) { StatusHandler.log(new Status(IStatus.ERROR, FocusedTeamUiPlugin.ID_PLUGIN, "Could not update change set", e)); //$NON-NLS-1$ } } private IContextChangeSet getOrCreateSet(ActiveChangeSetManager manager, ITask task) { ChangeSet[] sets = manager.getSets(); for (ChangeSet set : sets) { if (set instanceof IContextChangeSet && task.equals(((IContextChangeSet) set).getTask())) { return (IContextChangeSet) set; } } // change set does not exist, create a new one AbstractActiveChangeSetProvider provider = FocusedTeamUiPlugin.getDefault().getActiveChangeSetProvider(manager); return provider.createChangeSet(task); } // TODO m4.0 remove deprecated method that is needed maintain backwards compatibility @SuppressWarnings("deprecation") @Override public void contextDeactivated(IInteractionContext context) { for (ActiveChangeSetManager collector : changeSetManagers) { ChangeSet[] sets = collector.getSets(); for (ChangeSet set : sets) { if (set instanceof ActiveChangeSet) { IResource[] resources = set.getResources(); if (resources == null || resources.length == 0) { collector.remove(set); } } } AbstractActiveChangeSetProvider changeSetProvider = FocusedTeamUiPlugin.getDefault() .getActiveChangeSetProvider(collector); changeSetProvider.activateDefaultChangeSet(); } activeChangeSets.clear(); } // TODO m4.0 remove deprecated method that is needed maintain backwards compatibility @SuppressWarnings({ "restriction", "deprecation" }) @Override public void interestChanged(List<IInteractionElement> elements) { // disabled, see bug 162007 // for (IInteractionElement element : elements) { // AbstractContextStructureBridge bridge = ContextCore.getStructureBridge(element.getContentType()); // try { // if (bridge.isDocument(element.getHandleIdentifier())) { // IResource resource = ResourcesUiBridgePlugin.getDefault().getResourceForElement(element, false); // if (resource != null && resource.exists()) { // for (IContextChangeSet activeContextChangeSet : getActiveChangeSets()) { // if (activeContextChangeSet instanceof ActiveChangeSet) { // if (!((ActiveChangeSet) activeContextChangeSet).contains(resource)) { // if (element.getInterest().isInteresting()) { // ((ActiveChangeSet) activeContextChangeSet).add(new IResource[] { resource }); // } // } // } // } // if (shouldRemove(element)) { // for (ActiveChangeSetManager collector : changeSetManagers) { // ChangeSet[] sets = collector.getSets(); // for (ChangeSet set : sets) { // if (set instanceof ActiveChangeSet) { // set.remove(resource); // } // } // } // } // } // } // } catch (Exception e) { // StatusHandler.log(new Status(IStatus.ERROR, FocusedTeamUiPlugin.ID_PLUGIN, // "Could not manipulate change set resources", e)); //$NON-NLS-1$ // } // } } public List<IContextChangeSet> getActiveChangeSets() { return new ArrayList<IContextChangeSet>(activeChangeSets); } private ITask getTask(IInteractionContext context) { return TasksUi.getTaskActivityManager().getActiveTask(); } /** * Ignores decay. */ // private boolean shouldRemove(IInteractionElement element) { // // TODO: generalize this logic? // return (element.getInterest().getValue() + element.getInterest().getDecayValue()) < ContextCore.getCommonContextScaling() // .getInteresting(); // } }