| /******************************************************************************* |
| * Copyright (c) 2015, 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.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.lang.reflect.Type; |
| import java.text.ParseException; |
| import java.text.SimpleDateFormat; |
| import java.util.Date; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.TimeZone; |
| |
| import org.apache.http.HttpStatus; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.linuxtools.internal.mylyn.osio.rest.core.response.data.IdNamed; |
| import org.eclipse.linuxtools.internal.mylyn.osio.rest.core.response.data.Space; |
| import org.eclipse.mylyn.commons.core.operations.IOperationMonitor; |
| import org.eclipse.mylyn.commons.repositories.http.core.CommonHttpClient; |
| import org.eclipse.mylyn.commons.repositories.http.core.CommonHttpResponse; |
| import org.eclipse.mylyn.commons.repositories.http.core.HttpUtil; |
| import org.eclipse.mylyn.tasks.core.TaskRepository; |
| import org.eclipse.mylyn.tasks.core.data.TaskAttribute; |
| import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper; |
| import org.eclipse.mylyn.tasks.core.data.TaskData; |
| import org.eclipse.osgi.util.NLS; |
| |
| import com.google.gson.GsonBuilder; |
| import com.google.gson.JsonArray; |
| import com.google.gson.JsonDeserializationContext; |
| import com.google.gson.JsonDeserializer; |
| import com.google.gson.JsonElement; |
| import com.google.gson.JsonObject; |
| import com.google.gson.JsonParseException; |
| import com.google.gson.reflect.TypeToken; |
| |
| public class OSIORestGetSingleTaskData extends OSIORestGetRequest<TaskData> { |
| |
| private final TaskRepository taskRepository; |
| private final OSIORestConfiguration taskConfiguration; |
| |
| private final OSIORestConnector connector; |
| |
| public OSIORestGetSingleTaskData(@SuppressWarnings("restriction") CommonHttpClient client, OSIORestConnector connector, String urlSuffix, |
| TaskRepository taskRepository) throws CoreException { |
| super(client, urlSuffix, null); //$NON-NLS-1$ |
| this.taskRepository = taskRepository; |
| this.taskConfiguration = connector.getRepositoryConfiguration(taskRepository); |
| this.connector = connector; |
| } |
| |
| @Override |
| protected TaskData parseFromJson(InputStreamReader in) throws OSIORestException { |
| TypeToken<TaskData> type = new TypeToken<TaskData>() { |
| }; |
| return new GsonBuilder().registerTypeAdapter(type.getType(), new JSonTaskDataDeserializer()) |
| .create() |
| .fromJson(in, type.getType()); |
| } |
| |
| @Override |
| protected TaskData doProcess(CommonHttpResponse response, IOperationMonitor monitor) |
| throws IOException, OSIORestException { |
| InputStream is = response.getResponseEntityAsStream(); |
| InputStreamReader in = new InputStreamReader(is); |
| return parseFromJson(in); |
| } |
| |
| @Override |
| protected void doValidate(CommonHttpResponse response, IOperationMonitor monitor) |
| throws IOException, OSIORestException { |
| int statusCode = response.getStatusCode(); |
| if (statusCode != 400 && statusCode != 200) { |
| if (statusCode == HttpStatus.SC_NOT_FOUND) { |
| throw new OSIORestResourceNotFoundException( |
| NLS.bind("Requested resource ''{0}'' does not exist", response.getRequestPath())); |
| } |
| throw new OSIORestException(NLS.bind("Unexpected response from OSIO REST server for ''{0}'': {1}", |
| response.getRequestPath(), HttpUtil.getStatusText(statusCode))); |
| } |
| |
| } |
| |
| OSIORestTaskSchema taskSchema = OSIORestTaskSchema.getDefault(); |
| |
| private class JSonTaskDataDeserializer implements JsonDeserializer<TaskData> { |
| |
| @Override |
| public TaskData deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) |
| throws JsonParseException { |
| OSIORestTaskDataHandler dataHandler = (OSIORestTaskDataHandler) connector.getTaskDataHandler(); |
| TaskAttributeMapper mapper = dataHandler.getAttributeMapper(taskRepository); |
| JsonObject workitemdata = json.getAsJsonObject().get("data").getAsJsonObject(); //$NON-NLS-1$ |
| JsonObject attributes = workitemdata.get("attributes").getAsJsonObject(); //$NON-NLS-1$ |
| JsonObject relationships = workitemdata.get("relationships").getAsJsonObject(); //$NON-NLS-1$ |
| JsonObject space = relationships.get("space").getAsJsonObject(); //$NON-NLS-1$ |
| JsonObject spaceData = space.get("data").getAsJsonObject(); //$NON-NLS-1$ |
| String spaceId = spaceData.get("id").getAsString(); //$NON-NLS-1$ |
| Map<String, Space> spaces = taskConfiguration.getSpaces(); |
| Space actualSpace = null; |
| for (Space entry : spaces.values()) { |
| if (entry.getId().equals(spaceId)) { |
| actualSpace = entry; |
| break; |
| } |
| } |
| String spaceName = actualSpace.getName(); |
| int number = attributes.get("system.number").getAsInt(); //$NON-NLS-1$ |
| String taskId = spaceName + "#" + number; //$NON-NLS-1$ |
| TaskData taskData = null; |
| taskData = new TaskData(mapper, connector.getConnectorKind(), taskRepository.getRepositoryUrl(), |
| taskId); |
| try { |
| dataHandler.initializeTaskData(taskRepository, taskData, null, null); |
| } catch (CoreException e) { |
| com.google.common.base.Throwables.propagate(e); |
| } |
| TaskAttribute idAttribute = taskData.getRoot().getAttribute(taskSchema.ID.getKey()); |
| idAttribute.setValue(taskId); |
| TaskAttribute uuidAttribute = taskData.getRoot().getAttribute(taskSchema.UUID.getKey()); |
| String uuid = workitemdata.get("id").getAsString(); //$NON-NLS-1$ |
| uuidAttribute.setValue(uuid); |
| TaskAttribute spaceAttribute = taskData.getRoot().getAttribute(taskSchema.SPACE.getKey()); |
| spaceAttribute.setValue(spaceName); |
| // handle fields in the attributes section |
| for (Entry<String, JsonElement> entry : attributes.entrySet()) { |
| String attributeId = OSIORestTaskSchema.getAttributeNameFromFieldName(entry.getKey()); |
| if (entry.getKey().equals("system.updated_at")) { //$NON-NLS-1$ |
| TaskAttribute attribute = taskData.getRoot() |
| .getAttribute(taskSchema.DATE_MODIFICATION.getKey()); |
| JsonElement value = entry.getValue(); //.get("real_name"); |
| if (attribute != null) { |
| try { |
| SimpleDateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'", //$NON-NLS-1$ |
| Locale.US); |
| iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC")); //$NON-NLS-1$ |
| Date tempDate = iso8601Format.parse(value.getAsString()); |
| attribute.setValue(Long.toString(tempDate.getTime())); |
| continue; |
| } catch (ParseException e) { |
| com.google.common.base.Throwables.propagate( |
| new CoreException(new Status(IStatus.ERROR, OSIORestCore.ID_PLUGIN, |
| "Can not parse Date (" + value.getAsString() + ")"))); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| } else if (entry.getKey().equals("system.created_at")) { //$NON-NLS-1$ |
| TaskAttribute attribute = taskData.getRoot() |
| .getAttribute(taskSchema.DATE_CREATION.getKey()); |
| JsonElement value = entry.getValue(); //.get("real_name"); |
| if (attribute != null) { |
| try { |
| SimpleDateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'", //$NON-NLS-1$ |
| Locale.US); |
| iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC")); //$NON-NLS-1$ |
| Date tempDate = iso8601Format.parse(value.getAsString()); |
| attribute.setValue(Long.toString(tempDate.getTime())); |
| continue; |
| } catch (ParseException e) { |
| com.google.common.base.Throwables.propagate( |
| new CoreException(new Status(IStatus.ERROR, OSIORestCore.ID_PLUGIN, |
| "Can not parse Date (" + value.getAsString() + ")"))); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| } |
| |
| TaskAttribute attribute = taskData.getRoot().getAttribute(attributeId); |
| if (attribute != null) { |
| JsonElement value = entry.getValue(); |
| if (!value.isJsonNull()) { |
| if (value.isJsonArray()) { |
| JsonArray valueArray = value.getAsJsonArray(); |
| attribute.clearValues(); |
| for (JsonElement jsonElement : valueArray) { |
| attribute.addValue(jsonElement.getAsString()); |
| } |
| } else { |
| attribute.setValue(entry.getValue().getAsString()); |
| } |
| } |
| } |
| } |
| // handle fields in the relationships section |
| for (Entry<String, JsonElement> entry : relationships.entrySet()) { |
| String attributeId = OSIORestTaskSchema.getAttributeNameFromFieldName(entry.getKey()); |
| if (attributeId.equals("space") //$NON-NLS-1$ |
| || attributeId.equals("assignees") //$NON-NLS-1$ |
| || attributeId.equals("creator") //$NON-NLS-1$ |
| || attributeId.equals("children")) { //$NON-NLS-1$ |
| continue; |
| } |
| TaskAttribute attribute = taskData.getRoot().getAttribute(attributeId); |
| if (attribute != null) { |
| JsonObject entryObject = entry.getValue().getAsJsonObject(); |
| if (entryObject.has("data")) { //$NON-NLS-1$ |
| JsonObject entryData = entryObject.get("data").getAsJsonObject(); //$NON-NLS-1$ |
| String entryId = entryData.get("id").getAsString(); //$NON-NLS-1$ |
| Map<String, IdNamed> itemMap = actualSpace.getMapFor(entry.getKey()); |
| if (itemMap != null) { |
| for (Entry<String, IdNamed> itemEntry : itemMap.entrySet()) { |
| if (itemEntry.getValue().getId().equals(entryId)) { |
| attribute.setValue(itemEntry.getKey()); |
| break; |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| // add assignee id (will resolve later) |
| TaskAttribute assigneeIDs = taskData.getRoot().getAttribute(taskSchema.ASSIGNEE_IDS.getKey()); |
| JsonObject assigneeObject = relationships.get("assignees").getAsJsonObject(); //$NON-NLS-1$ |
| if (assigneeObject.get("data") != null) { //$NON-NLS-1$ |
| JsonArray assigneeArray = assigneeObject.get("data").getAsJsonArray(); //$NON-NLS-1$ |
| for (JsonElement entry : assigneeArray) { |
| JsonObject entryObject = entry.getAsJsonObject(); |
| String id = entryObject.get("id").getAsString(); //$NON-NLS-1$ |
| assigneeIDs.addValue(id); |
| } |
| } |
| |
| // add creator id (will resolve later) |
| TaskAttribute creatorID = taskData.getRoot().getAttribute(taskSchema.CREATOR_ID.getKey()); |
| JsonObject creatorObject = relationships.get("creator").getAsJsonObject(); //$NON-NLS-1$ |
| JsonObject creatorData = creatorObject.get("data").getAsJsonObject(); //$NON-NLS-1$ |
| creatorID.setValue(creatorData.get("id").getAsString()); |
| |
| // add workitem url |
| TaskAttribute workitemURL = taskData.getRoot().getAttribute(taskSchema.TASK_URL.getKey()); |
| JsonObject linksObject = workitemdata.get("links").getAsJsonObject(); //$NON-NLS-1$ |
| String workitemself = linksObject.get("self").getAsString(); //$NON-NLS-1$ |
| workitemURL.setValue(workitemself); |
| |
| OSIORestConfiguration config; |
| try { |
| config = connector.getRepositoryConfiguration(taskRepository); |
| if (config != null) { |
| config.addValidOperations(taskData); |
| } |
| } catch (CoreException e) { |
| com.google.common.base.Throwables.propagate(e); |
| } |
| return taskData; |
| } |
| |
| } |
| |
| } |