Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasklist/util/TaskListWriter.java')
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasklist/util/TaskListWriter.java544
1 files changed, 544 insertions, 0 deletions
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasklist/util/TaskListWriter.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasklist/util/TaskListWriter.java
new file mode 100644
index 000000000..5a2460d1b
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasklist/util/TaskListWriter.java
@@ -0,0 +1,544 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2006 University Of British Columbia 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:
+ * University Of British Columbia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylar.internal.tasklist.util;
+
+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 java.util.List;
+
+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.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.mylar.internal.core.util.MylarStatusHandler;
+import org.eclipse.mylar.internal.tasklist.TaskExternalizationException;
+import org.eclipse.mylar.provisional.tasklist.AbstractRepositoryQuery;
+import org.eclipse.mylar.provisional.tasklist.DelegatingTaskExternalizer;
+import org.eclipse.mylar.provisional.tasklist.ITask;
+import org.eclipse.mylar.provisional.tasklist.ITaskContainer;
+import org.eclipse.mylar.provisional.tasklist.ITaskListExternalizer;
+import org.eclipse.mylar.provisional.tasklist.MylarTaskListPlugin;
+import org.eclipse.mylar.provisional.tasklist.TaskList;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Mik Kersten
+ * @author Ken Sueda
+ */
+public class TaskListWriter {
+
+ public static final String ATTRIBUTE_VERSION = "Version";
+
+ public static final String ELEMENT_TASK_LIST = "TaskList";
+
+ private static final String VALUE_VERSION = "1.0.1";
+
+ private static final String VALUE_VERSION_1_0_0 = "1.0.0";
+
+ private static final String FILE_SUFFIX_SAVE = "save.xml";
+
+ private List<ITaskListExternalizer> externalizers;
+
+ private DelegatingTaskExternalizer delagatingExternalizer = new DelegatingTaskExternalizer();
+
+ private String readVersion = "";
+
+ private boolean hasCaughtException = false;
+
+ public void setDelegateExternalizers(List<ITaskListExternalizer> externalizers) {
+ this.externalizers = externalizers;
+ this.delagatingExternalizer.setDelegateExternalizers(externalizers);
+ }
+
+ public void writeTaskList(TaskList taskList, File outFile) {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db;
+ Document doc = null;
+
+ try {
+ db = dbf.newDocumentBuilder();
+ doc = db.newDocument();
+ } catch (ParserConfigurationException e) {
+ MylarStatusHandler.log(e, "could not create document");
+ }
+
+ Element root = doc.createElement(ELEMENT_TASK_LIST);
+ root.setAttribute(ATTRIBUTE_VERSION, VALUE_VERSION);
+
+ // create the categories
+ for (ITaskContainer category : taskList.getCategories()) {
+ if (!category.getHandleIdentifier().equals(TaskList.LABEL_ARCHIVE)) {
+ delagatingExternalizer.createCategoryElement(category, doc, root);
+ }
+ }
+
+ for (AbstractRepositoryQuery query : taskList.getQueries()) {
+ Element element = null;
+ for (ITaskListExternalizer externalizer : externalizers) {
+ if (externalizer.canCreateElementFor(query))
+ element = externalizer.createQueryElement(query, doc, root);
+ }
+ if (element == null && delagatingExternalizer.canCreateElementFor(query)) {
+ delagatingExternalizer.createQueryElement(query, doc, root);
+ } else if (element == null) {
+ MylarStatusHandler.log("Did not externalize: " + query, this);
+ }
+ }
+
+ for (ITask task : taskList.getAllTasks()) {
+ createTaskElement(doc, root, task);
+ }
+
+// for (ITask task : taskList.getArchiveTasks()) {
+// createTaskElement(doc, root, task);
+// }
+
+// for (ITask task : taskList.getRootTasks()) {
+// createTaskElement(doc, root, task);
+// }
+ doc.appendChild(root);
+ writeDOMtoFile(doc, outFile);
+ return;
+ }
+
+ private void createTaskElement(Document doc, Element root, ITask task) {
+ try {
+ Element element = null;
+ for (ITaskListExternalizer externalizer : externalizers) {
+ if (externalizer.canCreateElementFor(task)) {
+ element = externalizer.createTaskElement(task, doc, root);
+ break;
+ }
+ }
+ if (element == null && delagatingExternalizer.canCreateElementFor(task)) {
+ delagatingExternalizer.createTaskElement(task, doc, root);
+ } else if (element == null) {
+ MylarStatusHandler.log("Did not externalize: " + task, this);
+ }
+ } catch (Exception e) {
+ MylarStatusHandler.log(e, e.getMessage());
+ }
+ }
+
+ /**
+ * Writes an XML file from a DOM.
+ *
+ * doc - the document to write file - the file to be written to
+ */
+ private void writeDOMtoFile(Document doc, File file) {
+ try {
+ // A file output stream is an output stream for writing data to a
+ // File
+ //
+ OutputStream outputStream = new FileOutputStream(file);
+ writeDOMtoStream(doc, outputStream);
+ outputStream.flush();
+ outputStream.close();
+ } catch (Exception fnfe) {
+ MylarStatusHandler.log(fnfe, "TaskList could not be found");
+ }
+ }
+
+ /**
+ * Writes the provided XML document out to the specified output stream.
+ *
+ * doc - the document to be written outputStream - the stream to which the
+ * document is to be written
+ */
+ private void writeDOMtoStream(Document doc, OutputStream outputStream) {
+ // Prepare the DOM document for writing
+ // DOMSource - Acts as a holder for a transformation Source tree in the
+ // form of a Document Object Model (DOM) tree
+ //
+ Source source = new DOMSource(doc);
+
+ // StreamResult - Acts as an holder for a XML transformation result
+ // Prepare the output stream
+ //
+ Result result = new StreamResult(outputStream);
+
+ // An instance of this class can be obtained with the
+ // TransformerFactory.newTransformer method. This instance may
+ // then be used to process XML from a variety of sources and write
+ // the transformation output to a variety of sinks
+ //
+
+ Transformer xformer = null;
+ try {
+ xformer = TransformerFactory.newInstance().newTransformer();
+ // Transform the XML Source to a Result
+ //
+ xformer.transform(source, result);
+ } catch (TransformerConfigurationException e) {
+ e.printStackTrace();
+ } catch (TransformerFactoryConfigurationError e) {
+ e.printStackTrace();
+ } catch (TransformerException e1) {
+ e1.printStackTrace();
+ }
+ }
+
+ /**
+ * TODO: fix this old mess
+ */
+ public void readTaskList(TaskList taskList, File inFile) {
+ hasCaughtException = false;
+ try {
+ if (!inFile.exists())
+ return;
+ Document doc = openAsDOM(inFile);
+ if (doc == null) {
+ handleException(inFile, null, new TaskExternalizationException("TaskList was not well formed XML"));
+ return;
+ }
+ Element root = doc.getDocumentElement();
+ readVersion = root.getAttribute(ATTRIBUTE_VERSION);
+
+ if (readVersion.equals(VALUE_VERSION_1_0_0)) {
+ MylarStatusHandler.log("version: " + readVersion + " not supported", this);
+ } else {
+ NodeList list = root.getChildNodes();
+
+ // NOTE: order is important, first read the categories
+ for (int i = 0; i < list.getLength(); i++) {
+ Node child = list.item(i);
+ try {
+ if (child.getNodeName().endsWith(DelegatingTaskExternalizer.KEY_CATEGORY)) {
+ delagatingExternalizer.readCategory(child, taskList);
+ }
+ } catch (Exception e) {
+ handleException(inFile, child, e);
+ }
+ }
+
+ // then read the tasks
+ for (int i = 0; i < list.getLength(); i++) {
+ Node child = list.item(i);
+ try {
+ boolean wasRead = false;
+ if (!child.getNodeName().endsWith(DelegatingTaskExternalizer.KEY_CATEGORY)
+ && !child.getNodeName().endsWith(DelegatingTaskExternalizer.KEY_QUERY)) {
+ for (ITaskListExternalizer externalizer : externalizers) {
+ if (!wasRead && externalizer.canReadTask(child)) {
+ externalizer.readTask(child, taskList, null, null);
+ wasRead = true;
+ }
+ }
+ if (!wasRead && delagatingExternalizer.canReadTask(child)) {
+ delagatingExternalizer.readTask(child, taskList, null, null);
+ }
+ }
+ } catch (Exception e) {
+ handleException(inFile, child, e);
+ }
+ }
+
+ // then query hits hits, which get corresponded to tasks
+ for (int i = 0; i < list.getLength(); i++) {
+ Node child = list.item(i);
+ try {
+ if (child.getNodeName().endsWith(DelegatingTaskExternalizer.KEY_QUERY)) {
+ for (ITaskListExternalizer externalizer : externalizers) {
+ if (externalizer.canReadQuery(child)) {
+ AbstractRepositoryQuery query = externalizer.readQuery(child, taskList);
+ if (query != null) {
+ taskList.internalAddQuery(query);
+ }
+ break;
+ }
+ }
+ }
+ } catch (Exception e) {
+ handleException(inFile, child, e);
+ }
+ }
+ }
+ } catch (Exception e) {
+ handleException(inFile, null, e);
+ }
+ if (hasCaughtException) {
+ // if exception was caught, write out the new task file, so that it
+ // doesn't happen again.
+ // this is OK, since the original (corrupt) tasklist is saved.
+ // TODO: The problem with this is that if the orignal tasklist has
+ // tasks and bug reports, but a
+ // task is corrupted, the new tasklist that is written will not
+ // include the bug reports (since the
+ // bugzilla externalizer is not loaded. So there is a potentila that
+ // we can lose bug reports.
+ writeTaskList(taskList, inFile);
+ }
+ }
+
+ /**
+ * Opens the specified XML file and parses it into a DOM Document.
+ *
+ * Filename - the name of the file to open Return - the Document built from
+ * the XML file Throws - XMLException if the file cannot be parsed as XML -
+ * IOException if the file cannot be opened
+ */
+ private Document openAsDOM(File inputFile) throws IOException {
+
+ // A factory API that enables applications to obtain a parser
+ // that produces DOM object trees from XML documents
+ //
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+
+ // Using DocumentBuilder, obtain a Document from XML file.
+ //
+ DocumentBuilder builder = null;
+ Document document = null;
+ try {
+ // create new instance of DocumentBuilder
+ //
+ builder = factory.newDocumentBuilder();
+ } catch (ParserConfigurationException pce) {
+ inputFile.renameTo(new File(inputFile.getName() + FILE_SUFFIX_SAVE));
+ MylarStatusHandler.log(pce, "Failed to load XML file");
+ }
+ try {
+ // Parse the content of the given file as an XML document
+ // and return a new DOM Document object. Also throws IOException
+ document = builder.parse(inputFile);
+ } catch (SAXException se) {
+ File backup = new File(MylarTaskListPlugin.getDefault().getTaskListSaveManager().getBackupFilePath());
+ String message = "Restoring the tasklist failed. Would you like to attempt to restore from the backup?\n\nTasklist XML File location: "
+ + inputFile.getAbsolutePath()
+ + "\n\nBackup tasklist XML file location: "
+ + backup.getAbsolutePath();
+ if (backup.exists() && MessageDialog.openQuestion(null, "Restore From Backup", message)) {
+ try {
+ document = builder.parse(backup);
+ MylarTaskListPlugin.getDefault().getTaskListSaveManager().reverseBackup();
+ } catch (SAXException s) {
+ inputFile.renameTo(new File(inputFile.getName() + FILE_SUFFIX_SAVE));
+ MylarStatusHandler.log(s, "Failed to recover from backup restore");
+ }
+ }
+ }
+ return document;
+ }
+
+ private void handleException(File inFile, Node child, Exception e) {
+ hasCaughtException = true;
+ String name = inFile.getAbsolutePath();
+ name = name.substring(0, name.lastIndexOf('.')) + "-save1.xml";
+ File save = new File(name);
+ int i = 2;
+ while (save.exists()) {
+ name = name.substring(0, name.lastIndexOf('.') - 1) + i + ".xml";
+ save = new File(name);
+ i++;
+ }
+ if (!copy(inFile, save)) {
+ inFile.renameTo(new File(name));
+ }
+ if (child == null) {
+ MylarStatusHandler.log(e, "Could not read task list");
+ } else {
+ MylarStatusHandler.log(e, "Tasks may have been lost from " + child.getNodeName());
+ }
+ }
+
+ private boolean copy(File src, File dst) {
+ try {
+ InputStream in = new FileInputStream(src);
+ OutputStream out = new FileOutputStream(dst);
+
+ // Transfer bytes from in to out
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = in.read(buf)) > 0) {
+ out.write(buf, 0, len);
+ }
+ in.close();
+ out.close();
+ return true;
+ } catch (IOException ioe) {
+ return false;
+ }
+ }
+
+// private Document openAsDOM(String input) throws IOException {
+//
+// // A factory API that enables applications to obtain a parser
+// // that produces DOM object trees from XML documents
+// //
+// DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+//
+// // Using DocumentBuilder, obtain a Document from XML file.
+// //
+// DocumentBuilder builder = null;
+// Document document = null;
+// try {
+// // create new instance of DocumentBuilder
+// //
+// builder = factory.newDocumentBuilder();
+// } catch (ParserConfigurationException pce) {
+// MylarStatusHandler.log(pce, "Failed to load XML file");
+// }
+// try {
+// // Parse the content of the given file as an XML document
+// // and return a new DOM Document object. Also throws IOException
+// StringReader s = new StringReader(input);
+// InputSource in = new InputSource(s);
+// document = builder.parse(in);
+// } catch (SAXException se) {
+// MylarStatusHandler.log(se, "Failed to parse XML file");
+// }
+// return document;
+// }
+
+// public void readTaskList(TaskList taskList, String input) {
+// try {
+// Document doc = openAsDOM(input);
+// if (doc == null) {
+// return;
+// }
+// Element root = doc.getDocumentElement();
+// readVersion = root.getAttribute(ATTRIBUTE_VERSION);
+//
+// if (readVersion.equals(VALUE_VERSION_1_0_0)) {
+// MylarStatusHandler.log("version: " + readVersion + " not supported", this);
+// } else {
+// NodeList list = root.getChildNodes();
+// for (int i = 0; i < list.getLength(); i++) {
+// Node child = list.item(i);
+// boolean wasRead = false;
+// try {
+// if (child.getNodeName().endsWith(DelegatingTaskExternalizer.KEY_CATEGORY)) {
+//// for (ITaskListExternalizer externalizer : externalizers) {
+//// if (externalizer.canReadCategory(child)) {
+//// externalizer.readCategory(child, taskList);
+//// wasRead = true;
+//// break;
+//// }
+//// }
+// if (delagatingExternalizer.canReadCategory(child)) {
+// delagatingExternalizer.readCategory(child, taskList);
+// }
+// } else {
+// for (ITaskListExternalizer externalizer : externalizers) {
+// if (externalizer.canReadTask(child)) {
+// ITask newTask = externalizer.readTask(child, taskList, null, null);
+//// externalizer.getRepositoryClient().addTaskToArchive(newTask);
+// taskList.addTaskToArchive(newTask);
+//
+// taskList.internalAddRootTask(newTask);
+//
+// wasRead = true;
+// break;
+// }
+// }
+// if (!wasRead && delagatingExternalizer.canReadTask(child)) {
+// taskList.internalAddRootTask(delagatingExternalizer.readTask(child, taskList, null, null));
+// }
+// }
+// } catch (Exception e) {
+// MylarStatusHandler.log(e, "can't read xml string");
+// }
+// }
+// }
+// } catch (Exception e) {
+// MylarStatusHandler.log(e, "can't read xml string");
+// }
+// }
+
+// public String getTaskListXml(TaskList tlist) {
+// // TODO make this and writeTaskList use the same base code
+// DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+// DocumentBuilder db;
+// Document doc = null;
+//
+// try {
+// db = dbf.newDocumentBuilder();
+// doc = db.newDocument();
+// } catch (ParserConfigurationException e) {
+// MylarStatusHandler.log(e, "could not create document");
+// e.printStackTrace();
+// }
+//
+// Element root = doc.createElement(ELEMENT_TASK_LIST);
+// root.setAttribute(ATTRIBUTE_VERSION, VALUE_VERSION);
+//
+// for (ITaskListExternalizer externalizer : externalizers) {
+// externalizer.createRegistry(doc, root);
+// }
+//
+// for (ITaskContainer category : tlist.getCategories()) {
+// Element element = null;
+// for (ITaskListExternalizer externalizer : externalizers) {
+// if (externalizer.canCreateElementFor(category))
+// element = externalizer.createCategoryElement(category, doc, root);
+// }
+// if (element == null && delagatingExternalizer.canCreateElementFor(category)) {
+// delagatingExternalizer.createCategoryElement(category, doc, root);
+// } else if (element == null) {
+// MylarStatusHandler.log("Did not externalize: " + category, this);
+// }
+// }
+// for (ITask task : tlist.getRootTasks()) {
+// try {
+// Element element = null;
+// for (ITaskListExternalizer externalizer : externalizers) {
+// if (externalizer.canCreateElementFor(task))
+// element = externalizer.createTaskElement(task, doc, root);
+// }
+// if (element == null && delagatingExternalizer.canCreateElementFor(task)) {
+// delagatingExternalizer.createTaskElement(task, doc, root);
+// } else if (element == null) {
+// MylarStatusHandler.log("Did not externalize: " + task, this);
+// }
+// } catch (Exception e) {
+// MylarStatusHandler.log(e, e.getMessage());
+// }
+// }
+// doc.appendChild(root);
+// StringWriter sw = new StringWriter();
+//
+// Source source = new DOMSource(doc);
+//
+// Result result = new StreamResult(sw);
+//
+// Transformer xformer = null;
+// try {
+// xformer = TransformerFactory.newInstance().newTransformer();
+// // Transform the XML Source to a Result
+// //
+// xformer.transform(source, result);
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+// return sw.toString();
+// }
+
+ public void setDelegatingExternalizer(DelegatingTaskExternalizer delagatingExternalizer) {
+ this.delagatingExternalizer = delagatingExternalizer;
+ }
+}

Back to the top