/******************************************************************************* * Copyright (c) 2004, 2012 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.tasks.ui.actions; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.mylyn.commons.core.StatusHandler; import org.eclipse.mylyn.internal.tasks.core.AbstractTask; import org.eclipse.mylyn.internal.tasks.core.LocalTask; import org.eclipse.mylyn.internal.tasks.core.Person; import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery; import org.eclipse.mylyn.internal.tasks.core.ScheduledTaskContainer; import org.eclipse.mylyn.internal.tasks.core.TaskCategory; import org.eclipse.mylyn.internal.tasks.core.TaskGroup; import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin; import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal; import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView; import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector; import org.eclipse.mylyn.tasks.core.IRepositoryQuery; import org.eclipse.mylyn.tasks.core.ITask; import org.eclipse.mylyn.tasks.core.ITask.SynchronizationState; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.ui.TasksUi; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IViewActionDelegate; import org.eclipse.ui.IViewPart; import org.eclipse.ui.actions.ActionDelegate; import org.eclipse.ui.actions.ActionFactory; /** * @author Mik Kersten * @author Rob Elves */ public class SynchronizeSelectedAction extends ActionDelegate implements IViewActionDelegate { @Override public void run(IAction action) { TaskListView taskListView = TaskListView.getFromActivePerspective(); if (taskListView != null) { ISelection selection = taskListView.getViewer().getSelection(); if (selection.isEmpty()) { TasksUiInternal.synchronizeAllRepositories(true); } else if (selection instanceof IStructuredSelection) { synchronizeSelected((IStructuredSelection) selection); } } } private void synchronizeSelected(IStructuredSelection selection) { Map<AbstractRepositoryConnector, List<RepositoryQuery>> queriesToSyncMap = new LinkedHashMap<AbstractRepositoryConnector, List<RepositoryQuery>>(); Map<AbstractRepositoryConnector, List<ITask>> tasksToSyncMap = new LinkedHashMap<AbstractRepositoryConnector, List<ITask>>(); // collect queries and tasks for (Object obj : selection.toList()) { if (obj instanceof IRepositoryQuery) { final RepositoryQuery repositoryQuery = (RepositoryQuery) obj; AbstractRepositoryConnector client = TasksUi.getRepositoryManager().getRepositoryConnector( repositoryQuery.getConnectorKind()); if (client != null) { List<RepositoryQuery> queriesToSync = queriesToSyncMap.get(client); if (queriesToSync == null) { queriesToSync = new ArrayList<RepositoryQuery>(); queriesToSyncMap.put(client, queriesToSync); } queriesToSync.add(repositoryQuery); } } else if (obj instanceof TaskCategory) { TaskCategory cat = (TaskCategory) obj; for (ITask task : cat.getChildren()) { AbstractRepositoryConnector client = TasksUi.getRepositoryManager().getRepositoryConnector( task.getConnectorKind()); addTaskToSync(client, task, tasksToSyncMap); } } else if (obj instanceof ITask) { AbstractTask repositoryTask = (AbstractTask) obj; AbstractRepositoryConnector client = TasksUi.getRepositoryManager().getRepositoryConnector( repositoryTask.getConnectorKind()); addTaskToSync(client, repositoryTask, tasksToSyncMap); } else if (obj instanceof ScheduledTaskContainer) { ScheduledTaskContainer scheduledContainer = (ScheduledTaskContainer) obj; for (ITask task : scheduledContainer.getChildren()) { AbstractRepositoryConnector client = TasksUi.getRepositoryManager().getRepositoryConnector( task.getConnectorKind()); addTaskToSync(client, task, tasksToSyncMap); } } else if (obj instanceof Person) { Person person = (Person) obj; for (ITask task : person.getChildren()) { AbstractRepositoryConnector client = TasksUi.getRepositoryManager().getRepositoryConnector( task.getConnectorKind()); addTaskToSync(client, task, tasksToSyncMap); } } else if (obj instanceof TaskGroup) { TaskGroup group = (TaskGroup) obj; for (ITask task : group.getChildren()) { AbstractRepositoryConnector client = TasksUi.getRepositoryManager().getRepositoryConnector( task.getConnectorKind()); addTaskToSync(client, task, tasksToSyncMap); } } } // update queries if (!queriesToSyncMap.isEmpty()) { // determine which repositories to synch changed tasks for HashMap<TaskRepository, Set<RepositoryQuery>> repositoriesToSync = new HashMap<TaskRepository, Set<RepositoryQuery>>(); for (AbstractRepositoryConnector connector : queriesToSyncMap.keySet()) { List<RepositoryQuery> queriesToSync = queriesToSyncMap.get(connector); if (queriesToSync == null || queriesToSync.isEmpty()) { continue; } for (RepositoryQuery query : queriesToSync) { TaskRepository repos = TasksUi.getRepositoryManager().getRepository(query.getConnectorKind(), query.getRepositoryUrl()); if (repos == null) { StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Failed to synchronize query \"" + query.getUrl() //$NON-NLS-1$ + "\" because Repository is null")); //$NON-NLS-1$ continue; } Set<RepositoryQuery> queries = repositoriesToSync.get(repos); if (queries == null) { queries = new HashSet<RepositoryQuery>(); repositoriesToSync.put(repos, queries); } queries.add(query); } } for (Map.Entry<TaskRepository, Set<RepositoryQuery>> entry : repositoriesToSync.entrySet()) { TaskRepository repository = entry.getKey(); AbstractRepositoryConnector connector = TasksUi.getRepositoryManager().getRepositoryConnector( repository.getConnectorKind()); Set<RepositoryQuery> queries = entry.getValue(); TasksUiInternal.synchronizeQueries(connector, repository, queries, null, true); } } // update tasks if (!tasksToSyncMap.isEmpty()) { for (AbstractRepositoryConnector connector : tasksToSyncMap.keySet()) { List<ITask> tasksToSync = tasksToSyncMap.get(connector); if (tasksToSync != null && tasksToSync.size() > 0) { TasksUiInternal.synchronizeTasks(connector, new HashSet<ITask>(tasksToSync), true, null); } } } } private void addTaskToSync(AbstractRepositoryConnector connector, ITask task, Map<AbstractRepositoryConnector, List<ITask>> tasksToSyncMap) { if (connector == null // || task instanceof LocalTask // || task.getSynchronizationState() == SynchronizationState.OUTGOING_NEW) { return; } List<ITask> tasksToSync = tasksToSyncMap.get(connector); if (tasksToSync == null) { tasksToSync = new ArrayList<ITask>(); tasksToSyncMap.put(connector, tasksToSync); } tasksToSync.add(task); } private IAction action; @Override public void init(IAction action) { this.action = action; } public void init(IViewPart view) { IActionBars actionBars = view.getViewSite().getActionBars(); actionBars.setGlobalActionHandler(ActionFactory.REFRESH.getId(), action); actionBars.updateActionBars(); } }