Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Becker2015-02-21 14:31:52 +0000
committerGerrit Code Review @ Eclipse.org2015-07-30 19:59:09 +0000
commit869a056a29aac2a817adb0b2ce02b1bbe1d07a89 (patch)
tree539f5fd70d4fd346a90420f4507fdd04f5dd27cc
parentc3774ec86109fd47097b974ee51f2c0d2538305a (diff)
downloadorg.eclipse.mylyn.tasks-869a056a29aac2a817adb0b2ce02b1bbe1d07a89.tar.gz
org.eclipse.mylyn.tasks-869a056a29aac2a817adb0b2ce02b1bbe1d07a89.tar.xz
org.eclipse.mylyn.tasks-869a056a29aac2a817adb0b2ce02b1bbe1d07a89.zip
414360: add support for Task update
Change-Id: I4374580bfe58dafe735c95820c434f8d7100bb85 Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=414360
-rw-r--r--connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestClientTest.java107
-rw-r--r--connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/test/support/BugzillaRestHarness.java65
-rw-r--r--connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedPutRequest.java103
-rw-r--r--connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java8
-rw-r--r--connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConfiguration.java17
-rw-r--r--connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPutUpdateTask.java214
-rw-r--r--connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskDataHandler.java3
-rw-r--r--connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskSchema.java30
-rw-r--r--connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/response/data/PutUpdateEntry.java36
-rw-r--r--connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/response/data/PutUpdateResult.java24
10 files changed, 576 insertions, 31 deletions
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestClientTest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestClientTest.java
index 2344b658d..9c0ecb330 100644
--- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestClientTest.java
+++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestClientTest.java
@@ -11,14 +11,17 @@
package org.eclipse.mylyn.internal.bugzilla.rest.core.tests;
+import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -38,12 +41,13 @@ import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestConfiguration;
import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestConnector;
import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestCreateTaskSchema;
import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestException;
+import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestTaskSchema;
import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestVersion;
-import org.eclipse.mylyn.internal.bugzilla.rest.core.SingleTaskDataCollector;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Field;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.LoginToken;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Parameters;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Product;
+import org.eclipse.mylyn.internal.bugzilla.rest.test.support.BugzillaRestHarness;
import org.eclipse.mylyn.internal.bugzilla.rest.test.support.BugzillaRestTestFixture;
import org.eclipse.mylyn.internal.commons.core.operations.NullOperationMonitor;
import org.eclipse.mylyn.internal.commons.repositories.core.InMemoryCredentialsStore;
@@ -54,6 +58,7 @@ import org.eclipse.mylyn.tasks.core.TaskMapping;
import org.eclipse.mylyn.tasks.core.TaskMapping;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler;
+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.mylyn.tasks.core.data.TaskMapper;
@@ -80,13 +85,16 @@ public class BugzillaRestClientTest {
private BugzillaRestConnector connector;
+ private BugzillaRestHarness harness;
+
public BugzillaRestClientTest(BugzillaRestTestFixture fixture) {
this.actualFixture = fixture;
}
@Before
public void setUp() {
- connector = new BugzillaRestConnector();
+ connector = actualFixture.connector();
+ harness = actualFixture.createHarness();
}
@Test
@@ -254,8 +262,8 @@ public class BugzillaRestClientTest {
taskDataHandler.initializeTaskData(actualFixture.repository(), taskData, taskMappingInit, null);
taskData.getRoot().getAttribute("cf_dropdown").setValue("one");
try {
- connector.getClient(actualFixture.repository()).postTaskData(taskData, null);
- fail("BugzillaRestException expected, never reach this!");
+ connector.getClient(actualFixture.repository()).postTaskData(taskData, null, null);
+ fail("never reach this!");
} catch (BugzillaRestException e) {
String url = actualFixture.getRepositoryUrl();
assertEquals("You must select/enter a product. (status: Bad Request from "
@@ -298,7 +306,7 @@ public class BugzillaRestClientTest {
taskDataHandler.initializeTaskData(actualFixture.repository(), taskData, taskMappingInit, null);
taskData.getRoot().getAttribute("cf_dropdown").setValue("one");
try {
- connector.getClient(actualFixture.repository()).postTaskData(taskData, null);
+ connector.getClient(actualFixture.repository()).postTaskData(taskData, null, null);
fail("never reach this!");
} catch (BugzillaRestException e) {
String url = actualFixture.getRepositoryUrl();
@@ -344,7 +352,8 @@ public class BugzillaRestClientTest {
taskData.getRoot()
.getAttribute(BugzillaRestCreateTaskSchema.getDefault().TARGET_MILESTONE.getKey())
.setValue("M2");
- RepositoryResponse reposonse = connector.getClient(actualFixture.repository()).postTaskData(taskData, null);
+ RepositoryResponse reposonse = connector.getClient(actualFixture.repository()).postTaskData(taskData, null,
+ null);
assertEquals(ResponseKind.TASK_CREATED, reposonse.getReposonseKind());
}
@@ -393,7 +402,7 @@ public class BugzillaRestClientTest {
connector.getTaskMapping(taskDataSubmit).merge(mapper1);
RepositoryResponse reposonse = connector.getClient(actualFixture.repository()).postTaskData(taskDataSubmit,
- null);
+ null, null);
assertEquals(ResponseKind.TASK_CREATED, reposonse.getReposonseKind());
}
@@ -425,31 +434,25 @@ public class BugzillaRestClientTest {
return "R1";
}
};
- AbstractTaskDataHandler taskDataHandler = connector.getTaskDataHandler();
- TaskAttributeMapper mapper = taskDataHandler.getAttributeMapper(actualFixture.repository());
- TaskData taskData = new TaskData(mapper, actualFixture.repository().getConnectorKind(),
- actualFixture.repository().getRepositoryUrl(), "");
- taskDataHandler.initializeTaskData(actualFixture.repository(), taskData, taskMappingInit, null);
+ TaskData taskData = harness.createTaskData(taskMappingInit, null, null);
+
taskData.getRoot().getAttribute("cf_dropdown").setValue("one");
taskData.getRoot()
.getAttribute(BugzillaRestCreateTaskSchema.getDefault().TARGET_MILESTONE.getKey())
.setValue("M2");
- RepositoryResponse reposonse = connector.getClient(actualFixture.repository()).postTaskData(taskData, null);
- assertEquals(ResponseKind.TASK_CREATED, reposonse.getReposonseKind());
- String taskId = reposonse.getTaskId();
- Set<String> taskIds = new HashSet<String>();
- taskIds.add(taskId);
- SingleTaskDataCollector singleTaskDataCollector = new SingleTaskDataCollector();
- connector.getClient(actualFixture.repository()).getTaskData(taskIds, actualFixture.repository(),
- singleTaskDataCollector, null);
- TaskData taskDataGet = singleTaskDataCollector.getTaskData();
- assertNotNull(taskDataGet);
- assertNotNull(taskDataGet.getRoot());
+ String taskId = harness.submitNewTask(taskData);
+ TaskData taskDataGet = harness.getTaskFromServer(taskId);
// actual we read no comments and so we also can not get the description
taskData.getRoot().removeAttribute("task.common.description");
taskDataGet.getRoot().removeAttribute("task.common.description");
+ // resolution is only for new tasks readonly
+ taskData.getRoot()
+ .getAttribute(BugzillaRestTaskSchema.getDefault().RESOLUTION.getKey())
+ .getMetaData()
+ .setReadOnly(false);
+
// attributes we know that they can not be equal
taskData.getRoot().removeAttribute("task.common.status");
taskDataGet.getRoot().removeAttribute("task.common.status");
@@ -471,9 +474,65 @@ public class BugzillaRestClientTest {
taskDataGet.getRoot().removeAttribute("task.common.operation-RESOLVED");
taskDataGet.getRoot().removeAttribute("resolutionInput");
taskDataGet.getRoot().removeAttribute("task.common.operation-duplicate");
- taskDataGet.getRoot().removeAttribute("dup_id");
+ taskDataGet.getRoot().removeAttribute("dupe_of");
assertEquals(taskData.getRoot().toString(), taskDataGet.getRoot().toString());
}
+ @Test
+ public void testUpdateTaskData() throws Exception {
+ String taskId = harness.getTaksId4TestProduct();
+ TaskData taskDataGet = harness.getTaskFromServer(taskId);
+
+ Set<TaskAttribute> changed = new HashSet<TaskAttribute>();
+
+ TaskAttribute attribute = taskDataGet.getRoot()
+ .getMappedAttribute(BugzillaRestCreateTaskSchema.getDefault().PRODUCT.getKey());
+ attribute.setValue("Product with Spaces");
+ changed.add(attribute);
+ attribute = taskDataGet.getRoot()
+ .getMappedAttribute(BugzillaRestCreateTaskSchema.getDefault().COMPONENT.getKey());
+ attribute.setValue("Component 1");
+ changed.add(attribute);
+ attribute = taskDataGet.getRoot()
+ .getMappedAttribute(BugzillaRestCreateTaskSchema.getDefault().VERSION.getKey());
+ attribute.setValue("b");
+ changed.add(attribute);
+ attribute = taskDataGet.getRoot()
+ .getMappedAttribute(BugzillaRestCreateTaskSchema.getDefault().TARGET_MILESTONE.getKey());
+ attribute.setValue("M3.0");
+ changed.add(attribute);
+
+ attribute = taskDataGet.getRoot().getAttribute("cf_dropdown");
+ attribute.setValue("two");
+ changed.add(attribute);
+ attribute = taskDataGet.getRoot().getAttribute("cf_multiselect");
+ attribute.setValues(Arrays.asList("Red", "Yellow"));
+ changed.add(attribute);
+
+ //Act
+ RepositoryResponse reposonse = connector.getClient(actualFixture.repository()).postTaskData(taskDataGet,
+ changed, null);
+
+ //Assert
+ TaskData taskDataUpdate = harness.getTaskFromServer(taskId);
+
+ attribute = taskDataGet.getRoot()
+ .getMappedAttribute(BugzillaRestCreateTaskSchema.getDefault().PRODUCT.getKey());
+ assertThat(attribute.getValue(), is("Product with Spaces"));
+ attribute = taskDataGet.getRoot()
+ .getMappedAttribute(BugzillaRestCreateTaskSchema.getDefault().COMPONENT.getKey());
+ assertThat(attribute.getValue(), is("Component 1"));
+ attribute = taskDataGet.getRoot()
+ .getMappedAttribute(BugzillaRestCreateTaskSchema.getDefault().VERSION.getKey());
+ assertThat(attribute.getValue(), is("b"));
+ attribute = taskDataGet.getRoot()
+ .getAttribute(BugzillaRestCreateTaskSchema.getDefault().TARGET_MILESTONE.getKey());
+ assertThat(attribute.getValue(), is("M3.0"));
+ attribute = taskDataUpdate.getRoot().getAttribute("cf_dropdown");
+ assertThat(attribute.getValue(), is("two"));
+ attribute = taskDataUpdate.getRoot().getAttribute("cf_multiselect");
+ assertThat(attribute.getValues(), is(Arrays.asList("Red", "Yellow")));
+ }
+
}
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/test/support/BugzillaRestHarness.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/test/support/BugzillaRestHarness.java
index aaa5da856..0c018787b 100644
--- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/test/support/BugzillaRestHarness.java
+++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/test/support/BugzillaRestHarness.java
@@ -11,13 +11,26 @@
package org.eclipse.mylyn.internal.bugzilla.rest.test.support;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import java.util.HashSet;
+import java.util.Set;
+
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.bugzilla.rest.core.BugzillaRestConnector;
import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestCore;
+import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestCreateTaskSchema;
+import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestException;
+import org.eclipse.mylyn.internal.bugzilla.rest.core.SingleTaskDataCollector;
import org.eclipse.mylyn.tasks.core.ITaskMapping;
+import org.eclipse.mylyn.tasks.core.RepositoryResponse;
+import org.eclipse.mylyn.tasks.core.RepositoryResponse.ResponseKind;
+import org.eclipse.mylyn.tasks.core.TaskMapping;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler;
import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper;
@@ -54,4 +67,56 @@ public class BugzillaRestHarness {
return taskData;
}
+ public String submitNewTask(TaskData taskData) throws BugzillaRestException, CoreException {
+ RepositoryResponse reposonse = connector().getClient(repository()).postTaskData(taskData, null, null);
+ assertThat(reposonse.getReposonseKind(), is(ResponseKind.TASK_CREATED));
+ return reposonse.getTaskId();
+ }
+
+ public TaskData getTaskFromServer(String taskId) throws BugzillaRestException, CoreException {
+ Set<String> taskIds = new HashSet<String>();
+ taskIds.add(taskId);
+ SingleTaskDataCollector singleTaskDataCollector = new SingleTaskDataCollector();
+ connector().getClient(repository()).getTaskData(taskIds, repository(), singleTaskDataCollector, null);
+ TaskData taskDataGet = singleTaskDataCollector.getTaskData();
+ assertNotNull(taskDataGet);
+ assertNotNull(taskDataGet.getRoot());
+ return taskDataGet;
+ }
+
+ public String getTaksId4TestProduct() throws BugzillaRestException, CoreException {
+ final TaskMapping taskMappingInit = new TaskMapping() {
+ @Override
+ public String getSummary() {
+ return "The Summary";
+ }
+
+ @Override
+ public String getDescription() {
+ return "The Description";
+ }
+
+ @Override
+ public String getProduct() {
+ return "ManualTest";
+ }
+
+ @Override
+ public String getComponent() {
+ return "ManualC1";
+ }
+
+ @Override
+ public String getVersion() {
+ return "R1";
+ }
+ };
+ TaskData taskData = createTaskData(taskMappingInit, null, null);
+ taskData.getRoot().getAttribute("cf_dropdown").setValue("one");
+ taskData.getRoot()
+ .getAttribute(BugzillaRestCreateTaskSchema.getDefault().TARGET_MILESTONE.getKey())
+ .setValue("M1");
+ String taskId = submitNewTask(taskData);
+ return taskId;
+ }
}
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedPutRequest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedPutRequest.java
new file mode 100644
index 000000000..df6ef3f55
--- /dev/null
+++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedPutRequest.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.bugzilla.rest.core;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.text.MessageFormat;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.eclipse.mylyn.commons.core.operations.IOperationMonitor;
+import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationException;
+import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationRequest;
+import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationType;
+import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials;
+import org.eclipse.mylyn.commons.repositories.http.core.CommonHttpResponse;
+import org.eclipse.mylyn.commons.repositories.http.core.HttpUtil;
+import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.LoginToken;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+public abstract class BugzillaRestAuthenticatedPutRequest<T> extends BugzillaRestRequest<T> {
+
+ public BugzillaRestAuthenticatedPutRequest(BugzillaRestHttpClient client) {
+ super(client);
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ protected void authenticate(IOperationMonitor monitor) throws IOException {
+ UserCredentials credentials = getClient().getLocation().getCredentials(AuthenticationType.REPOSITORY);
+ if (credentials == null) {
+ throw new IllegalStateException("Authentication requested without valid credentials");
+ }
+ HttpRequestBase request = new HttpGet(baseUrl()
+ + MessageFormat.format("/login?login={0}&password={1}", new Object[] { credentials.getUserName(),
+ credentials.getPassword() }));
+ request.setHeader(CONTENT_TYPE, TEXT_XML_CHARSET_UTF_8);
+ request.setHeader(ACCEPT, APPLICATION_JSON);
+ HttpResponse response = getClient().execute(request, monitor);
+ try {
+ if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
+ getClient().setAuthenticated(false);
+ throw new AuthenticationException("Authentication failed",
+ new AuthenticationRequest<AuthenticationType<UserCredentials>>(getClient().getLocation(),
+ AuthenticationType.REPOSITORY));
+ } else {
+ TypeToken<LoginToken> type = new TypeToken<LoginToken>() {
+ };
+ InputStream is = response.getEntity().getContent();
+ InputStreamReader in = new InputStreamReader(is);
+ LoginToken loginToken = new Gson().fromJson(in, type.getType());
+ ((BugzillaRestHttpClient) getClient()).setLoginToken(loginToken);
+ getClient().setAuthenticated(true);
+ }
+ } finally {
+ HttpUtil.release(request, response, monitor);
+ }
+ }
+
+ @Override
+ protected T execute(IOperationMonitor monitor) throws IOException, BugzillaRestException {
+ if (needsAuthentication() && ((BugzillaRestHttpClient) getClient()).getLoginToken() == null) {
+ authenticate(monitor);
+ }
+ HttpRequestBase request = createHttpRequestBase();
+ CommonHttpResponse response = execute(request, monitor);
+ return processAndRelease(response, monitor);
+ }
+
+ @Override
+ protected HttpRequestBase createHttpRequestBase() {
+ String bugUrl = getUrlSuffix();
+ LoginToken token = ((BugzillaRestHttpClient) getClient()).getLoginToken();
+ if (token != null && bugUrl.length() > 0) {
+ if (bugUrl.endsWith("?")) { //$NON-NLS-1$
+ bugUrl += ("token=" + token.getToken()); //$NON-NLS-1$
+ } else {
+ bugUrl += ("&token=" + token.getToken()); //$NON-NLS-1$
+ }
+ }
+
+ HttpPut request = new HttpPut(baseUrl() + bugUrl);
+ request.setHeader(CONTENT_TYPE, APPLICATION_JSON);
+ request.setHeader(ACCEPT, APPLICATION_JSON);
+ return request;
+ }
+
+} \ No newline at end of file
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java
index 9593445a6..1eb602ab2 100644
--- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java
+++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java
@@ -29,11 +29,13 @@ import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Named;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.ParameterResponse;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Product;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.ProductResponse;
+import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.PutUpdateResult;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.RestResponse;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.VersionResponse;
import org.eclipse.mylyn.tasks.core.RepositoryResponse;
import org.eclipse.mylyn.tasks.core.RepositoryResponse.ResponseKind;
import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskDataCollector;
@@ -116,12 +118,14 @@ public class BugzillaRestClient {
}).run(monitor);
}
- public RepositoryResponse postTaskData(TaskData taskData, IOperationMonitor monitor) throws BugzillaRestException {
+ public RepositoryResponse postTaskData(TaskData taskData, Set<TaskAttribute> oldAttributes,
+ IOperationMonitor monitor) throws BugzillaRestException {
if (taskData.isNew()) {
BugzillaRestIdResult result = new BugzillaRestPostNewTask(client, taskData).run(monitor);
return new RepositoryResponse(ResponseKind.TASK_CREATED, result.getId());
} else {
- throw new UnsupportedOperationException();
+ PutUpdateResult result = new BugzillaRestPutUpdateTask(client, taskData, oldAttributes).run(monitor);
+ return new RepositoryResponse(ResponseKind.TASK_UPDATED, result.getBugs()[0].getId());
}
}
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConfiguration.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConfiguration.java
index 1572e3818..3dbf3bc8b 100644
--- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConfiguration.java
+++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConfiguration.java
@@ -120,6 +120,7 @@ public class BugzillaRestConfiguration implements Serializable {
for (String key : data.getRoot().getAttributes().keySet()) {
if (key.equals(BugzillaRestTaskSchema.getDefault().ADD_SELF_CC.getKey())
|| key.equals(BugzillaRestTaskSchema.getDefault().NEW_COMMENT.getKey())
+ || key.equals(BugzillaRestTaskSchema.getDefault().DUPE_OF.getKey())
|| key.equals(TaskAttribute.OPERATION)) {
continue;
}
@@ -396,6 +397,11 @@ public class BugzillaRestConfiguration implements Serializable {
}
TaskAttribute attribute = bugReport.getRoot()
.createAttribute(TaskAttribute.PREFIX_OPERATION + attributeStatusValue);
+ if (attributeStatusValue.equals("RESOLVED")) {
+ attribute.getMetaData().putValue(TaskAttribute.META_ASSOCIATED_ATTRIBUTE_ID,
+ BugzillaRestTaskSchema.getDefault().RESOLUTION.getKey());
+ }
+
TaskOperation.applyTo(attribute, attributeStatusValue, attributeStatusValue);
// set as default
TaskOperation.applyTo(operationAttribute, attributeStatusValue, attributeStatusValue);
@@ -425,8 +431,15 @@ public class BugzillaRestConfiguration implements Serializable {
}
attribute = bugReport.getRoot().createAttribute(TaskAttribute.PREFIX_OPERATION + "duplicate");
TaskOperation.applyTo(attribute, "duplicate", "Mark as Duplicate");
- TaskAttribute attrResolvedInput = attribute.getTaskData().getRoot().createAttribute("dup_id");
+ TaskAttribute attrResolvedInput = attribute.getTaskData()
+ .getRoot()
+ .getAttribute(BugzillaRestTaskSchema.getDefault().DUPE_OF.getKey());
+ if (attrResolvedInput == null) {
+ attrResolvedInput = attribute.getTaskData()
+ .getRoot()
+ .createAttribute(BugzillaRestTaskSchema.getDefault().DUPE_OF.getKey());
+ }
attrResolvedInput.getMetaData().setType(TaskAttribute.TYPE_TASK_DEPENDENCY);
- attribute.getMetaData().putValue(TaskAttribute.META_ASSOCIATED_ATTRIBUTE_ID, "dup_id");
+ attribute.getMetaData().putValue(TaskAttribute.META_ASSOCIATED_ATTRIBUTE_ID, attrResolvedInput.getId());
}
} \ No newline at end of file
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPutUpdateTask.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPutUpdateTask.java
new file mode 100644
index 000000000..ee919ff39
--- /dev/null
+++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPutUpdateTask.java
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.bugzilla.rest.core;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.entity.StringEntity;
+import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.LoginToken;
+import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.PutUpdateResult;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.mylyn.tasks.core.data.TaskData;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.TypeAdapter;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+public class BugzillaRestPutUpdateTask extends BugzillaRestAuthenticatedPutRequest<PutUpdateResult> {
+ private final TaskData taskData;
+
+ class OldAttributes {
+ private final Set<TaskAttribute> oldAttributes;
+
+ public OldAttributes(Set<TaskAttribute> oldAttributes) {
+ super();
+ this.oldAttributes = oldAttributes;
+ }
+
+ }
+
+ OldAttributes oldAttributes;
+
+ ImmutableList<String> legalUpdateAttributes = new ImmutableList.Builder<String>()
+ .add(BugzillaRestTaskSchema.getDefault().PRODUCT.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().COMPONENT.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().SUMMARY.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().VERSION.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().DESCRIPTION.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().OS.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().PLATFORM.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().PRIORITY.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().SEVERITY.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().ALIAS.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().ASSIGNED_TO.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().QA_CONTACT.getKey())
+ .add(TaskAttribute.OPERATION)
+ .add(BugzillaRestTaskSchema.getDefault().TARGET_MILESTONE.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().NEW_COMMENT.getKey())
+ .add("resolutionInput") //$NON-NLS-1$
+ .add(BugzillaRestTaskSchema.getDefault().RESOLUTION.getKey())
+ .add(BugzillaRestTaskSchema.getDefault().DUPE_OF.getKey())
+ .build();
+
+ class TaskAttributeTypeAdapter extends TypeAdapter<OldAttributes> {
+ LoginToken token;
+
+ public TaskAttributeTypeAdapter(LoginToken token) {
+ super();
+ this.token = token;
+ }
+
+ private final Function<String, String> function = new Function<String, String>() {
+
+ @Override
+ public String apply(String input) {
+ return BugzillaRestGsonUtil.convertString2GSonString(input);
+ }
+ };
+
+ @Override
+ public void write(JsonWriter out, OldAttributes oldValues) throws IOException {
+ out.beginObject();
+ out.name("Bugzilla_token").value(token.getToken()); //$NON-NLS-1$
+ for (TaskAttribute element : oldValues.oldAttributes) {
+ TaskAttribute taskAttribute = taskData.getRoot().getAttribute(element.getId());
+ String id = taskAttribute.getId();
+ String value = BugzillaRestGsonUtil.convertString2GSonString(taskAttribute.getValue());
+ if ((legalUpdateAttributes.contains(id) || id.startsWith("cf_")) && value != null) { //$NON-NLS-1$
+ id = BugzillaRestTaskSchema.getFieldNameFromAttributeName(id);
+ if (id.equals("status")) { //$NON-NLS-1$
+ if (value != null && value.equals(TaskAttribute.PREFIX_OPERATION + "default")) { //$NON-NLS-1$
+ continue;
+ }
+ if (value.equals("duplicate")) { //$NON-NLS-1$
+ TaskAttribute res = element.getParentAttribute()
+ .getAttribute(BugzillaRestTaskSchema.getDefault().RESOLUTION.getKey());
+ if (!oldAttributes.oldAttributes.contains(res)) {
+ out.name("resolution").value("DUPLICATE"); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ TaskAttribute res1 = taskData.getRoot()
+ .getAttribute(BugzillaRestTaskSchema.getDefault().RESOLUTION.getKey());
+ res1.setValue("DUPLICATE"); //$NON-NLS-1$
+ }
+ value = "RESOLVED"; //$NON-NLS-1$
+ }
+ }
+ if (taskAttribute.getMetaData().getType() != null
+ && taskAttribute.getMetaData().getType().equals(TaskAttribute.TYPE_MULTI_SELECT)) {
+ Iterable<String> taskIdsTemp = Iterables.transform(taskAttribute.getValues(), function);
+ Joiner joiner = Joiner.on(",").skipNulls(); //$NON-NLS-1$
+ value = joiner.join(taskIdsTemp);
+ }
+ if (id.equals(BugzillaRestTaskSchema.getDefault().NEW_COMMENT.getKey())) {
+ out.name("comment").beginObject(); //$NON-NLS-1$
+ out.name("body").value(value); //$NON-NLS-1$
+ out.endObject();
+ continue;
+ }
+ out.name(id).value(value);
+ if (id.equals("description")) { //$NON-NLS-1$
+ TaskAttribute descriptionpri = taskAttribute
+ .getAttribute(BugzillaRestTaskSchema.getDefault().COMMENT_ISPRIVATE.getKey());
+ Boolean descriptionprivalue = (descriptionpri != null)
+ ? (descriptionpri.getValue().equals("1")) //$NON-NLS-1$
+ : false;
+ out.name("comment_is_private").value(Boolean.toString(descriptionprivalue)); //$NON-NLS-1$
+ }
+ }
+ }
+ out.endObject();
+ }
+
+ @Override
+ public OldAttributes read(JsonReader in) throws IOException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ }
+
+ public BugzillaRestPutUpdateTask(BugzillaRestHttpClient client, TaskData taskData,
+ Set<TaskAttribute> oldAttributes) {
+ super(client);
+ this.taskData = taskData;
+ this.oldAttributes = new OldAttributes(oldAttributes);
+ }
+
+ @Override
+ protected String getUrlSuffix() {
+ return "/bug/" + taskData.getTaskId(); //$NON-NLS-1$
+ }
+
+ List<NameValuePair> requestParameters;
+
+ @Override
+ protected HttpRequestBase createHttpRequestBase() {
+ String bugUrl = getUrlSuffix();
+ LoginToken token = ((BugzillaRestHttpClient) getClient()).getLoginToken();
+
+ HttpPut request = new HttpPut(baseUrl() + bugUrl);
+ request.setHeader(CONTENT_TYPE, APPLICATION_JSON);
+ request.setHeader(ACCEPT, APPLICATION_JSON);
+
+ try {
+ Gson gson = new GsonBuilder().registerTypeAdapter(OldAttributes.class, new TaskAttributeTypeAdapter(token))
+ .create();
+ StringEntity requestEntity = new StringEntity(gson.toJson(oldAttributes));
+ request.setEntity(requestEntity);
+ } catch (UnsupportedEncodingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return request;
+ }
+
+ public static String convert(String str) {
+ str = str.replace("\"", "\\\"").replace("\n", "\\\n"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
+ StringBuffer ostr = new StringBuffer();
+ for (int i = 0; i < str.length(); i++) {
+ char ch = str.charAt(i);
+ if ((ch >= 0x0020) && (ch <= 0x007e)) {
+ ostr.append(ch);
+ } else {
+ ostr.append("\\u"); //$NON-NLS-1$
+ String hex = Integer.toHexString(str.charAt(i) & 0xFFFF);
+ for (int j = 0; j < 4 - hex.length(); j++) {
+ ostr.append("0"); //$NON-NLS-1$
+ }
+ ostr.append(hex.toLowerCase());
+ }
+ }
+ return (new String(ostr));
+ }
+
+ @Override
+ protected PutUpdateResult parseFromJson(InputStreamReader in) {
+ TypeToken<PutUpdateResult> type = new TypeToken<PutUpdateResult>() {
+ };
+ return new Gson().fromJson(in, type.getType());
+ }
+
+} \ No newline at end of file
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskDataHandler.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskDataHandler.java
index 9454dc7d0..f25f0e81f 100644
--- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskDataHandler.java
+++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskDataHandler.java
@@ -47,7 +47,7 @@ public class BugzillaRestTaskDataHandler extends AbstractTaskDataHandler {
BugzillaRestClient client = connector.getClient(repository);
try {
IOperationMonitor progress = OperationUtil.convert(monitor, "post taskdata", 3);
- return client.postTaskData(taskData, progress);
+ return client.postTaskData(taskData, oldAttributes, progress);
} catch (BugzillaRestException e) {
throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, 2,
"Error post taskdata.\n\n" + e.getMessage(), e));
@@ -119,5 +119,4 @@ public class BugzillaRestTaskDataHandler extends AbstractTaskDataHandler {
monitor.done();
}
}
-
}
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskSchema.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskSchema.java
index 977611289..dd8241c60 100644
--- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskSchema.java
+++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskSchema.java
@@ -35,6 +35,24 @@ public class BugzillaRestTaskSchema extends AbstractTaskSchema {
.put("op_sys", getDefault().OS.getKey())
.put("resolution", getDefault().RESOLUTION.getKey())
.put("version", getDefault().VERSION.getKey())
+ .put("dup_id", getDefault().DUPE_OF.getKey())
+ .build();
+
+ private static ImmutableMap<String, String> attribute2FieldMapper = new ImmutableMap.Builder()
+ .put(getDefault().SUMMARY.getKey(), "summary")
+ .put(getDefault().DESCRIPTION.getKey(), "description")
+ .put(getDefault().OPERATION.getKey(), "status")
+ .put(getDefault().PRODUCT.getKey(), "product")
+ .put(getDefault().COMPONENT.getKey(), "component")
+ .put(getDefault().CC.getKey(), "cc")
+ .put(getDefault().SEVERITY.getKey(), "severity")
+ .put(getDefault().PRIORITY.getKey(), "priority")
+ .put(getDefault().ASSIGNED_TO.getKey(), "assigned_to")
+ .put(getDefault().OS.getKey(), "op_sys")
+ .put(getDefault().VERSION.getKey(), "version")
+ .put(getDefault().RESOLUTION.getKey(), "resolution")
+ .put(getDefault().getDefault().DUPE_OF.getKey(), "dup_id")
+ .put("resolutionInput", "resolution")
.build();
public static String getAttributeNameFromFieldName(String fieldName) {
@@ -45,6 +63,14 @@ public class BugzillaRestTaskSchema extends AbstractTaskSchema {
return result;
}
+ public static String getFieldNameFromAttributeName(String attributeName) {
+ String result = attribute2FieldMapper.get(attributeName);
+ if (result == null) {
+ result = attributeName;
+ }
+ return result;
+ }
+
public static BugzillaRestTaskSchema getDefault() {
return instance;
}
@@ -96,12 +122,14 @@ public class BugzillaRestTaskSchema extends AbstractTaskSchema {
public final Field TARGET_MILESTONE = createField("target_milestone", "Target milestone",
TaskAttribute.TYPE_SINGLE_SELECT, null, PRODUCT.getKey(), Flag.ATTRIBUTE, Flag.REQUIRED);
- public final Field RESOLUTION = inheritFrom(parent.RESOLUTION).create();
+ public final Field RESOLUTION = inheritFrom(parent.RESOLUTION).removeFlags(Flag.READ_ONLY).create();
public final Field OPERATION = createField(TaskAttribute.OPERATION, "Operation", TaskAttribute.TYPE_OPERATION);
public final Field NEW_COMMENT = inheritFrom(parent.NEW_COMMENT).create();
+ public final Field DUPE_OF = createField("dupe_of", "Dup", TaskAttribute.META_ASSOCIATED_ATTRIBUTE_ID);
+
@Override
public void initialize(TaskData taskData) {
for (Field field : getFields()) {
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/response/data/PutUpdateEntry.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/response/data/PutUpdateEntry.java
new file mode 100644
index 000000000..0c730d170
--- /dev/null
+++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/response/data/PutUpdateEntry.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.bugzilla.rest.core.response.data;
+
+public class PutUpdateEntry {
+ private String last_change_time;
+
+ private String id;
+
+ private String[] alias;
+
+ public PutUpdateEntry() {
+ }
+
+ public String getLast_change_time() {
+ return last_change_time;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String[] getAlias() {
+ return alias;
+ }
+
+}
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/response/data/PutUpdateResult.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/response/data/PutUpdateResult.java
new file mode 100644
index 000000000..f98c4b49e
--- /dev/null
+++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/response/data/PutUpdateResult.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.bugzilla.rest.core.response.data;
+
+public class PutUpdateResult {
+ private PutUpdateEntry[] bugs;
+
+ public PutUpdateEntry[] getBugs() {
+ return bugs;
+ }
+
+ public PutUpdateResult() {
+ }
+
+}

Back to the top