Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorspingel2011-01-31 17:53:23 -0500
committerspingel2011-01-31 17:53:23 -0500
commita759e7c8f9239349cc12f9ac3fadc6e02a4e847f (patch)
tree805cf92fa43d800a39fcb029169b39a4e2e46fa2
parentf5d135864588587a54d3fd87ca9e84802a1d95f1 (diff)
downloadorg.eclipse.mylyn.tasks-a759e7c8f9239349cc12f9ac3fadc6e02a4e847f.tar.gz
org.eclipse.mylyn.tasks-a759e7c8f9239349cc12f9ac3fadc6e02a4e847f.tar.xz
org.eclipse.mylyn.tasks-a759e7c8f9239349cc12f9ac3fadc6e02a4e847f.zip
NEW - bug 268456: reading of task data fails with fatal error
https://bugs.eclipse.org/bugs/show_bug.cgi?id=268456
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataExternalizer.java107
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataStore.java38
-rw-r--r--org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java4
-rw-r--r--org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/TaskDataStoreTest.java55
-rw-r--r--org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/TaskDataExternalizerTest.java213
-rw-r--r--org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/Xml11InputStreamTest.java88
-rw-r--r--org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/XmlExternalizationTest.java160
7 files changed, 509 insertions, 156 deletions
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataExternalizer.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataExternalizer.java
index 4336296cd..dceb6f2d0 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataExternalizer.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataExternalizer.java
@@ -11,6 +11,8 @@
package org.eclipse.mylyn.internal.tasks.core.data;
+import java.io.EOFException;
+import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -41,6 +43,88 @@ import org.xml.sax.helpers.XMLReaderFactory;
*/
public class TaskDataExternalizer {
+ /**
+ * Replaces the first 38 bytes of a an input stream with an XML 1.1 header.
+ */
+ public static class Xml11InputStream extends FilterInputStream {
+
+ /**
+ * XML 1.1 header.
+ */
+ byte[] header;
+
+ /**
+ * Current position in {@link #header}.
+ */
+ int pointer;
+
+ public Xml11InputStream(InputStream in) throws IOException {
+ super(in);
+ header = new String("<?xml version=\"1.1\" encoding=\"UTF-8\"?>").getBytes("US-ASCII"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Override
+ public synchronized void reset() throws IOException {
+ throw new IOException();
+ }
+
+ @Override
+ public synchronized void mark(int readlimit) {
+ }
+
+ @Override
+ public boolean markSupported() {
+ return false;
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ // fill b with bytes from header until the header has been read
+ if (pointer < header.length) {
+ int read = 0;
+ for (; pointer < header.length && read < len; read++, pointer++) {
+ b[off + read] = header[pointer];
+ readByte();
+ }
+ return read;
+ } else {
+ return super.read(b, off, len);
+ }
+ }
+
+ /**
+ * Advances the underlying stream by a single byte.
+ */
+ private void readByte() throws IOException, EOFException {
+ if (in.read() == -1) {
+ throw new EOFException();
+ }
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (pointer < header.length) {
+ readByte();
+ return header[pointer++];
+ } else {
+ return super.read();
+ }
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ if (pointer < header.length) {
+ // skip at most the number of bytes remaining in the header
+ long skip = Math.min(header.length - pointer, n);
+ pointer += skip;
+ return skip;
+ } else {
+ return super.skip(n);
+ }
+ }
+
+ }
+
private final IRepositoryManager taskRepositoryManager;
public TaskDataExternalizer(IRepositoryManager taskRepositoryManager) {
@@ -90,21 +174,16 @@ public class TaskDataExternalizer {
}
}
- public TaskDataState readState(InputStream in) throws IOException {
- try {
- XMLReader parser = XMLReaderFactory.createXMLReader();
- TaskDataStateReader handler = new TaskDataStateReader(taskRepositoryManager);
- parser.setContentHandler(handler);
- parser.parse(new InputSource(in));
- TaskDataState taskDataState = handler.getTaskDataState();
- if (taskDataState != null) {
- migrate(taskDataState);
- }
- return taskDataState;
- } catch (SAXException e) {
- //e.printStackTrace();
- throw new IOException("Error parsing task data: " + e.getMessage()); //$NON-NLS-1$
+ public TaskDataState readState(InputStream in) throws IOException, SAXException {
+ XMLReader parser = XMLReaderFactory.createXMLReader();
+ TaskDataStateReader handler = new TaskDataStateReader(taskRepositoryManager);
+ parser.setContentHandler(handler);
+ parser.parse(new InputSource(in));
+ TaskDataState taskDataState = handler.getTaskDataState();
+ if (taskDataState != null) {
+ migrate(taskDataState);
}
+ return taskDataState;
}
public void writeState(OutputStream out, ITaskDataWorkingCopy state) throws IOException {
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataStore.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataStore.java
index 9dd1e692b..b08ef73d9 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataStore.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataStore.java
@@ -26,8 +26,10 @@ import org.eclipse.core.runtime.CoreException;
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.data.TaskDataExternalizer.Xml11InputStream;
import org.eclipse.mylyn.tasks.core.IRepositoryManager;
import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.xml.sax.SAXException;
/**
* @author Steffen Pingel
@@ -106,15 +108,41 @@ public class TaskDataStore {
writeState(file, state);
}
+ private TaskDataState readStateInternal(File file, boolean xml11) throws IOException, SAXException {
+ ZipInputStream in = new ZipInputStream(new BufferedInputStream(new FileInputStream(file)));
+ try {
+ in.getNextEntry();
+ // bug 268456: When TaskData that contains C0 control characters is written to disk using XML 1.0 reading it back
+ // in fails with a SAXException. The XML 1.1 standard allows C0 entities but fails if C1 entities. If C0 control
+ // characters are detected while parsing file as XML 1.0 a second attempt is made using XML 1.1. If the file contains
+ // C0 and C1 control characters reading will fail regardless.
+ if (xml11) {
+ return externalizer.readState(new Xml11InputStream(in));
+ } else {
+ return externalizer.readState(in);
+ }
+ } finally {
+ in.close();
+ }
+ }
+
private TaskDataState readState(File file) throws CoreException {
try {
if (file.exists()) {
- ZipInputStream in = new ZipInputStream(new BufferedInputStream(new FileInputStream(file)));
try {
- in.getNextEntry();
- return externalizer.readState(in);
- } finally {
- in.close();
+ try {
+ return readStateInternal(file, false);
+ } catch (SAXException e) {
+ // bug 268456: if reading fails, try again using a different XML version
+ if (e.getMessage() != null && e.getMessage().contains("invalid XML character")) { //$NON-NLS-1$
+ return readStateInternal(file, true);
+ } else {
+ throw e;
+ }
+ }
+
+ } catch (SAXException e) {
+ throw new IOException("Error parsing task data: " + e.getMessage()); //$NON-NLS-1$
}
}
return null;
diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java
index 537190d3c..3f00d3187 100644
--- a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java
+++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java
@@ -18,6 +18,8 @@ import org.eclipse.mylyn.tasks.tests.core.FileTaskAttachmentSourceTest;
import org.eclipse.mylyn.tasks.tests.core.ITasksCoreConstantsTest;
import org.eclipse.mylyn.tasks.tests.core.TaskListUnmatchedContainerTest;
import org.eclipse.mylyn.tasks.tests.core.TaskRepositoryLocationTest;
+import org.eclipse.mylyn.tasks.tests.data.TaskDataExternalizerTest;
+import org.eclipse.mylyn.tasks.tests.data.Xml11InputStreamTest;
import org.eclipse.mylyn.tasks.tests.ui.ContextPerspectiveManagerTest;
import org.eclipse.mylyn.tasks.tests.ui.RetrieveTitleFromUrlTest;
import org.eclipse.mylyn.tasks.tests.ui.TaskAttachmentPropertyTesterTest;
@@ -106,6 +108,8 @@ public class AllTasksTests {
suite.addTestSuite(TaskAttributeDiffTest.class);
suite.addTestSuite(ServiceMessageManagerTest.class);
suite.addTestSuite(TaskMigratorTest.class);
+ suite.addTestSuite(TaskDataExternalizerTest.class);
+ suite.addTestSuite(Xml11InputStreamTest.class);
// XXX long running tests, put back?
//suite.addTestSuite(QueryExportImportTest.class);
//suite.addTestSuite(BackgroundSaveTest.class);
diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/TaskDataStoreTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/TaskDataStoreTest.java
index fa0e34e52..6e1775883 100644
--- a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/TaskDataStoreTest.java
+++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/TaskDataStoreTest.java
@@ -193,4 +193,59 @@ public class TaskDataStoreTest extends TestCase {
assertData(2);
}
+
+ public void testReadWriteInvalidCharacters() throws Exception {
+ setupData();
+ data.getRoot().createAttribute("attribute").setValue("\u0000");
+
+ File file = File.createTempFile("mylyn", null);
+ file.deleteOnExit();
+ storage.putTaskData(file, state);
+
+ try {
+ TaskDataState state2 = storage.getTaskDataState(file);
+ fail("Expected CoreException, got " + state2);
+ } catch (CoreException expected) {
+ }
+ }
+
+ public void testReadWriteC0Characters() throws Exception {
+ setupData();
+ data.getRoot().createAttribute("attribute").setValue("\u0001\u001F");
+
+ File file = File.createTempFile("mylyn", null);
+ file.deleteOnExit();
+ storage.putTaskData(file, state);
+
+ TaskDataState state2 = storage.getTaskDataState(file);
+ assertEquals(state.getRepositoryData().getRoot().toString(), state2.getRepositoryData().getRoot().toString());
+ }
+
+ public void testReadWriteC1Characters() throws Exception {
+ setupData();
+ data.getRoot().createAttribute("attribute").setValue("\u007F\u0080");
+
+ File file = File.createTempFile("mylyn", null);
+ file.deleteOnExit();
+ storage.putTaskData(file, state);
+
+ TaskDataState state2 = storage.getTaskDataState(file);
+ assertEquals(state.getRepositoryData().getRoot().toString(), state2.getRepositoryData().getRoot().toString());
+ }
+
+ public void testReadWriteC0C1Characters() throws Exception {
+ setupData();
+ data.getRoot().createAttribute("attribute").setValue("\u0001\u001F\u007F\u0080");
+
+ File file = File.createTempFile("mylyn", null);
+ file.deleteOnExit();
+ storage.putTaskData(file, state);
+
+ try {
+ TaskDataState state2 = storage.getTaskDataState(file);
+ fail("Expected CoreException, got " + state2);
+ } catch (CoreException expected) {
+ }
+ }
+
}
diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/TaskDataExternalizerTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/TaskDataExternalizerTest.java
index 875d456bc..4a3f58e0b 100644
--- a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/TaskDataExternalizerTest.java
+++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/TaskDataExternalizerTest.java
@@ -13,105 +13,54 @@ package org.eclipse.mylyn.tasks.tests.data;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.zip.ZipInputStream;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-
-import junit.framework.Assert;
import junit.framework.TestCase;
-import org.eclipse.mylyn.internal.tasks.core.data.ITaskDataConstants;
+import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryManager;
import org.eclipse.mylyn.internal.tasks.core.data.TaskDataExternalizer;
+import org.eclipse.mylyn.internal.tasks.core.data.TaskDataExternalizer.Xml11InputStream;
import org.eclipse.mylyn.internal.tasks.core.data.TaskDataState;
-import org.eclipse.mylyn.tasks.core.data.ITaskDataWorkingCopy;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper;
import org.eclipse.mylyn.tasks.core.data.TaskData;
-import org.eclipse.mylyn.tasks.core.data.TaskMapper;
import org.eclipse.mylyn.tasks.tests.TaskTestUtil;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.AttributesImpl;
-import org.xml.sax.helpers.DefaultHandler;
-import org.xml.sax.helpers.XMLReaderFactory;
+import org.eclipse.mylyn.tasks.tests.connector.MockRepositoryConnector;
+import org.xml.sax.SAXParseException;
/**
* @author Steffen Pingel
*/
public class TaskDataExternalizerTest extends TestCase {
- private class SimpleCharacterReader extends DefaultHandler {
-
- private char ch;
-
- public SimpleCharacterReader() {
- }
-
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException {
- Assert.assertEquals(1, length);
- this.ch = ch[start];
- }
-
- public char getCharacter() {
- return ch;
- }
-
- }
-
- private final class SimpleCharacterWriter {
- private final TransformerHandler handler;
-
- public SimpleCharacterWriter(TransformerHandler handler) {
- this.handler = handler;
- }
-
- public void write(char character) throws SAXException {
- handler.startDocument();
- AttributesImpl atts = new AttributesImpl();
- handler.startElement("", "", ITaskDataConstants.ELEMENT_VALUE, atts); //$NON-NLS-1$ //$NON-NLS-2$
- ///handler.startCDATA();
- handler.characters(new char[] { character }, 0, 1);
- //handler.endCDATA();
- handler.endElement("", "", ITaskDataConstants.ELEMENT_VALUE);
- handler.endDocument();
- }
- }
+ private TaskDataExternalizer externalizer;
- TaskDataExternalizer externalizer;
+ private TaskRepository repository;
@Override
protected void setUp() throws Exception {
- externalizer = new TaskDataExternalizer(null);
-
+ TaskRepositoryManager taskRepositoryManager = new TaskRepositoryManager();
+ taskRepositoryManager.addRepositoryConnector(new MockRepositoryConnector());
+ //taskRepositoryManager.addRepositoryConnector(new BugzillaRepositoryConnector());
+ repository = TaskTestUtil.createMockRepository();
+ taskRepositoryManager.addRepository(repository);
+ externalizer = new TaskDataExternalizer(taskRepositoryManager);
}
- public void testMapFromLegacy() throws Exception {
- File file = TaskTestUtil.getFile("testdata/taskdata-1.0-bug-219897.zip");
- ZipInputStream in = new ZipInputStream(new FileInputStream(file));
- ITaskDataWorkingCopy state;
- try {
- in.getNextEntry();
- state = externalizer.readState(in);
- } finally {
- in.close();
- }
-
- TaskData taskData = state.getRepositoryData();
- @SuppressWarnings("unused")
- TaskMapper taskScheme = new TaskMapper(taskData);
-
- fail("fixme");
+// public void testMapFromLegacy() throws Exception {
+// File file = TaskTestUtil.getFile("testdata/taskdata-1.0-bug-219897.zip");
+// ZipInputStream in = new ZipInputStream(new FileInputStream(file));
+// ITaskDataWorkingCopy state;
+// try {
+// in.getNextEntry();
+// state = externalizer.readState(in);
+// } finally {
+// in.close();
+// }
+//
+// TaskData taskData = state.getRepositoryData();
+// @SuppressWarnings("unused")
+// TaskMapper taskScheme = new TaskMapper(taskData);
+//
// RepositoryTaskData legacyData = TaskDataUtil.toLegacyData(taskData, IdentityAttributeFactory.getInstance());
// assertEquals(taskData.getConnectorKind(), legacyData.getConnectorKind());
// assertEquals(taskData.getRepositoryUrl(), legacyData.getRepositoryUrl());
@@ -126,69 +75,59 @@ public class TaskDataExternalizerTest extends TestCase {
// assertEquals(taskData.getTaskId(), taskData2.getTaskId());
//
// assertEquals(taskData.getRoot().toString(), taskData2.getRoot().toString());
- }
+// }
+//
+// public void testRead() throws Exception {
+// File file = TaskTestUtil.getFile("testdata/taskdata-1.0-bug-219897.zip");
+// ZipInputStream in = new ZipInputStream(new FileInputStream(file));
+// try {
+// in.getNextEntry();
+// @SuppressWarnings("unused")
+// ITaskDataWorkingCopy state = externalizer.readState(in);
+// } finally {
+// in.close();
+// }
+// }
+//
+// public void testReadWrite() throws Exception {
+// File file = TaskTestUtil.getFile("testdata/taskdata-1.0-bug-219897.zip");
+// ZipInputStream in = new ZipInputStream(new FileInputStream(file));
+// ITaskDataWorkingCopy state;
+// try {
+// in.getNextEntry();
+// state = externalizer.readState(in);
+// } finally {
+// in.close();
+// }
+// ByteArrayOutputStream out = new ByteArrayOutputStream();
+// externalizer.writeState(out, state);
+// TaskDataState state2 = externalizer.readState(new ByteArrayInputStream(out.toByteArray()));
+// assertEquals(state.getConnectorKind(), state2.getConnectorKind());
+// assertEquals(state.getRepositoryUrl(), state2.getRepositoryUrl());
+// assertEquals(state.getTaskId(), state2.getTaskId());
+//
+// assertEquals(state.getRepositoryData().getRoot().toString(), state2.getRepositoryData().getRoot().toString());
+// }
- public void testRead() throws Exception {
- File file = TaskTestUtil.getFile("testdata/taskdata-1.0-bug-219897.zip");
- ZipInputStream in = new ZipInputStream(new FileInputStream(file));
- try {
- in.getNextEntry();
- @SuppressWarnings("unused")
- ITaskDataWorkingCopy state = externalizer.readState(in);
- } finally {
- in.close();
- }
- }
+ public void testReadWriteInvalidCharacters() throws Exception {
+ TaskData data = new TaskData(new TaskAttributeMapper(repository), repository.getConnectorKind(),
+ repository.getRepositoryUrl(), "1");
+ data.getRoot().createAttribute("attribute").setValue("\u0001\u001F");
+
+ TaskDataState state = new TaskDataState(repository.getConnectorKind(), repository.getRepositoryUrl(), "1");
+ state.setRepositoryData(data);
- public void testReadWrite() throws Exception {
- File file = TaskTestUtil.getFile("testdata/taskdata-1.0-bug-219897.zip");
- ZipInputStream in = new ZipInputStream(new FileInputStream(file));
- ITaskDataWorkingCopy state;
- try {
- in.getNextEntry();
- state = externalizer.readState(in);
- } finally {
- in.close();
- }
ByteArrayOutputStream out = new ByteArrayOutputStream();
externalizer.writeState(out, state);
- TaskDataState state2 = externalizer.readState(new ByteArrayInputStream(out.toByteArray()));
- assertEquals(state.getConnectorKind(), state2.getConnectorKind());
- assertEquals(state.getRepositoryUrl(), state2.getRepositoryUrl());
- assertEquals(state.getTaskId(), state2.getTaskId());
+ try {
+ externalizer.readState(new ByteArrayInputStream(out.toByteArray()));
+ fail("Expected SAXParseException");
+ } catch (SAXParseException expected) {
+ }
+ TaskDataState state2 = externalizer.readState(new Xml11InputStream(new ByteArrayInputStream(out.toByteArray())));
assertEquals(state.getRepositoryData().getRoot().toString(), state2.getRepositoryData().getRoot().toString());
-
+ assertEquals("\u0001\u001F", state2.getRepositoryData().getRoot().getAttribute("attribute").getValue());
}
- public void testWriteandReadBadCharacter() throws Exception {
- for (int i = 0; i < 0xFFFF; i++) {
- char badChar = (char) i;
-
- StringWriter stringWriter = new StringWriter();
- SAXTransformerFactory transformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance();
- TransformerHandler handler = transformerFactory.newTransformerHandler();
- Transformer serializer = handler.getTransformer();
- serializer.setOutputProperty(OutputKeys.VERSION, "1.0");
- serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
- serializer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
- handler.setResult(new StreamResult(stringWriter));
- SimpleCharacterWriter writer = new SimpleCharacterWriter(handler);
- writer.write(badChar);
-
- XMLReader parser = XMLReaderFactory.createXMLReader();
- SimpleCharacterReader readHandler = new SimpleCharacterReader();
- parser.setEntityResolver(new EntityResolver() {
- public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
- System.out.println(publicId);
- System.out.println(systemId);
- return null;
- }
- });
- parser.setContentHandler(readHandler);
- parser.parse(new InputSource(new StringReader(stringWriter.getBuffer().toString())));
- char character = readHandler.getCharacter();
- assertEquals(badChar, character);
- }
- }
}
diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/Xml11InputStreamTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/Xml11InputStreamTest.java
new file mode 100644
index 000000000..ae8a1be11
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/Xml11InputStreamTest.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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.tasks.tests.data;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.io.InputStreamReader;
+
+import junit.framework.TestCase;
+
+import org.eclipse.mylyn.internal.tasks.core.data.TaskDataExternalizer.Xml11InputStream;
+
+/**
+ * @author Steffen Pingel
+ */
+public class Xml11InputStreamTest extends TestCase {
+
+ public void testShortStream() throws Exception {
+ ByteArrayInputStream source = new ByteArrayInputStream("foo bar".getBytes());
+ Xml11InputStream in = new Xml11InputStream(source);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ try {
+ assertEquals("<?xml version=\"1.1\" encoding=\"UTF-8\"?>", reader.readLine());
+ fail("Expected EOFException");
+ } catch (EOFException expected) {
+ }
+ }
+
+ public void testXml10Stream() throws Exception {
+ ByteArrayInputStream source = new ByteArrayInputStream("<?xml version=\"1.0\" encoding=\"UTF-8\"?>".getBytes());
+ Xml11InputStream in = new Xml11InputStream(source);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ assertEquals("<?xml version=\"1.1\" encoding=\"UTF-8\"?>", reader.readLine());
+ assertEquals(-1, in.read());
+ }
+
+ public void testXml10StreamMultiLines() throws Exception {
+ ByteArrayInputStream source = new ByteArrayInputStream(
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<abc>\n<def>".getBytes());
+ Xml11InputStream in = new Xml11InputStream(source);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
+ assertEquals("<?xml version=\"1.1\" encoding=\"UTF-8\"?>", reader.readLine());
+ assertEquals("<abc>", reader.readLine());
+ assertEquals("<def>", reader.readLine());
+ assertEquals(null, reader.readLine());
+ }
+
+ public void testSkipRead() throws Exception {
+ ByteArrayInputStream source = new ByteArrayInputStream(
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".getBytes());
+ Xml11InputStream in = new Xml11InputStream(source);
+ assertEquals(0, in.skip(0));
+ assertEquals('<', in.read());
+ assertEquals(5, in.skip(5));
+ assertEquals('v', in.read());
+ }
+
+ public void testSkipReadLine() throws Exception {
+ ByteArrayInputStream source = new ByteArrayInputStream(
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".getBytes());
+ Xml11InputStream in = new Xml11InputStream(source);
+ assertEquals(3, in.skip(3));
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
+ assertEquals("ml version=\"1.1\" encoding=\"UTF-8\"?>", reader.readLine());
+ assertEquals(null, reader.readLine());
+ }
+
+ public void testSkipHeader() throws Exception {
+ ByteArrayInputStream source = new ByteArrayInputStream(
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>abc".getBytes());
+ Xml11InputStream in = new Xml11InputStream(source);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
+ assertEquals(38, reader.skip(38));
+ assertEquals("abc", reader.readLine());
+ assertEquals(null, reader.readLine());
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/XmlExternalizationTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/XmlExternalizationTest.java
new file mode 100644
index 000000000..de0cbd45c
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/data/XmlExternalizationTest.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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.tasks.tests.data;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.eclipse.mylyn.internal.tasks.core.data.ITaskDataConstants;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * @author Steffen Pingel
+ * @author Shawn Minto
+ */
+public class XmlExternalizationTest extends TestCase {
+
+ private class SimpleCharacterReader extends DefaultHandler {
+
+ private char ch;
+
+ public SimpleCharacterReader() {
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ //System.err.println(Arrays.toString(ch));
+ Assert.assertEquals(1, length);
+ this.ch = ch[start];
+ }
+
+ public char getCharacter() {
+ return ch;
+ }
+
+ }
+
+ private final class SimpleCharacterWriter {
+ private final TransformerHandler handler;
+
+ public SimpleCharacterWriter(TransformerHandler handler) {
+ this.handler = handler;
+ }
+
+ public void write(char character) throws SAXException {
+ handler.startDocument();
+ AttributesImpl atts = new AttributesImpl();
+ handler.startElement("", "", ITaskDataConstants.ELEMENT_VALUE, atts); //$NON-NLS-1$ //$NON-NLS-2$
+ ///handler.startCDATA();
+ handler.characters(new char[] { character }, 0, 1);
+ //handler.endCDATA();
+ handler.endElement("", "", ITaskDataConstants.ELEMENT_VALUE);
+ handler.endDocument();
+ }
+ }
+
+ public void testWriteandReadBadCharacterXml10() throws Exception {
+ for (int i = 0; i < 0xFFFF; i++) {
+ char badChar = (char) i;
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ SAXTransformerFactory transformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance();
+ TransformerHandler handler = transformerFactory.newTransformerHandler();
+ Transformer serializer = handler.getTransformer();
+ serializer.setOutputProperty(OutputKeys.VERSION, "1.0");
+ serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
+ serializer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+ handler.setResult(new StreamResult(out));
+ SimpleCharacterWriter writer = new SimpleCharacterWriter(handler);
+ writer.write(badChar);
+
+ XMLReader parser = XMLReaderFactory.createXMLReader();
+ parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
+ SimpleCharacterReader readHandler = new SimpleCharacterReader();
+ parser.setErrorHandler(new ErrorHandler() {
+ public void warning(SAXParseException exception) throws SAXException {
+ exception.printStackTrace();
+ }
+
+ public void fatalError(SAXParseException exception) throws SAXException {
+ exception.printStackTrace();
+ }
+
+ public void error(SAXParseException exception) throws SAXException {
+ exception.printStackTrace();
+ }
+ });
+ parser.setContentHandler(readHandler);
+ parser.parse(new InputSource(new ByteArrayInputStream(out.toByteArray())));
+ char character = readHandler.getCharacter();
+ assertEquals(badChar, character);
+ }
+ }
+
+ public void testWriteandReadBadCharacterXml11() throws Exception {
+ for (int i = 0; i < 0xFFFF; i++) {
+ char badChar = (char) i;
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ SAXTransformerFactory transformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance();
+ TransformerHandler handler = transformerFactory.newTransformerHandler();
+ Transformer serializer = handler.getTransformer();
+ serializer.setOutputProperty(OutputKeys.VERSION, "1.1");
+ serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
+ serializer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+ handler.setResult(new StreamResult(out));
+ SimpleCharacterWriter writer = new SimpleCharacterWriter(handler);
+ writer.write(badChar);
+
+ XMLReader parser = XMLReaderFactory.createXMLReader();
+ parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
+ SimpleCharacterReader readHandler = new SimpleCharacterReader();
+ parser.setErrorHandler(new ErrorHandler() {
+ public void warning(SAXParseException exception) throws SAXException {
+ exception.printStackTrace();
+ }
+
+ public void fatalError(SAXParseException exception) throws SAXException {
+ exception.printStackTrace();
+ }
+
+ public void error(SAXParseException exception) throws SAXException {
+ exception.printStackTrace();
+ }
+ });
+ parser.setContentHandler(readHandler);
+ parser.parse(new InputSource(new ByteArrayInputStream(out.toByteArray())));
+ char character = readHandler.getCharacter();
+ assertEquals(badChar, character);
+ }
+ }
+
+}

Back to the top