/*******************************************************************************
* Copyright (c) 2013 BREDEX GmbH.
* 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:
* BREDEX GmbH - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.jubula.mylyn.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.jubula.mylyn.Activator;
import org.eclipse.jubula.mylyn.exceptions.InvalidALMAttributeException;
import org.eclipse.jubula.mylyn.i18n.Messages;
import org.eclipse.mylyn.commons.net.AuthenticationType;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.IRepositoryManager;
import org.eclipse.mylyn.tasks.core.IRepositoryModel;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.RepositoryResponse;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler;
import org.eclipse.mylyn.tasks.core.data.ITaskDataManager;
import org.eclipse.mylyn.tasks.core.data.ITaskDataWorkingCopy;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskDataModel;
import org.eclipse.mylyn.tasks.ui.TasksUi;
import org.eclipse.osgi.util.NLS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author BREDEX GmbH
*/
public final class MylynAccess {
/**
* @author BREDEX GmbH
*/
public enum CONNECTOR {
/** default handling type */
DEFAULT,
/** custom handling type */
HP_ALM,
/** tasktop connector */
TASKTOP;
}
/** the logger */
private static final Logger LOG = LoggerFactory
.getLogger(MylynAccess.class);
/** Constructor */
private MylynAccess() {
// hide
}
/**
* @param repoLabel
* the label of the repository
* @return the task repository or <code>null</code> if not found
*/
public static TaskRepository getRepositoryByLabel(String repoLabel) {
List<TaskRepository> allRepositories = getAllRepositories();
for (TaskRepository repo : allRepositories) {
if (repo.getRepositoryLabel().equals(repoLabel)) {
return repo;
}
}
return null;
}
/**
* @return a list of all available task repositories
*/
public static List<TaskRepository> getAllRepositories() {
IRepositoryManager repositoryManager = TasksUi.getRepositoryManager();
return repositoryManager.getAllRepositories();
}
/**
* @param repo
* the task repository
* @param taskId
* the taskId
* @param monitor
* the monitor to use
* @return the task or <code>null</code> if not found
* @throws CoreException
* in case of a problem
*/
public static ITask getTaskByID(TaskRepository repo, String taskId,
IProgressMonitor monitor) throws CoreException {
ITask task = null;
if (validRepository(repo)) {
IRepositoryModel repositoryModel = TasksUi.getRepositoryModel();
task = repositoryModel.getTask(repo, taskId);
if (task == null) {
task = repositoryModel.createTask(repo, taskId);
}
}
return task;
}
/**
* @param repo
* the repository to check
* @return if the repository is valid
*/
private static boolean validRepository(TaskRepository repo) {
return repo != null && !repo.isOffline();
}
/**
* @param repo
* the task repository
* @param taskId
* the taskId
* @param monitor
* the monitor to use
* @return the tasks data or <code>null</code> if not found
* @throws CoreException
* in case of a problem
*/
public static TaskData getTaskDataByID(TaskRepository repo, String taskId,
IProgressMonitor monitor) throws CoreException {
TaskData taskData = null;
if (validRepository(repo)) {
AbstractRepositoryConnector connector = TasksUi
.getRepositoryConnector(repo.getConnectorKind());
if (connector.getConnectorKind().toLowerCase()
.contains(CONNECTOR.TASKTOP.name().toLowerCase())) {
// In Tasktop connector using dash in id is not allowed, so need
// to search by task key
if (connector.supportsSearchByTaskKey(repo)) {
// Fetch partial data to get the task id
TaskData partialTaskData = connector.searchByTaskKey(repo,
taskId, monitor);
if (partialTaskData != null) {
// need to fetch the full task data to modify
taskData = connector.getTaskData(repo,
partialTaskData.getTaskId(), monitor);
}
}
} else {
taskData = connector.getTaskData(repo, taskId, monitor);
}
}
return taskData;
}
/**
* @param repoLabel
* the repository to test the connection for
* @return a status reflecting the current connection state
*/
public static IStatus testConnection(String repoLabel) {
TaskRepository repository = getRepositoryByLabel(repoLabel);
if (repository == null) {
return new Status(IStatus.ERROR, Activator.ID, NLS.bind(
Messages.TaskRepositoryNotFound, repoLabel));
}
if (repository.isOffline()) {
return new Status(IStatus.ERROR, Activator.ID, NLS.bind(
Messages.TaskRepositoryOffline, repoLabel));
}
boolean savePassword = repository
.getSavePassword(AuthenticationType.REPOSITORY);
if (!savePassword) {
return new Status(IStatus.ERROR, Activator.ID, NLS.bind(
Messages.TaskRepositoryNoCredentialsStored, repoLabel));
}
AbstractRepositoryConnector connector = TasksUi
.getRepositoryConnector(repository.getConnectorKind());
if (connector == null) {
return new Status(IStatus.ERROR, Activator.ID, NLS.bind(
Messages.TaskRepositoryNoConnectorFound, repoLabel));
}
try {
connector.updateRepositoryConfiguration(repository,
new NullProgressMonitor());
} catch (CoreException e) {
return new Status(IStatus.ERROR, Activator.ID,
e.getLocalizedMessage().replace("\n\n", " ")); //$NON-NLS-1$ //$NON-NLS-2$
}
IStatus repoStatus = repository.getStatus();
if (repoStatus != null) {
return repoStatus;
}
return Status.OK_STATUS;
}
/**
* Updates fields in ALM system
* @param repo the task repository to perform the update in
* @param taskId task id
* @param attributeUpdates list of field updates
* @param monitor monitor
* @return a list of status information per performed attribute update
*/
public static IStatus updateAttributes(TaskRepository repo,
String taskId, List<Map<String, String>> attributeUpdates,
IProgressMonitor monitor) {
MultiStatus updateInfo = new MultiStatus(Activator.ID,
IStatus.INFO, "Task update is about to start...", null); //$NON-NLS-1$
try {
TaskData taskData = getTaskDataByID(repo, taskId, monitor);
if (taskData != null) {
ITask task = getTaskByID(repo, taskData.getTaskId(),
monitor);
if (task != null) {
String connectorKind = repo.getConnectorKind();
AbstractRepositoryConnector connector = TasksUi
.getRepositoryConnector(connectorKind);
AbstractTaskDataHandler taskDataHandler = connector
.getTaskDataHandler();
ITaskDataManager taskDataManager =
TasksUi.getTaskDataManager();
ITaskDataWorkingCopy taskWorkingCopy = taskDataManager
.createWorkingCopy(task, taskData);
TaskDataModel taskModel = new TaskDataModel(repo, task,
taskWorkingCopy);
TaskAttribute rootData = taskModel.getTaskData()
.getRoot();
for (Map<String, String> udpate : attributeUpdates) {
List<TaskAttribute> changes = attributeUpdateHandling(
udpate, rootData);
if (changes.isEmpty()) {
updateInfo.add(new Status(IStatus.INFO,
Activator.ID, "No changes for Task.")); //$NON-NLS-1$
continue;
}
for (TaskAttribute change : changes) {
taskModel.attributeChanged(change);
}
RepositoryResponse response = taskDataHandler
.postTaskData(
taskModel.getTaskRepository(),
taskModel.getTaskData(),
taskModel.getChangedOldAttributes(), monitor);
if (response != null
&& RepositoryResponse.ResponseKind.TASK_UPDATED
.equals(response.getReposonseKind())) {
updateInfo.add(new Status(IStatus.OK,
Activator.ID, "Task has been updated.")); //$NON-NLS-1$
} else {
updateInfo.add(new Status(IStatus.WARNING,
Activator.ID,
"Task might not have been updated successfully.")); //$NON-NLS-1$
}
if (monitor != null && monitor.isCanceled()) {
updateInfo.add(new Status(IStatus.OK,
Activator.ID, "Task update has been cancelled.")); //$NON-NLS-1$
break;
}
}
}
} else {
updateInfo.add(new Status(IStatus.ERROR, Activator.ID,
"No task data found in the given repository!")); //$NON-NLS-1$
}
} catch (InvalidALMAttributeException e) {
updateInfo.add(new Status(IStatus.ERROR, Activator.ID,
e.getMessage()));
} catch (CoreException e) {
updateInfo.add(new Status(IStatus.ERROR, Activator.ID,
e.getLocalizedMessage()));
} catch (IllegalArgumentException e) {
LOG.error(e.getLocalizedMessage(), e);
// This is necessary due to an IllegalArgumentException which might be
// thrown in the TaskDataHandler
updateInfo.add(new Status(IStatus.ERROR, Activator.ID,
e.getLocalizedMessage(), e));
}
return updateInfo;
}
/**
* Creates list of task attributes to change for default repository type
* @param attributesToChange the attributes to update
* @param rootAttr root attribute
* @return list of task attributes to change
* @throws InvalidALMAttributeException
*/
private static List<TaskAttribute> attributeUpdateHandling(
Map<String, String> attributesToChange, TaskAttribute rootAttr)
throws InvalidALMAttributeException {
List<TaskAttribute> changes = new ArrayList<TaskAttribute>();
for (String key : attributesToChange.keySet()) {
if (StringUtils.isBlank(key)) {
throw new InvalidALMAttributeException(
Messages.BlankAttributeID);
}
TaskAttribute attributeUpdate = rootAttr.getAttribute(key);
if (attributeUpdate == null) {
throw new InvalidALMAttributeException(NLS.bind(
Messages.InvalidAttributeID, key));
}
if (attributeUpdate.getMetaData().isReadOnly()) {
throw new InvalidALMAttributeException(NLS.bind(
Messages.ReadOnlyAttributeID, key));
}
String value = attributesToChange.get(key);
Map<String, String> options = attributeUpdate.getOptions();
if (options != null && !options.isEmpty()) {
if (!options.containsKey(value)) {
throw new InvalidALMAttributeException(NLS.bind(
Messages.InvalidValue, value, key));
}
}
attributeUpdate.setValue(value);
changes.add(attributeUpdate);
}
return changes;
}
}