Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormkersten2007-06-05 01:20:37 +0000
committermkersten2007-06-05 01:20:37 +0000
commit77b03f518715908344326384e6f585a84cf3d243 (patch)
tree7ffaa26a88bca40928cfa1bf8791dd7f4ecae50a /org.eclipse.mylyn.trac.core
parent8a2bb7d31f69655928880ac393b1d39cdd3aac84 (diff)
downloadorg.eclipse.mylyn.tasks-77b03f518715908344326384e6f585a84cf3d243.tar.gz
org.eclipse.mylyn.tasks-77b03f518715908344326384e6f585a84cf3d243.tar.xz
org.eclipse.mylyn.tasks-77b03f518715908344326384e6f585a84cf3d243.zip
NEW - bug 186070: [api] make IAttachmentHandler API stream-based
https://bugs.eclipse.org/bugs/show_bug.cgi?id=186070
Diffstat (limited to 'org.eclipse.mylyn.trac.core')
-rw-r--r--org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/ITracClient.java9
-rw-r--r--org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracAttachmentHandler.java91
-rw-r--r--org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracWebClient.java75
-rw-r--r--org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracXmlRpcClient.java42
4 files changed, 119 insertions, 98 deletions
diff --git a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/ITracClient.java b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/ITracClient.java
index e38132eac..95c24a454 100644
--- a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/ITracClient.java
+++ b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/ITracClient.java
@@ -11,6 +11,7 @@
package org.eclipse.mylar.internal.trac.core;
+import java.io.InputStream;
import java.net.Proxy;
import java.util.Date;
import java.util.List;
@@ -18,12 +19,12 @@ import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.mylar.internal.trac.core.model.TracComponent;
-import org.eclipse.mylar.internal.trac.core.model.TracTicketField;
import org.eclipse.mylar.internal.trac.core.model.TracMilestone;
import org.eclipse.mylar.internal.trac.core.model.TracPriority;
import org.eclipse.mylar.internal.trac.core.model.TracSearch;
import org.eclipse.mylar.internal.trac.core.model.TracSeverity;
import org.eclipse.mylar.internal.trac.core.model.TracTicket;
+import org.eclipse.mylar.internal.trac.core.model.TracTicketField;
import org.eclipse.mylar.internal.trac.core.model.TracTicketResolution;
import org.eclipse.mylar.internal.trac.core.model.TracTicketStatus;
import org.eclipse.mylar.internal.trac.core.model.TracTicketType;
@@ -91,6 +92,8 @@ public interface ITracClient {
public static final String MILESTONE_URL = "/milestone/";
public static final String BROWSER_URL = "/browser/";
+
+ public static final String ATTACHMENT_URL = "/attachment/ticket/";
/**
* Gets ticket with <code>id</code> from repository.
@@ -164,9 +167,9 @@ public interface ITracClient {
TracVersion[] getVersions();
- byte[] getAttachmentData(int ticketId, String filename) throws TracException;
+ InputStream getAttachmentData(int ticketId, String filename) throws TracException;
- void putAttachmentData(int ticketId, String name, String description, byte[] data) throws TracException;
+ void putAttachmentData(int ticketId, String name, String description, InputStream source) throws TracException;
void deleteAttachment(int ticketId, String filename) throws TracException;
diff --git a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracAttachmentHandler.java b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracAttachmentHandler.java
index 8d2153f3d..04300fe93 100644
--- a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracAttachmentHandler.java
+++ b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracAttachmentHandler.java
@@ -11,20 +11,16 @@
package org.eclipse.mylar.internal.trac.core;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.mylar.internal.trac.core.model.TracTicket;
+import org.eclipse.mylar.tasks.core.AbstractAttachmentHandler;
import org.eclipse.mylar.tasks.core.AbstractRepositoryTask;
-import org.eclipse.mylar.tasks.core.IAttachmentHandler;
import org.eclipse.mylar.tasks.core.IMylarStatusConstants;
+import org.eclipse.mylar.tasks.core.ITaskAttachment;
import org.eclipse.mylar.tasks.core.RepositoryAttachment;
import org.eclipse.mylar.tasks.core.RepositoryStatus;
import org.eclipse.mylar.tasks.core.RepositoryTaskAttribute;
@@ -33,7 +29,7 @@ import org.eclipse.mylar.tasks.core.TaskRepository;
/**
* @author Steffen Pingel
*/
-public class TracAttachmentHandler implements IAttachmentHandler {
+public class TracAttachmentHandler extends AbstractAttachmentHandler {
private TracRepositoryConnector connector;
@@ -41,59 +37,47 @@ public class TracAttachmentHandler implements IAttachmentHandler {
this.connector = connector;
}
- public void downloadAttachment(TaskRepository repository, RepositoryAttachment attachment, File file, IProgressMonitor monitor)
- throws CoreException {
- byte[] data = getAttachmentData(repository, attachment);
- try {
- writeData(file, data);
- } catch (IOException e) {
- throw new CoreException(TracCorePlugin.toStatus(e));
+ public InputStream getAttachmentAsStream(TaskRepository repository, RepositoryAttachment attachment,
+ IProgressMonitor monitor) throws CoreException {
+ String filename = attachment.getAttributeValue(RepositoryTaskAttribute.ATTACHMENT_FILENAME);
+ if (filename == null) {
+ throw new CoreException(new RepositoryStatus(repository.getUrl(), IStatus.ERROR, TracCorePlugin.PLUGIN_ID,
+ IMylarStatusConstants.REPOSITORY_ERROR, "Attachment download from " + repository.getUrl()
+ + " failed, missing attachment filename."));
}
- }
- private void writeData(File file, byte[] data) throws IOException {
- OutputStream out = new FileOutputStream(file);
try {
- out.write(data);
- } finally {
- out.close();
+ ITracClient client = connector.getClientManager().getRepository(repository);
+ int id = Integer.parseInt(attachment.getTaskId());
+ return client.getAttachmentData(id, filename);
+ } catch (Exception e) {
+ throw new CoreException(TracCorePlugin.toStatus(e));
}
}
- public void uploadAttachment(TaskRepository repository, AbstractRepositoryTask task, String comment,
- String description, File file, String contentType, boolean isPatch, IProgressMonitor monitor) throws CoreException {
+ public void uploadAttachment(TaskRepository repository, AbstractRepositoryTask task, ITaskAttachment attachment,
+ String comment, IProgressMonitor monitor) throws CoreException {
if (!TracRepositoryConnector.hasAttachmentSupport(repository, task)) {
throw new CoreException(new RepositoryStatus(repository.getUrl(), IStatus.INFO, TracCorePlugin.PLUGIN_ID,
IMylarStatusConstants.REPOSITORY_ERROR,
"Attachments are not supported by this repository access type"));
}
+ monitor.beginTask("Uploading attachment", IProgressMonitor.UNKNOWN);
try {
- ITracClient client = connector.getClientManager().getRepository(repository);
- int id = Integer.parseInt(task.getTaskId());
- byte[] data = readData(file);
- client.putAttachmentData(id, file.getName(), description, data);
- if (comment != null && comment.length() > 0) {
- TracTicket ticket = new TracTicket(id);
- client.updateTicket(ticket, comment);
+ try {
+ ITracClient client = connector.getClientManager().getRepository(repository);
+ int id = Integer.parseInt(task.getTaskId());
+ client.putAttachmentData(id, attachment.getFilename(), attachment.getDescription(), attachment.createInputStream());
+ if (comment != null && comment.length() > 0) {
+ TracTicket ticket = new TracTicket(id);
+ client.updateTicket(ticket, comment);
+ }
+ } catch (Exception e) {
+ throw new CoreException(TracCorePlugin.toStatus(e));
}
- } catch (Exception e) {
- throw new CoreException(TracCorePlugin.toStatus(e));
- }
- }
-
- private byte[] readData(File file) throws IOException {
- if (file.length() > Integer.MAX_VALUE) {
- throw new IOException("Can not upload files larger than " + Integer.MAX_VALUE + " bytes");
- }
-
- InputStream in = new FileInputStream(file);
- try {
- byte[] data = new byte[(int) file.length()];
- in.read(data, 0, (int) file.length());
- return data;
} finally {
- in.close();
+ monitor.done();
}
}
@@ -119,21 +103,4 @@ public class TracAttachmentHandler implements IAttachmentHandler {
throw new UnsupportedOperationException();
}
- public byte[] getAttachmentData(TaskRepository repository, RepositoryAttachment attachment) throws CoreException {
- String filename = attachment.getAttributeValue(RepositoryTaskAttribute.ATTACHMENT_FILENAME);
- if (filename == null) {
- throw new CoreException(new RepositoryStatus(repository.getUrl(), IStatus.ERROR, TracCorePlugin.PLUGIN_ID,
- IMylarStatusConstants.REPOSITORY_ERROR, "Attachment download from " + repository.getUrl()
- + " failed, missing attachment filename."));
- }
-
- try {
- ITracClient client = connector.getClientManager().getRepository(repository);
- int id = Integer.parseInt(attachment.getTaskId());
- return client.getAttachmentData(id, filename);
- } catch (Exception e) {
- throw new CoreException(TracCorePlugin.toStatus(e));
- }
- }
-
}
diff --git a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracWebClient.java b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracWebClient.java
index 283a499fb..9fb49c573 100644
--- a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracWebClient.java
+++ b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracWebClient.java
@@ -13,6 +13,7 @@ package org.eclipse.mylar.internal.trac.core;
import java.io.BufferedReader;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.io.StringReader;
@@ -145,13 +146,14 @@ public class TracWebClient extends AbstractTracClient {
// the expected return code is a redirect, anything else is suspicious
if (code == HttpURLConnection.HTTP_OK) {
- // try form-based authentication via AccountManagerPlugin as a fall-back
+ // try form-based authentication via AccountManagerPlugin as a
+ // fall-back
authenticateAccountManager(httpClient);
}
-
+
validateAuthenticationState(httpClient);
-
- // success since no exception was thrown
+
+ // success since no exception was thrown
authenticated = true;
}
@@ -320,7 +322,7 @@ public class TracWebClient extends AbstractTracClient {
boolean inFooter = false;
boolean valid = false;
String version = null;
-
+
HtmlStreamTokenizer tokenizer = new HtmlStreamTokenizer(reader, null);
for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
if (token.getType() == Token.TAG) {
@@ -328,7 +330,7 @@ public class TracWebClient extends AbstractTracClient {
if (tag.getTagType() == HtmlTag.Type.DIV) {
String id = tag.getAttribute("id");
inFooter = !tag.isEndTag() && "footer".equals(id);
- } else if (tag.getTagType() == HtmlTag.Type.STRONG && inFooter) {
+ } else if (tag.getTagType() == HtmlTag.Type.STRONG && inFooter) {
version = getText(tokenizer);
} else if (tag.getTagType() == HtmlTag.Type.A) {
String id = tag.getAttribute("id");
@@ -340,9 +342,10 @@ public class TracWebClient extends AbstractTracClient {
}
if (version != null && !(version.startsWith("Trac 0.9") || version.startsWith("Trac 0.10"))) {
- throw new TracException("The Trac version " + version + " is unsupported. Please use version 0.9.x or 0.10.x.");
+ throw new TracException("The Trac version " + version
+ + " is unsupported. Please use version 0.9.x or 0.10.x.");
}
-
+
if (!valid) {
throw new TracException("Not a valid Trac repository");
}
@@ -379,7 +382,7 @@ public class TracWebClient extends AbstractTracClient {
}
}
}
-
+
addResolutionAndStatus();
} catch (IOException e) {
throw new TracException(e);
@@ -390,10 +393,13 @@ public class TracWebClient extends AbstractTracClient {
}
}
- enum AttributeState { INIT, IN_LIST, IN_ATTRIBUTE_KEY, IN_ATTRIBUTE_VALUE, IN_ATTRIBUTE_VALUE_LIST };
-
- /**
- * Parses the JavaScript code from the query page to extract repository configuration.
+ enum AttributeState {
+ INIT, IN_LIST, IN_ATTRIBUTE_KEY, IN_ATTRIBUTE_VALUE, IN_ATTRIBUTE_VALUE_LIST
+ };
+
+ /**
+ * Parses the JavaScript code from the query page to extract repository
+ * configuration.
*/
private void parseAttributes(String text) throws IOException {
StreamTokenizer t = new StreamTokenizer(new StringReader(text));
@@ -401,7 +407,7 @@ public class TracWebClient extends AbstractTracClient {
AttributeFactory attributeFactory = null;
String attributeType = null;
-
+
AttributeState state = AttributeState.INIT;
int tokenType;
while ((tokenType = t.nextToken()) != StreamTokenizer.TT_EOF) {
@@ -413,56 +419,57 @@ public class TracWebClient extends AbstractTracClient {
attributeFactory = new AttributeFactory() {
public void addAttribute(String value) {
data.components.add(new TracComponent(value));
- }
+ }
};
} else if ("milestone".equals(t.sval)) {
data.milestones = new ArrayList<TracMilestone>();
attributeFactory = new AttributeFactory() {
public void addAttribute(String value) {
data.milestones.add(new TracMilestone(value));
- }
+ }
};
} else if ("priority".equals(t.sval)) {
data.priorities = new ArrayList<TracPriority>();
attributeFactory = new AttributeFactory() {
public void addAttribute(String value) {
data.priorities.add(new TracPriority(value, data.priorities.size() + 1));
- }
+ }
};
} else if ("resolution".equals(t.sval)) {
data.ticketResolutions = new ArrayList<TracTicketResolution>();
attributeFactory = new AttributeFactory() {
public void addAttribute(String value) {
- data.ticketResolutions.add(new TracTicketResolution(value, data.ticketResolutions.size() + 1));
- }
+ data.ticketResolutions.add(new TracTicketResolution(value, data.ticketResolutions
+ .size() + 1));
+ }
};
} else if ("severity".equals(t.sval)) {
data.severities = new ArrayList<TracSeverity>();
attributeFactory = new AttributeFactory() {
public void addAttribute(String value) {
data.severities.add(new TracSeverity(value, data.severities.size() + 1));
- }
+ }
};
} else if ("status".equals(t.sval)) {
data.ticketStatus = new ArrayList<TracTicketStatus>();
attributeFactory = new AttributeFactory() {
public void addAttribute(String value) {
data.ticketStatus.add(new TracTicketStatus(value, data.ticketStatus.size() + 1));
- }
+ }
};
} else if ("type".equals(t.sval)) {
data.ticketTypes = new ArrayList<TracTicketType>();
attributeFactory = new AttributeFactory() {
public void addAttribute(String value) {
data.ticketTypes.add(new TracTicketType(value, data.ticketTypes.size() + 1));
- }
+ }
};
} else if ("version".equals(t.sval)) {
data.versions = new ArrayList<TracVersion>();
attributeFactory = new AttributeFactory() {
public void addAttribute(String value) {
data.versions.add(new TracVersion(value));
- }
+ }
};
} else {
attributeFactory = null;
@@ -515,7 +522,7 @@ public class TracWebClient extends AbstractTracClient {
} else {
throw new IOException("Error parsing attributes: unexpected token '}'");
}
- break;
+ break;
}
}
}
@@ -654,18 +661,26 @@ public class TracWebClient extends AbstractTracClient {
return "";
}
- public byte[] getAttachmentData(int id, String filename) throws TracException {
- throw new TracException("Unsupported operation");
+ public InputStream getAttachmentData(int id, String filename) throws TracException {
+ GetMethod method = connect(repositoryUrl + ITracClient.ATTACHMENT_URL + id + "/" + filename + "?format=raw");
+ try {
+ // the receiver is responsible for closing the stream which will
+ // release the connection
+ return method.getResponseBodyAsStream();
+ } catch (IOException e) {
+ method.releaseConnection();
+ throw new TracException(e);
+ }
}
- public void putAttachmentData(int id, String name, String description, byte[] data) throws TracException {
+ public void putAttachmentData(int id, String name, String description, InputStream in) throws TracException {
throw new TracException("Unsupported operation");
}
public void deleteAttachment(int ticketId, String filename) throws TracException {
throw new TracException("Unsupported operation");
}
-
+
public int createTicket(TracTicket ticket) throws TracException {
throw new TracException("Unsupported operation");
}
@@ -679,9 +694,9 @@ public class TracWebClient extends AbstractTracClient {
}
private interface AttributeFactory {
-
+
void addAttribute(String value);
-
+
}
}
diff --git a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracXmlRpcClient.java b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracXmlRpcClient.java
index ffee25ded..48c9c59dd 100644
--- a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracXmlRpcClient.java
+++ b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/TracXmlRpcClient.java
@@ -1,6 +1,9 @@
package org.eclipse.mylar.internal.trac.core;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
@@ -528,14 +531,47 @@ public class TracXmlRpcClient extends AbstractTracClient {
return attributes;
}
- public byte[] getAttachmentData(int ticketId, String filename) throws TracException {
- return (byte[]) call("ticket.getAttachment", ticketId, filename);
+ public InputStream getAttachmentData(int ticketId, String filename) throws TracException {
+ byte[] data = (byte[]) call("ticket.getAttachment", ticketId, filename);
+ return new ByteArrayInputStream(data);
}
- public void putAttachmentData(int ticketId, String filename, String description, byte[] data) throws TracException {
+ public void putAttachmentData(int ticketId, String filename, String description, InputStream in) throws TracException {
+ byte[] data;
+ try {
+ data = readData(in, new NullProgressMonitor());
+ } catch (IOException e) {
+ throw new TracException(e);
+ }
call("ticket.putAttachment", ticketId, filename, description, data, false);
}
+ private byte[] readData(InputStream in, IProgressMonitor monitor) throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ byte[] buffer = new byte[512];
+ while (true) {
+ int count = in.read(buffer);
+ if (count == -1) {
+ return out.toByteArray();
+ }
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ out.write(buffer, 0, count);
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ }
+ } finally {
+ try {
+ in.close();
+ } catch (IOException e) {
+ MylarStatusHandler.fail(e, "Error closing attachment stream", false);
+ }
+ }
+ }
+
public void deleteAttachment(int ticketId, String filename) throws TracException {
call("ticket.deleteAttachment", ticketId, filename);
}

Back to the top