/******************************************************************************* * Copyright (c) 2004, 2011 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.core.data; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants; import org.eclipse.mylyn.tasks.core.ITask; import org.eclipse.mylyn.tasks.core.data.ITaskDataWorkingCopy; import org.eclipse.mylyn.tasks.core.data.TaskAttribute; import org.eclipse.mylyn.tasks.core.data.TaskData; /** * @author Rob Elves * @author Steffen Pingel */ public class TaskDataState implements ITaskDataWorkingCopy { private final String connectorKind; private TaskData editsTaskData; private TaskData lastReadTaskData; private TaskData localTaskData; private boolean saved; private TaskData repositoryTaskData; private final String repositoryUrl; private ITask task; private final String taskId; private TaskDataManager taskDataManager; public TaskDataState(String connectorKind, String repositoryUrl, String taskId) { Assert.isNotNull(connectorKind); Assert.isNotNull(repositoryUrl); Assert.isNotNull(taskId); this.connectorKind = connectorKind; this.repositoryUrl = repositoryUrl; this.taskId = taskId; this.saved = true; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } TaskDataState other = (TaskDataState) obj; return connectorKind.equals(other.connectorKind) && repositoryUrl.equals(other.repositoryUrl) && taskId.equals(other.taskId); } public String getConnectorKind() { return connectorKind; } public TaskData getEditsData() { return editsTaskData; } public TaskData getLastReadData() { return lastReadTaskData; } public TaskData getLocalData() { return localTaskData; } public TaskData getRepositoryData() { return repositoryTaskData; } public String getRepositoryUrl() { return repositoryUrl; } public String getTaskId() { return taskId; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + connectorKind.hashCode(); result = prime * result + taskId.hashCode(); result = prime * result + repositoryUrl.hashCode(); return result; } void init(TaskDataManager taskSynchronizationManager, ITask task) { this.taskDataManager = taskSynchronizationManager; this.task = task; } public boolean isSaved() { return saved; } public void refresh(IProgressMonitor monitor) throws CoreException { ITaskDataWorkingCopy state = taskDataManager.getWorkingCopy(task); setRepositoryData(state.getRepositoryData()); setEditsData(state.getEditsData()); setLastReadData(state.getLastReadData()); revert(); } public void revert() { localTaskData = new TaskData(repositoryTaskData.getAttributeMapper(), repositoryTaskData.getConnectorKind(), repositoryTaskData.getRepositoryUrl(), repositoryTaskData.getTaskId()); localTaskData.setVersion(repositoryTaskData.getVersion()); deepCopyChildren(repositoryTaskData.getRoot(), localTaskData.getRoot()); if (editsTaskData != null) { deepCopyChildren(editsTaskData.getRoot(), localTaskData.getRoot()); } else { editsTaskData = new TaskData(repositoryTaskData.getAttributeMapper(), repositoryTaskData.getConnectorKind(), repositoryTaskData.getRepositoryUrl(), repositoryTaskData.getTaskId()); editsTaskData.setVersion(repositoryTaskData.getVersion()); } } private void deepCopyChildren(TaskAttribute source, TaskAttribute target) { for (TaskAttribute child : source.getAttributes().values()) { target.deepAddCopy(child); } } public void save(Set<TaskAttribute> edits, IProgressMonitor monitor) throws CoreException { if (edits != null) { for (TaskAttribute edit : edits) { editsTaskData.getRoot().deepAddCopy(edit); } } if (saved) { taskDataManager.putEdits(task, editsTaskData); } else { taskDataManager.saveWorkingCopy(task, this); setSaved(true); } } /** * @see #getEditsData() */ public void setEditsData(TaskData editsTaskData) { this.editsTaskData = editsTaskData; } /** * @see #getLastReadData() */ public void setLastReadData(TaskData oldTaskData) { this.lastReadTaskData = oldTaskData; } /** * @see #getLocalData() */ public void setLocalTaskData(TaskData localTaskData) { this.localTaskData = localTaskData; } void setSaved(boolean saved) { this.saved = saved; } /** * @see #getRepositoryData() */ public void setRepositoryData(TaskData newTaskData) { this.repositoryTaskData = newTaskData; } public void merge(TaskDataState oldState) { setEditsData(createCopy(oldState.getEditsData(), getTaskId())); setLocalTaskData(createCopy(oldState.getLocalData(), getTaskId())); setRepositoryData(createCopy(oldState.getRepositoryData(), getTaskId())); } public void changeAttributeValues(Map<TaskAttribute, Collection<String>> newValues) { changeAttributeValues(localTaskData, newValues); changeAttributeValues(repositoryTaskData, newValues); changeAttributeValues(editsTaskData, newValues); changeAttributeValues(lastReadTaskData, newValues); } private void changeAttributeValues(TaskData taskData, Map<TaskAttribute, Collection<String>> newValues) { if (taskData != null) { for (TaskAttribute key : newValues.keySet()) { TaskAttribute attribute = taskData.getRoot().getMappedAttribute(key.getPath()); if (attribute != null) { attribute.setValues(new ArrayList<>(newValues.get(key))); } } } } public static TaskData createCopy(TaskData oldData) { if (oldData == null) { return null; } return createCopy(oldData, oldData.getTaskId()); } private static TaskData createCopy(TaskData oldData, String newTaskId) { if (oldData == null) { return null; } TaskData newData = new TaskData(oldData.getAttributeMapper(), oldData.getConnectorKind(), oldData.getRepositoryUrl(), newTaskId); newData.setVersion(oldData.getVersion()); for (TaskAttribute child : oldData.getRoot().getAttributes().values()) { newData.getRoot().deepAddCopy(child); } return newData; } public void refactorAttribute(TaskAttribute attribute) throws CoreException { refactorAttribute(localTaskData, attribute); refactorAttribute(repositoryTaskData, attribute); refactorAttribute(editsTaskData, attribute); refactorAttribute(lastReadTaskData, attribute); } private void refactorAttribute(TaskData taskData, TaskAttribute attribute) throws CoreException { if (taskData != null) { String[] path = attribute.getPath(); if (path.length == 0) { throw new CoreException( new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, Messages.TaskDataState_RefactorRoot)); } String[] shortenedPath = Arrays.copyOfRange(path, 0, path.length - 1); TaskAttribute parent = taskData.getRoot().getMappedAttribute(shortenedPath); if (parent != null) { parent.removeAttribute(attribute.getId()); parent.deepAddCopy(attribute); } } } }