Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaxsun McCarthy Huggan2016-05-16 19:44:26 -0400
committerJaxsun McCarthy Huggan2016-05-17 12:52:22 -0400
commit7f3f9dc21e4b3ff6afd680c835277f08da7c124d (patch)
treec2f8a2e6cdfa6db32bb9546e338ac6783804bdd7 /org.eclipse.mylyn.tasks.core
parent8d958cc06f60633412164e2d8fddc3ec907ae413 (diff)
downloadorg.eclipse.mylyn.tasks-7f3f9dc21e4b3ff6afd680c835277f08da7c124d.tar.gz
org.eclipse.mylyn.tasks-7f3f9dc21e4b3ff6afd680c835277f08da7c124d.tar.xz
org.eclipse.mylyn.tasks-7f3f9dc21e4b3ff6afd680c835277f08da7c124d.zip
493037: write task list using SAX instead of DOM
Change-Id: Ie0e4c7ff38dbe78951849f0cc880cfa21b7a32eb Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=493037 Signed-off-by: Jaxsun McCarthy Huggan <jaxsun.mccarthy@tasktop.com>
Diffstat (limited to 'org.eclipse.mylyn.tasks.core')
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/AttributesWrapper.java34
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/ContentHandlerWrapper.java42
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxCategoryWriter.java43
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxOrphanWriter.java55
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxQueryWriter.java58
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxTaskListElementWriter.java84
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxTaskListWriter.java194
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxTaskWriter.java127
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/TaskListExternalizer.java115
9 files changed, 642 insertions, 110 deletions
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/AttributesWrapper.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/AttributesWrapper.java
new file mode 100644
index 000000000..082974ad0
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/AttributesWrapper.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Tasktop Technologies 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:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.externalization;
+
+import org.xml.sax.helpers.AttributesImpl;
+
+public class AttributesWrapper {
+
+ private final AttributesImpl attributes;
+
+ public AttributesWrapper() {
+ this.attributes = new AttributesImpl();
+ }
+
+ public void addAttribute(String key, String value) {
+ if (key != null && value != null) {
+ attributes.addAttribute("", key, key, "", value); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ public AttributesImpl getAttributes() {
+ return attributes;
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/ContentHandlerWrapper.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/ContentHandlerWrapper.java
new file mode 100644
index 000000000..5b35c0b66
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/ContentHandlerWrapper.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Tasktop Technologies 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:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.externalization;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+public class ContentHandlerWrapper {
+
+ private final ContentHandler handler;
+
+ public ContentHandlerWrapper(ContentHandler handler) {
+ this.handler = handler;
+ }
+
+ public void startElement(String elementName, AttributesWrapper attributes) throws SAXException {
+ handler.startElement("", elementName, elementName, attributes.getAttributes()); //$NON-NLS-1$
+ }
+
+ public void endElement(String elementName) throws SAXException {
+ handler.endElement("", elementName, elementName);//$NON-NLS-1$
+ }
+
+ public void characters(String value) throws SAXException {
+ char[] chars = value.toCharArray();
+ handler.characters(chars, 0, chars.length);
+ }
+
+ public ContentHandler getHandler() {
+ return handler;
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxCategoryWriter.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxCategoryWriter.java
new file mode 100644
index 000000000..322971b05
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxCategoryWriter.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Tasktop Technologies 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:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.externalization;
+
+import org.eclipse.mylyn.internal.tasks.core.AbstractTaskCategory;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.xml.sax.SAXException;
+
+public class SaxCategoryWriter extends SaxTaskListElementWriter<AbstractTaskCategory> {
+
+ public SaxCategoryWriter(ContentHandlerWrapper handler) {
+ super(handler);
+ }
+
+ @Override
+ public void writeElement(AbstractTaskCategory category) throws SAXException {
+ AttributesWrapper attributes = new AttributesWrapper();
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_HANDLE, category.getHandleIdentifier());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_NAME, category.getSummary());
+ handler.startElement(TaskListExternalizationConstants.NODE_CATEGORY, attributes);
+ for (ITask task : category.getChildren()) {
+ createTaskReference(task);
+ }
+ handler.endElement(TaskListExternalizationConstants.NODE_CATEGORY);
+ }
+
+ private void createTaskReference(ITask task) throws SAXException {
+ AttributesWrapper attributes = new AttributesWrapper();
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_HANDLE, task.getHandleIdentifier());
+ handler.startElement(TaskListExternalizationConstants.NODE_TASK_REFERENCE, attributes);
+ handler.endElement(TaskListExternalizationConstants.NODE_TASK_REFERENCE);
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxOrphanWriter.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxOrphanWriter.java
new file mode 100644
index 000000000..d3ba93d81
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxOrphanWriter.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Tasktop Technologies 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:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.externalization;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.SAXException;
+
+public class SaxOrphanWriter {
+
+ private final ContentHandlerWrapper handler;
+
+ public SaxOrphanWriter(ContentHandlerWrapper handler) {
+ this.handler = handler;
+ }
+
+ public void writeOrphans(NodeList orphanNodes) throws SAXException {
+ for (int i = 0; i < orphanNodes.getLength(); i++) {
+ Node orphanNode = orphanNodes.item(i);
+ if (orphanNode instanceof Element) {
+ Element orphanElement = (Element) orphanNode;
+ AttributesWrapper saxAttributes = getAttributes(orphanElement);
+ handler.startElement(orphanElement.getNodeName(), saxAttributes);
+ writeOrphans(orphanElement.getChildNodes());
+ handler.endElement(orphanElement.getNodeName());
+ } else if (orphanNode instanceof Text) {
+ Text orphanText = (Text) orphanNode;
+ handler.characters(orphanText.getData());
+ }
+ }
+ }
+
+ private AttributesWrapper getAttributes(Element orphanElement) {
+ AttributesWrapper saxAttributes = new AttributesWrapper();
+ NamedNodeMap domAttributes = orphanElement.getAttributes();
+ for (int i = 0; i < domAttributes.getLength(); i++) {
+ Node attribute = domAttributes.item(i);
+ saxAttributes.addAttribute(attribute.getNodeName(), attribute.getNodeValue());
+ }
+ return saxAttributes;
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxQueryWriter.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxQueryWriter.java
new file mode 100644
index 000000000..edbf068c2
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxQueryWriter.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Tasktop Technologies 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:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.externalization;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
+import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.xml.sax.SAXException;
+
+public class SaxQueryWriter extends SaxTaskListElementWriter<RepositoryQuery> {
+
+ public SaxQueryWriter(ContentHandlerWrapper handler) {
+ super(handler);
+ }
+
+ @Override
+ public void writeElement(RepositoryQuery query) throws SAXException {
+ if (query.getClass() == RepositoryQuery.class) {
+ AttributesWrapper attributes = new AttributesWrapper();
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_HANDLE, query.getHandleIdentifier());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_CONNECTOR_KIND, query.getConnectorKind());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_NAME, query.getSummary());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_QUERY_STRING, query.getUrl());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_REPOSITORY_URL, query.getRepositoryUrl());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_LAST_REFRESH,
+ query.getLastSynchronizedTimeStamp());
+ handler.startElement(TaskListExternalizationConstants.NODE_QUERY, attributes);
+ writeAttributes(query);
+ for (ITask task : query.getChildren()) {
+ writeQueryHit(task);
+ }
+ handler.endElement(TaskListExternalizationConstants.NODE_QUERY);
+ } else {
+ addError(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN,
+ String.format("Unable to externalize query \"%s\" as it is of an unsupported type %s", //$NON-NLS-1$
+ query.getHandleIdentifier(), query.getClass())));
+ }
+ }
+
+ private void writeQueryHit(ITask task) throws SAXException {
+ AttributesWrapper attributes = new AttributesWrapper();
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_HANDLE, task.getHandleIdentifier());
+ handler.startElement(TaskListExternalizationConstants.NODE_QUERY_HIT, attributes);
+ handler.endElement(TaskListExternalizationConstants.NODE_QUERY_HIT);
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxTaskListElementWriter.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxTaskListElementWriter.java
new file mode 100644
index 000000000..9845358aa
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxTaskListElementWriter.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Tasktop Technologies 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:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.externalization;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
+import org.eclipse.mylyn.tasks.core.IAttributeContainer;
+import org.eclipse.mylyn.tasks.core.IRepositoryElement;
+import org.xml.sax.SAXException;
+
+public abstract class SaxTaskListElementWriter<T extends IRepositoryElement> {
+
+ protected final ContentHandlerWrapper handler;
+
+ private final MultiStatus errors;
+
+ public SaxTaskListElementWriter(ContentHandlerWrapper handler) {
+ this.handler = handler;
+ this.errors = new MultiStatus(ITasksCoreConstants.ID_PLUGIN, IStatus.OK, null, null);
+ }
+
+ public abstract void writeElement(T element) throws SAXException;
+
+ protected void writeAttributes(IAttributeContainer container) throws SAXException {
+ Map<String, String> attributes = container.getAttributes();
+ for (Map.Entry<String, String> entry : attributes.entrySet()) {
+ AttributesWrapper xmlAttributes = new AttributesWrapper();
+ xmlAttributes.addAttribute(TaskListExternalizationConstants.KEY_KEY, entry.getKey());
+
+ handler.startElement(TaskListExternalizationConstants.NODE_ATTRIBUTE, xmlAttributes);
+ handler.characters(entry.getValue());
+ handler.endElement(TaskListExternalizationConstants.NODE_ATTRIBUTE);
+ }
+ }
+
+ @SuppressWarnings({ "restriction" })
+ protected String stripControlCharacters(String text) {
+ if (text == null) {
+ return ""; //$NON-NLS-1$
+ }
+ return org.eclipse.mylyn.internal.commons.core.XmlStringConverter.cleanXmlString(text);
+ }
+
+ protected String formatExternDate(Date date) {
+ if (date == null) {
+ return ""; //$NON-NLS-1$
+ }
+ SimpleDateFormat format = new SimpleDateFormat(TaskListExternalizationConstants.OUT_DATE_FORMAT,
+ Locale.ENGLISH);
+ return format.format(date);
+ }
+
+ protected String formatExternCalendar(Calendar date) {
+ if (date == null) {
+ return ""; //$NON-NLS-1$
+ }
+ return formatExternDate(date.getTime());
+ }
+
+ protected void addError(IStatus status) {
+ errors.add(status);
+ }
+
+ public IStatus getErrors() {
+ return errors;
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxTaskListWriter.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxTaskListWriter.java
new file mode 100644
index 000000000..439f6fe2d
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxTaskListWriter.java
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Tasktop Technologies 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:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.externalization;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collection;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.commons.core.StatusHandler;
+import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
+import org.eclipse.mylyn.internal.tasks.core.ITransferList;
+import org.eclipse.mylyn.internal.tasks.core.SaxRepositoriesWriter;
+import org.eclipse.mylyn.tasks.core.IRepositoryElement;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+
+/**
+ * Adapted from {@link SaxRepositoriesWriter}
+ */
+public class SaxTaskListWriter {
+
+ private static final String ATTRIBUTE_VERSION = "Version"; //$NON-NLS-1$
+
+ // Mylyn 3.0
+ private static final String VALUE_VERSION = "2.0"; //$NON-NLS-1$
+
+ private OutputStream outputStream;
+
+ public void setOutputStream(OutputStream outputStream) {
+ this.outputStream = outputStream;
+ }
+
+ public void writeTaskListToStream(ITransferList taskList, Document orphans) throws IOException {
+ if (outputStream == null) {
+ throw new IOException("OutputStream not set"); //$NON-NLS-1$
+ }
+
+ try {
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.transform(new SAXSource(new TaskListWriter(), new TaskListInputSource(taskList, orphans)),
+ new StreamResult(outputStream));
+ } catch (TransformerException e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Could not write task list", e)); //$NON-NLS-1$
+ throw new IOException(e.getMessage(), e);
+ }
+
+ }
+
+ private static class TaskListInputSource extends InputSource {
+ private final ITransferList taskList;
+
+ private final Document orphans;
+
+ public TaskListInputSource(ITransferList taskList, Document orphans) {
+ this.taskList = taskList;
+ this.orphans = orphans;
+ }
+
+ public ITransferList getTaskList() {
+ return this.taskList;
+ }
+
+ public Document getOrphans() {
+ return orphans;
+ }
+
+ }
+
+ private static class TaskListWriter implements XMLReader {
+
+ private ContentHandlerWrapper handler;
+
+ private ErrorHandler errorHandler;
+
+ public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
+ return false;
+ }
+
+ public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
+ }
+
+ public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
+ return null;
+ }
+
+ public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
+ }
+
+ public void setEntityResolver(EntityResolver resolver) {
+ }
+
+ public EntityResolver getEntityResolver() {
+ return null;
+ }
+
+ public void setDTDHandler(DTDHandler handler) {
+ }
+
+ public DTDHandler getDTDHandler() {
+ return null;
+ }
+
+ public void setContentHandler(ContentHandler handler) {
+ this.handler = new ContentHandlerWrapper(handler);
+ }
+
+ public ContentHandler getContentHandler() {
+ return handler.getHandler();
+ }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ this.errorHandler = handler;
+ }
+
+ public ErrorHandler getErrorHandler() {
+ return errorHandler;
+ }
+
+ public void parse(InputSource input) throws IOException, SAXException {
+ if (!(input instanceof TaskListInputSource)) {
+ throw new SAXException("Can only parse writable input sources"); //$NON-NLS-1$
+ }
+ TaskListInputSource taskListInputSource = (TaskListInputSource) input;
+
+ handler.getHandler().startDocument();
+ writeTaskList(taskListInputSource.getTaskList(), taskListInputSource.getOrphans());
+ handler.getHandler().endDocument();
+ }
+
+ private void writeTaskList(ITransferList taskList, Document orphanDocument) throws IOException, SAXException {
+ AttributesWrapper attributes = new AttributesWrapper();
+ attributes.addAttribute(ATTRIBUTE_VERSION, VALUE_VERSION);
+ handler.startElement(TaskListExternalizationConstants.NODE_TASK_LIST, attributes);
+
+ writeTaskListElements(new SaxTaskWriter(handler), taskList.getAllTasks());
+ writeTaskListElements(new SaxCategoryWriter(handler), taskList.getCategories());
+ writeTaskListElements(new SaxQueryWriter(handler), taskList.getQueries());
+
+ writeOrphans(orphanDocument);
+
+ handler.endElement(TaskListExternalizationConstants.NODE_TASK_LIST);
+ }
+
+ private <T extends IRepositoryElement> void writeTaskListElements(SaxTaskListElementWriter<T> writer,
+ Collection<T> elements) throws SAXException {
+ for (T element : elements) {
+ writer.writeElement(element);
+ }
+ if (!writer.getErrors().isOK()) {
+ StatusHandler.log(writer.getErrors());
+ }
+ }
+
+ private void writeOrphans(Document orphanDocument) throws SAXException {
+ if (orphanDocument != null) {
+ SaxOrphanWriter writer = new SaxOrphanWriter(handler);
+ NodeList orphanNodes = orphanDocument.getChildNodes();
+ if (orphanNodes.getLength() == 1) {
+ writer.writeOrphans(orphanNodes.item(0).getChildNodes());
+ }
+ }
+ }
+
+ public void parse(String systemId) throws IOException, SAXException {
+ throw new SAXException("Can only parse writable input sources"); //$NON-NLS-1$
+ }
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxTaskWriter.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxTaskWriter.java
new file mode 100644
index 000000000..299891987
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/SaxTaskWriter.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Tasktop Technologies 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:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.externalization;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
+import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
+import org.eclipse.mylyn.internal.tasks.core.LocalTask;
+import org.eclipse.mylyn.internal.tasks.core.TaskTask;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.mylyn.tasks.core.ITask.SynchronizationState;
+import org.xml.sax.SAXException;
+
+public class SaxTaskWriter extends SaxTaskListElementWriter<AbstractTask> {
+
+ public SaxTaskWriter(ContentHandlerWrapper handler) {
+ super(handler);
+ }
+
+ @Override
+ public void writeElement(AbstractTask task) throws SAXException {
+ if (task.getClass() == TaskTask.class || task instanceof LocalTask) {
+ handler.startElement(TaskListExternalizationConstants.NODE_TASK, createTaskElementAttributes(task));
+ writeAttributes(task);
+ for (ITask subTask : task.getChildren()) {
+ createTaskReference(subTask);
+ }
+ handler.endElement(TaskListExternalizationConstants.NODE_TASK);
+ } else {
+ addError(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN,
+ String.format("Unable to externalize task \"%s\" as it is of an unsupported type %s", //$NON-NLS-1$
+ task.getTaskId(), task.getClass())));
+ }
+ }
+
+ private AttributesWrapper createTaskElementAttributes(AbstractTask task) {
+ AttributesWrapper attributes = new AttributesWrapper();
+
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_CONNECTOR_KIND, task.getConnectorKind());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_REPOSITORY_URL, task.getRepositoryUrl());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_TASK_ID, task.getTaskId());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_KEY, task.getTaskKey());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_HANDLE, task.getHandleIdentifier());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_LABEL, stripControlCharacters(task.getSummary()));
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_PRIORITY, task.getPriority());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_KIND, task.getTaskKind());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_ISSUEURL, task.getUrl());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_NOTES, stripControlCharacters(task.getNotes()));
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_TIME_ESTIMATED,
+ Integer.toString(task.getEstimatedTimeHours()));
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_DATE_END,
+ formatExternDate(task.getCompletionDate()));
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_DATE_CREATION,
+ formatExternDate(task.getCreationDate()));
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_DATE_MODIFICATION,
+ formatExternDate(task.getModificationDate()));
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_DATE_DUE, formatExternDate(task.getDueDate()));
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_OWNER, task.getOwner());
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_OWNER_ID, task.getOwnerId());
+
+ if (task.isActive()) {
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_ACTIVE,
+ TaskListExternalizationConstants.VAL_TRUE);
+ } else {
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_ACTIVE,
+ TaskListExternalizationConstants.VAL_FALSE);
+ }
+
+ if (task.getScheduledForDate() != null) {
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_DATE_SCHEDULED_START,
+ formatExternCalendar(task.getScheduledForDate().getStartDate()));
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_DATE_SCHEDULED_END,
+ formatExternCalendar(task.getScheduledForDate().getEndDate()));
+ }
+
+ if (task.isReminded()) {
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_REMINDED,
+ TaskListExternalizationConstants.VAL_TRUE);
+ } else {
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_REMINDED,
+ TaskListExternalizationConstants.VAL_FALSE);
+ }
+
+ if (task.isMarkReadPending()) {
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_MARK_READ_PENDING,
+ TaskListExternalizationConstants.VAL_TRUE);
+ } else {
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_MARK_READ_PENDING,
+ TaskListExternalizationConstants.VAL_FALSE);
+ }
+
+ if (task.isNotified()) {
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_NOTIFIED_INCOMING,
+ TaskListExternalizationConstants.VAL_TRUE);
+ } else {
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_NOTIFIED_INCOMING,
+ TaskListExternalizationConstants.VAL_FALSE);
+ }
+
+ if (task.getSynchronizationState() != null) {
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_SYNC_STATE,
+ task.getSynchronizationState().name());
+ } else {
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_SYNC_STATE,
+ SynchronizationState.SYNCHRONIZED.name());
+ }
+
+ return attributes;
+ }
+
+ public void createTaskReference(ITask task) throws SAXException {
+ AttributesWrapper attributes = new AttributesWrapper();
+ attributes.addAttribute(TaskListExternalizationConstants.KEY_HANDLE, task.getHandleIdentifier());
+ handler.startElement(TaskListExternalizationConstants.NODE_SUB_TASK, attributes);
+ handler.endElement(TaskListExternalizationConstants.NODE_SUB_TASK);
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/TaskListExternalizer.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/TaskListExternalizer.java
index 3ef523cf7..536c432d8 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/TaskListExternalizer.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/externalization/TaskListExternalizer.java
@@ -18,40 +18,21 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
-import org.eclipse.mylyn.commons.core.StatusHandler;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTaskCategory;
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
import org.eclipse.mylyn.internal.tasks.core.ITransferList;
import org.eclipse.mylyn.internal.tasks.core.RepositoryModel;
-import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery;
import org.eclipse.mylyn.internal.tasks.core.XmlReaderUtil;
import org.eclipse.mylyn.tasks.core.AbstractTaskListMigrator;
import org.eclipse.mylyn.tasks.core.IRepositoryManager;
import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
@@ -64,19 +45,6 @@ public class TaskListExternalizer {
private static final String ERROR_TASKLIST_READ = "Failed to load Task List"; //$NON-NLS-1$
- private static final String TRANSFORM_PROPERTY_VERSION = "version"; //$NON-NLS-1$
-
- // May 2007: There was a bug when reading in 1.1
- // Result was an infinite loop within the parser
- private static final String XML_VERSION = "1.0"; //$NON-NLS-1$
-
- public static final String ATTRIBUTE_VERSION = "Version"; //$NON-NLS-1$
-
- public static final String ELEMENT_TASK_LIST = "TaskList"; //$NON-NLS-1$
-
- // Mylyn 3.0
- private static final String VALUE_VERSION = "2.0"; //$NON-NLS-1$
-
private final DelegatingTaskExternalizer delegatingExternalizer;
private final RepositoryModel repositoryModel;
@@ -96,24 +64,19 @@ public class TaskListExternalizer {
}
public void writeTaskList(ITransferList taskList, File outFile) throws CoreException {
- try {
- FileOutputStream outStream = new FileOutputStream(outFile);
- try {
- Document doc = createTaskListDocument(taskList);
-
- ZipOutputStream zipOutStream = new ZipOutputStream(outStream);
-
+ try (FileOutputStream outStream = new FileOutputStream(outFile)) {
+ try (ZipOutputStream zipOutStream = new ZipOutputStream(outStream)) {
ZipEntry zipEntry = new ZipEntry(ITasksCoreConstants.OLD_TASK_LIST_FILE);
zipOutStream.putNextEntry(zipEntry);
zipOutStream.setMethod(ZipOutputStream.DEFLATED);
- writeDocument(doc, zipOutStream);
+ SaxTaskListWriter writer = new SaxTaskListWriter();
+ writer.setOutputStream(zipOutStream);
+ writer.writeTaskListToStream(taskList, orphanDocument);
zipOutStream.flush();
zipOutStream.closeEntry();
zipOutStream.finish();
- } finally {
- outStream.close();
}
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Saving Task List failed", //$NON-NLS-1$
@@ -121,74 +84,6 @@ public class TaskListExternalizer {
}
}
- private Document createTaskListDocument(ITransferList taskList) throws CoreException {
- Document doc = createDocument();
-
- delegatingExternalizer.clearErrorStatus();
-
- Element root = doc.createElement(ELEMENT_TASK_LIST);
- root.setAttribute(ATTRIBUTE_VERSION, VALUE_VERSION);
- doc.appendChild(root);
-
- // create task nodes...
- for (AbstractTask task : taskList.getAllTasks()) {
- delegatingExternalizer.createTaskElement(task, doc, root);
- }
-
- // create the category nodes...
- for (AbstractTaskCategory category : taskList.getCategories()) {
- delegatingExternalizer.createCategoryElement(category, doc, root);
- }
-
- // create query nodes...
- for (RepositoryQuery query : taskList.getQueries()) {
- delegatingExternalizer.createQueryElement(query, doc, root);
- }
-
- // Persist orphaned tasks...
- if (orphanDocument != null) {
- NodeList orphans = orphanDocument.getDocumentElement().getChildNodes();
- for (int i = 0; i < orphans.getLength(); i++) {
- Node node = orphans.item(i);
- Node tempNode = doc.importNode(node, true);
- if (tempNode != null) {
- root.appendChild(tempNode);
- }
- }
- }
-
- if (delegatingExternalizer.getErrorStatus() != null) {
- StatusHandler.log(delegatingExternalizer.getErrorStatus());
- }
-
- return doc;
- }
-
- private void writeDocument(Document doc, OutputStream outputStream) throws CoreException {
- Source source = new DOMSource(doc);
- Result result = new StreamResult(outputStream);
- try {
- Transformer xformer = TransformerFactory.newInstance().newTransformer();
- xformer.setOutputProperty(TRANSFORM_PROPERTY_VERSION, XML_VERSION);
- xformer.transform(source, result);
- } catch (TransformerException e) {
- throw new CoreException(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Failed write task list", //$NON-NLS-1$
- e));
- }
- }
-
- private Document createDocument() throws CoreException {
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- DocumentBuilder db;
- try {
- db = dbf.newDocumentBuilder();
- return db.newDocument();
- } catch (ParserConfigurationException e) {
- throw new CoreException(
- new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Failed to create document", e)); //$NON-NLS-1$
- }
- }
-
public void readTaskList(ITransferList taskList, File inFile) throws CoreException {
if (!inFile.exists()) {
throw new CoreException(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN,

Back to the top