blob: 787ad80460c622e01e5d26f5b6afd44f8ce021e6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2017 Frank Becker 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:
* Frank Becker - initial API and implementation
* Red Hat Inc. - modified for use with OpenShift.io
*******************************************************************************/
package org.eclipse.linuxtools.internal.mylyn.osio.rest.core;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.linuxtools.internal.mylyn.osio.rest.core.response.data.Space;
import org.eclipse.linuxtools.internal.mylyn.osio.rest.core.response.data.User;
import org.eclipse.linuxtools.internal.mylyn.osio.rest.core.response.data.WorkItemTypeAttributes;
import org.eclipse.linuxtools.internal.mylyn.osio.rest.core.response.data.WorkItemTypeData;
import org.eclipse.linuxtools.internal.mylyn.osio.rest.core.response.data.WorkItemTypeField;
import org.eclipse.linuxtools.internal.mylyn.osio.rest.core.response.data.WorkItemTypeFieldType;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskOperation;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Ordering;
public class OSIORestConfiguration implements Serializable {
private static final OSIORestTaskSchema SCHEMA = OSIORestTaskSchema.getDefault();
private static final long serialVersionUID = 4173223872076958202L;
private final String repositoryId;
private Map<String, Space> spaces;
private Map<String, User> users;
private final static String NEW = "new"; //$NON-NLS-1$
private final static String OPEN = "open"; //$NON-NLS-1$
private final static String IN_PROGRESS = "in progress"; //$NON-NLS-1$
private final static String RESOLVED = "resolved"; //$NON-NLS-1$
private final static String CLOSED = "closed"; //$NON-NLS-1$
private static final List<String> statusValues = Arrays.asList(new String[] {
NEW, OPEN, IN_PROGRESS, RESOLVED, CLOSED});
private static final List<String> newStatusTransitions = Arrays.asList(new String[] {
OPEN, IN_PROGRESS, RESOLVED, CLOSED
});
private static final List<String> openStatusTransitions = Arrays.asList(new String[] {
IN_PROGRESS, RESOLVED, CLOSED
});
private static final List<String> inProgressStatusTransitions = Arrays.asList(new String[] {
OPEN, RESOLVED, CLOSED
});
private static final List<String> resolvedStatusTransitions = Arrays.asList(new String[] {
OPEN, IN_PROGRESS, CLOSED
});
private static final List<String> closedStatusTransitions = Arrays.asList(new String[] {
OPEN, IN_PROGRESS, RESOLVED
});
private Map<String, List<String>> statusTransitions = new HashMap<>();
public OSIORestConfiguration(String repositoryId) {
this.repositoryId = repositoryId;
statusTransitions.put("", statusValues); //$NON-NLS-1$
statusTransitions.put(NEW, newStatusTransitions);
statusTransitions.put(OPEN, openStatusTransitions);
statusTransitions.put(IN_PROGRESS, inProgressStatusTransitions);
statusTransitions.put(RESOLVED, resolvedStatusTransitions);
statusTransitions.put(CLOSED, closedStatusTransitions);
}
public String getRepositoryId() {
return repositoryId;
}
public void setSpaces(Map<String, Space> spaces) {
Function<Space, String> getName = new Function<Space, String>() {
public String apply(Space item) {
return item.getName();
}
};
Function<String, String> comparatorFunction = Functions.compose(getName, Functions.forMap(spaces));
Ordering<String> comparator = Ordering.natural().onResultOf(comparatorFunction);
this.spaces = ImmutableSortedMap.copyOf(spaces, comparator);
}
public Map<String, Space> getSpaces() {
return spaces;
}
public Space getSpaceWithName(String SpaceName) {
return spaces.get(SpaceName);
}
public void updateInitialTaskData(TaskData data) throws CoreException {
setSpaceOptions(data, getSpaces());
updateSpaceOptions(data);
for (String key : data.getRoot().getAttributes().keySet()) {
if (key.equals(OSIORestTaskSchema.getDefault().NEW_COMMENT.getKey())
|| key.equals(TaskAttribute.OPERATION)
|| key.equals(OSIORestTaskSchema.getDefault().DATE_MODIFICATION.getKey())) {
continue;
}
TaskAttribute attribute = data.getRoot().getAttribute(key);
if (key.equals(OSIORestTaskSchema.getDefault().STATUS.getKey())) {
if (attribute.getOptions().isEmpty()) {
for (String status : statusValues) {
attribute.putOption(status, status);
}
}
}
if (!key.equals(SCHEMA.SPACE.getKey())) {
String configName = mapTaskAttributeKey2ConfigurationFields(key);
if (configName.equals("baseType")) {
if (attribute.getOptions().size() == 1 && attribute.getValue().isEmpty()) {
attribute.setValue((String) attribute.getOptions().values().toArray()[0]);
}
}
}
}
}
private String mapTaskAttributeKey2ConfigurationFields(String taskAttributeKey) {
String resultString;
if (taskAttributeKey.equals("task.common.summary")) {
resultString = "system.title";
} else if (taskAttributeKey.equals(TaskAttribute.STATUS)) {
resultString = "system.state"; //$NON-NLS-1$
} else if (taskAttributeKey.equals(TaskAttribute.USER_ASSIGNED)) {
resultString = "assignees"; //$NON-NLS-1$
} else if (taskAttributeKey.equals(TaskAttribute.DESCRIPTION)) {
resultString = "system.description"; //$NON-NLS-1$
} else if (taskAttributeKey.equals("comment")) { //$NON-NLS-1$
resultString = "longdesc"; //$NON-NLS-1$
} else {
resultString = taskAttributeKey;
}
return resultString;
}
private void setAttributeOptionsForSpace(TaskAttribute taskAttribute, Space actualSpace) {
taskAttribute.clearOptions();
if (taskAttribute.getId().equals(SCHEMA.WORKITEM_TYPE.getKey())) {
internalSetAttributeOptions(taskAttribute, actualSpace.getWorkItemTypes());
} else if (taskAttribute.getId().equals(SCHEMA.AREA.getKey())) {
internalSetAttributeOptions(taskAttribute, actualSpace.getAreas());
} else if (taskAttribute.getId().equals(SCHEMA.ITERATION.getKey())) {
internalSetAttributeOptions(taskAttribute, actualSpace.getIterations());
} else if (taskAttribute.getId().equals(SCHEMA.ASSIGNEES.getKey())) {
internalSetAttributeOptions(taskAttribute, actualSpace.getUsers());
} else if (taskAttribute.getId().equals(SCHEMA.STATUS.getKey())) {
Map<String, String> stateMap = new LinkedHashMap<>();
Map<String, WorkItemTypeData> workItemTypes = actualSpace.getWorkItemTypes();
for (Entry<String, WorkItemTypeData> entry : workItemTypes.entrySet()) {
WorkItemTypeData data = entry.getValue();
WorkItemTypeAttributes attributes = data.getWorkItemTypeAttributes();
Map<String, WorkItemTypeField> fields = attributes.getFields();
if (fields != null) {
WorkItemTypeField state = fields.get("system.state"); //$NON-NLS-1
if (state != null) {
WorkItemTypeFieldType stateType = state.getType();
for (String value : stateType.getValues()) {
stateMap.put(value, value);
}
}
}
}
internalSetAttributeOptions(taskAttribute, stateMap);
}
}
private void internalSetAttributeOptions(TaskAttribute taskAttribute, @SuppressWarnings("rawtypes") Map spaceMap) {
boolean found = false;
String actualValue = taskAttribute.getValue();
for (Object entry : spaceMap.keySet()) {
String option = (String)entry;
taskAttribute.putOption(option, option);
if (!found) {
found = actualValue.equals(option);
}
}
if (!found) {
taskAttribute.setValue(""); //$NON-NLS-1$
}
}
public boolean setSpaceOptions(@NonNull TaskData taskData, @NonNull Map<String, Space> spaces) {
TaskAttribute attributeSpace = taskData.getRoot().getMappedAttribute(SCHEMA.SPACE.getKey());
if (attributeSpace != null) {
SortedSet<String> spaceSet = new TreeSet<String>();
for (String key : spaces.keySet()) {
spaceSet.add(key);
}
attributeSpace.clearOptions();
for (String SpaceName : spaceSet) {
attributeSpace.putOption(SpaceName, SpaceName);
}
return true;
}
return false;
}
public boolean updateSpaceOptions(@NonNull TaskData taskData) {
if (taskData == null) {
return false;
}
TaskAttribute attributeSpace = taskData.getRoot().getMappedAttribute(SCHEMA.SPACE.getKey());
if (attributeSpace == null) {
return false;
}
if (!attributeSpace.getValue().isEmpty()) {
Space actualSpace = getSpaceWithName(attributeSpace.getValue());
TaskAttribute attributeWorkItemType = taskData.getRoot().getMappedAttribute(SCHEMA.WORKITEM_TYPE.getKey());
if (attributeWorkItemType != null) {
setAttributeOptionsForSpace(attributeWorkItemType, actualSpace);
}
TaskAttribute attributeArea = taskData.getRoot().getMappedAttribute(SCHEMA.AREA.getKey());
if (attributeArea != null) {
setAttributeOptionsForSpace(attributeArea, actualSpace);
}
TaskAttribute attributeIteration = taskData.getRoot().getMappedAttribute(SCHEMA.ITERATION.getKey());
if (attributeIteration != null) {
setAttributeOptionsForSpace(attributeIteration, actualSpace);
}
TaskAttribute attributeAssignees = taskData.getRoot().getMappedAttribute(SCHEMA.ASSIGNEES.getKey());
if (attributeAssignees != null) {
setAttributeOptionsForSpace(attributeAssignees, actualSpace);
}
TaskAttribute attributeState = taskData.getRoot().getMappedAttribute(SCHEMA.STATUS.getKey());
if (attributeState != null) {
setAttributeOptionsForSpace(attributeState, actualSpace);
}
} else {
SortedSet<String> workItemTypes = new TreeSet<>();
SortedSet<String> areas = new TreeSet<>();
SortedSet<String> iterations = new TreeSet<>();
SortedSet<String> users = new TreeSet<>();
Set<String> states = new LinkedHashSet<>();
for (Space space : getSpaces().values()) {
attributeSpace.putOption(space.getName(), space.getName());
if (space.getWorkItemTypes() != null) {
// assume first workItemType is representative of all with regards to states
if (!space.getWorkItemTypes().isEmpty()) {
WorkItemTypeData data = space.getWorkItemTypes().values().iterator().next();
WorkItemTypeAttributes attributes = data.getWorkItemTypeAttributes();
Map<String, WorkItemTypeField> fields = attributes.getFields();
WorkItemTypeField state = fields.get("system.state"); //$NON-NLS-1$
WorkItemTypeFieldType stateType = state.getType();
String[] values = stateType.getValues();
if (values != null) {
for (String value : values) {
states.add(value);
}
}
}
for (Entry<String, WorkItemTypeData> entry : space.getWorkItemTypes().entrySet()) {
workItemTypes.add(entry.getKey());
WorkItemTypeData data = entry.getValue();
}
}
if (space.getAreas() != null) {
for (String entry : space.getAreas().keySet()) {
areas.add(entry);
}
}
if (space.getIterations() != null) {
for (String entry : space.getIterations().keySet()) {
iterations.add(entry);
}
}
if (space.getUsers() != null) {
for (String entry : space.getUsers().keySet()) {
users.add(entry);
}
}
}
TaskAttribute attributeWorkItemType = taskData.getRoot().getMappedAttribute(SCHEMA.WORKITEM_TYPE.getKey());
if (attributeWorkItemType != null) {
setAllAttributeOptions(attributeWorkItemType, workItemTypes);
}
TaskAttribute attributeState = taskData.getRoot().getMappedAttribute(SCHEMA.STATUS.getKey());
if (attributeState != null) {
setAllAttributeOptions(attributeState, states);
}
}
return true;
}
private void setAllAttributeOptions(TaskAttribute updateAttribute, Set<String> values) {
for (String value : values) {
updateAttribute.putOption(value, value);
}
}
public void addValidOperations(TaskData workItem) {
TaskAttribute attributeStatus = workItem.getRoot().getMappedAttribute(TaskAttribute.STATUS);
String attributeStatusValue = attributeStatus.getValue();
TaskAttribute operationAttribute = workItem.getRoot().getAttribute(TaskAttribute.OPERATION);
if (operationAttribute == null) {
operationAttribute = workItem.getRoot().createAttribute(TaskAttribute.OPERATION);
}
TaskAttribute attribute = workItem.getRoot()
.createAttribute(TaskAttribute.PREFIX_OPERATION + attributeStatusValue);
TaskOperation.applyTo(attribute, attributeStatusValue,
OSIORestMessages.getFormattedString("KeepStateOperation", attributeStatusValue)); //$NON-NLS-1$
// set as default
TaskOperation.applyTo(operationAttribute, attributeStatusValue,
OSIORestMessages.getFormattedString("KeepStateOperation", attributeStatusValue)); //$NON-NLS-1$
for (String statusValue : statusValues) {
if (attributeStatusValue == null ||
(attributeStatusValue != null && attributeStatusValue.equals(statusValue))) {
if (attributeStatusValue == null) {
attributeStatusValue = ""; //$NON-NLS-1$
}
for (String transition : statusTransitions.get(statusValue)) {
attribute = workItem.getRoot()
.createAttribute(TaskAttribute.PREFIX_OPERATION + transition);
TaskOperation.applyTo(attribute, transition,
OSIORestMessages.getFormattedString("StateChangeOperation", transition)); //$NON-NLS-1$
}
}
}
}
}