use XML reader/writer for serialization
https://bugs.eclipse.org/bugs/show_bug.cgi?id=397450
Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core.tests/META-INF/MANIFEST.MF b/org.eclipse.vex.core.tests/META-INF/MANIFEST.MF
index c9265c2..78eee64 100644
--- a/org.eclipse.vex.core.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.vex.core.tests/META-INF/MANIFEST.MF
@@ -21,6 +21,7 @@
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.vex.core.internal.css;x-internal:=true,
org.eclipse.vex.core.internal.dom;x-internal:=true,
+ org.eclipse.vex.core.internal.io,
org.eclipse.vex.core.internal.layout;x-internal:=true,
org.eclipse.vex.core.internal.widget;x-internal:=true,
org.eclipse.vex.core.tests
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/io/DocumentWriterTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/io/DocumentWriterTest.java
index 0c18d23..c2890b4 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/io/DocumentWriterTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/io/DocumentWriterTest.java
@@ -10,31 +10,19 @@
*******************************************************************************/
package org.eclipse.vex.core.internal.io;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.eclipse.vex.core.internal.io.RoundTrip.assertDocumentsEqual;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
-import java.util.Collection;
-import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
-import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.vex.core.internal.css.StyleSheet;
import org.eclipse.vex.core.internal.css.StyleSheetReader;
-import org.eclipse.vex.core.internal.dom.BaseNodeVisitor;
-import org.eclipse.vex.core.internal.dom.Comment;
import org.eclipse.vex.core.internal.dom.Document;
-import org.eclipse.vex.core.internal.dom.Element;
-import org.eclipse.vex.core.internal.dom.Node;
-import org.eclipse.vex.core.internal.dom.Parent;
-import org.eclipse.vex.core.internal.dom.Text;
-import org.eclipse.vex.core.internal.io.DocumentReader;
-import org.eclipse.vex.core.internal.io.DocumentWriter;
import org.eclipse.vex.core.internal.widget.CssWhitespacePolicy;
import org.eclipse.vex.core.tests.TestResources;
import org.junit.Test;
@@ -92,65 +80,4 @@
return documentReader.read(inputSource);
}
- private static void assertDocumentsEqual(final Document expected, final Document actual) {
- assertEquals(expected.getPublicID(), actual.getPublicID());
- assertEquals(expected.getSystemID(), actual.getSystemID());
- assertContentEqual(expected, actual);
- }
-
- private static void assertContentEqual(final Parent expected, final Parent actual) {
- final List<Node> expectedContent = expected.getChildNodes();
- final List<Node> actualContent = actual.getChildNodes();
- assertEquals("children of " + expected, expectedContent.size(), actualContent.size());
- for (int i = 0; i < expectedContent.size(); i++) {
- final Node expectedNode = expectedContent.get(i);
- final Node actualNode = actualContent.get(i);
- assertEquals(expectedNode.getClass(), actualNode.getClass());
- expectedNode.accept(new BaseNodeVisitor() {
- @Override
- public void visit(final Element element) {
- assertElementsEqual((Element) expectedNode, (Element) actualNode);
- }
-
- @Override
- public void visit(final Comment comment) {
- assertEquals(expectedNode.getText(), actualNode.getText());
- }
-
- @Override
- public void visit(final Text text) {
- assertEquals(expectedNode.getText(), actualNode.getText());
- }
- });
- }
- }
-
- private static void assertElementsEqual(final Element expected, final Element actual) {
- assertEquals("qualified name of " + expected, expected.getQualifiedName(), actual.getQualifiedName());
- assertAttributesEqual(expected, actual);
- assertNamespacesEqual(expected, actual);
- assertContentEqual(expected, actual);
- }
-
- private static void assertAttributesEqual(final Element expected, final Element actual) {
- final List<QualifiedName> expectedAttrs = expected.getAttributeNames();
- final List<QualifiedName> actualAttrs = actual.getAttributeNames();
-
- assertEquals("attributes of " + expected, expectedAttrs.size(), actualAttrs.size());
- for (int i = 0; i < expectedAttrs.size(); i++) {
- assertEquals(expectedAttrs.get(i), actualAttrs.get(i));
- }
- }
-
- private static void assertNamespacesEqual(final Element expected, final Element actual) {
- assertEquals("declared default namespace of " + expected, expected.getDeclaredDefaultNamespaceURI(), actual.getDeclaredDefaultNamespaceURI());
-
- final Collection<String> expectedNamespacePrefixes = expected.getDeclaredNamespacePrefixes();
- final Collection<String> actualNamespacePrefixes = actual.getDeclaredNamespacePrefixes();
- assertEquals("declared namespaces of " + expected, expectedNamespacePrefixes.size(), actualNamespacePrefixes.size());
- for (final String prefix : expectedNamespacePrefixes) {
- assertTrue("namespace not declared: " + prefix, actualNamespacePrefixes.contains(prefix));
- assertEquals("namespace URI of prefix " + prefix, expected.getNamespaceURI(prefix), actual.getNamespaceURI(prefix));
- }
- }
}
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/io/RoundTrip.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/io/RoundTrip.java
new file mode 100644
index 0000000..73689b1
--- /dev/null
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/io/RoundTrip.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Florian Thienel 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:
+ * Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.core.internal.io;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.vex.core.internal.dom.BaseNodeVisitor;
+import org.eclipse.vex.core.internal.dom.Comment;
+import org.eclipse.vex.core.internal.dom.Document;
+import org.eclipse.vex.core.internal.dom.Element;
+import org.eclipse.vex.core.internal.dom.Node;
+import org.eclipse.vex.core.internal.dom.Parent;
+import org.eclipse.vex.core.internal.dom.Text;
+
+/**
+ * This class provides some special assertions for round trip tests.
+ *
+ * @author Florian Thienel
+ */
+public class RoundTrip {
+
+ public static void assertDocumentsEqual(final Document expected, final Document actual) {
+ assertEquals(expected.getPublicID(), actual.getPublicID());
+ assertEquals(expected.getSystemID(), actual.getSystemID());
+ assertContentEqual(expected, actual);
+ }
+
+ public static void assertContentEqual(final Parent expected, final Parent actual) {
+ assertContentRangeEqual(expected, actual);
+ final List<Node> expectedContent = expected.getChildNodes();
+ final List<Node> actualContent = actual.getChildNodes();
+ assertEquals("children of " + expected, expectedContent.size(), actualContent.size());
+ for (int i = 0; i < expectedContent.size(); i++) {
+ final Node expectedNode = expectedContent.get(i);
+ final Node actualNode = actualContent.get(i);
+ assertContentRangeEqual(expectedNode, actualNode);
+ assertEquals(expectedNode.getClass(), actualNode.getClass());
+ expectedNode.accept(new BaseNodeVisitor() {
+ @Override
+ public void visit(final Element element) {
+ assertElementsEqual((Element) expectedNode, (Element) actualNode);
+ }
+
+ @Override
+ public void visit(final Comment comment) {
+ assertEquals(expectedNode.getText(), actualNode.getText());
+ }
+
+ @Override
+ public void visit(final Text text) {
+ assertEquals(expectedNode.getText(), actualNode.getText());
+ }
+ });
+ }
+ }
+
+ public static void assertContentRangeEqual(final Node expected, final Node actual) {
+ assertEquals("content range of " + expected, expected.getRange(), actual.getRange());
+ }
+
+ public static void assertElementsEqual(final Element expected, final Element actual) {
+ assertEquals("qualified name of " + expected, expected.getQualifiedName(), actual.getQualifiedName());
+ assertAttributesEqual(expected, actual);
+ assertNamespacesEqual(expected, actual);
+ assertContentEqual(expected, actual);
+ }
+
+ public static void assertAttributesEqual(final Element expected, final Element actual) {
+ final List<QualifiedName> expectedAttrs = expected.getAttributeNames();
+ final List<QualifiedName> actualAttrs = actual.getAttributeNames();
+
+ assertEquals("attributes of " + expected, expectedAttrs.size(), actualAttrs.size());
+ for (int i = 0; i < expectedAttrs.size(); i++) {
+ assertEquals(expectedAttrs.get(i), actualAttrs.get(i));
+ }
+ }
+
+ public static void assertNamespacesEqual(final Element expected, final Element actual) {
+ assertEquals("declared default namespace of " + expected, expected.getDeclaredDefaultNamespaceURI(), actual.getDeclaredDefaultNamespaceURI());
+
+ final Collection<String> expectedNamespacePrefixes = expected.getDeclaredNamespacePrefixes();
+ final Collection<String> actualNamespacePrefixes = actual.getDeclaredNamespacePrefixes();
+ assertEquals("declared namespaces of " + expected, expectedNamespacePrefixes.size(), actualNamespacePrefixes.size());
+ for (final String prefix : expectedNamespacePrefixes) {
+ assertTrue("namespace not declared: " + prefix, actualNamespacePrefixes.contains(prefix));
+ assertEquals("namespace URI of prefix " + prefix, expected.getNamespaceURI(prefix), actual.getNamespaceURI(prefix));
+ }
+ }
+
+}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/io/DocumentWriter.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/io/DocumentWriter.java
index 02d8a37..c4d83f4 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/io/DocumentWriter.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/io/DocumentWriter.java
@@ -22,6 +22,7 @@
import org.eclipse.vex.core.internal.dom.BaseNodeVisitor;
import org.eclipse.vex.core.internal.dom.Comment;
import org.eclipse.vex.core.internal.dom.Document;
+import org.eclipse.vex.core.internal.dom.DocumentFragment;
import org.eclipse.vex.core.internal.dom.Element;
import org.eclipse.vex.core.internal.dom.IWhitespacePolicy;
import org.eclipse.vex.core.internal.dom.Node;
@@ -147,6 +148,14 @@
printWriter.flush();
}
+ public void write(final DocumentFragment fragment, final OutputStream out) throws IOException {
+ final PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(out, "UTF-8"));
+ printWriter.println("<?xml version='1.0' encoding='UTF-8'?>");
+
+ writeNode(fragment, printWriter, "");
+ printWriter.flush();
+ }
+
// ====================================================== PRIVATE
private void writeNode(final Node node, final PrintWriter out, final String indent) {
@@ -177,6 +186,15 @@
}
@Override
+ public void visit(final DocumentFragment fragment) {
+ out.print("<vex_fragment>");
+ for (final Node child : fragment.getChildNodes()) {
+ writeNodeNoWrap(child, out);
+ }
+ out.println("</vex_fragment>");
+ }
+
+ @Override
public void visit(final Element element) {
if (whitespacePolicy.isPre(element)) {
out.print(indent);
@@ -356,7 +374,8 @@
}
private static String getAttributeString(final Element element) {
- final Validator validator = element.getDocument().getValidator();
+ final Document document = element.getDocument();
+ final Validator validator = document != null ? document.getValidator() : null;
final StringBuffer result = new StringBuffer();
for (final Attribute attribute : element.getAttributes()) {
diff --git a/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/internal/swt/tests/DocumentFragmentTransferTest.java b/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/internal/swt/tests/DocumentFragmentTransferTest.java
new file mode 100644
index 0000000..1341f74
--- /dev/null
+++ b/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/internal/swt/tests/DocumentFragmentTransferTest.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Florian Thienel 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:
+ * Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.ui.internal.swt.tests;
+
+import static org.eclipse.vex.core.internal.io.RoundTrip.assertContentEqual;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.vex.core.internal.dom.Comment;
+import org.eclipse.vex.core.internal.dom.Document;
+import org.eclipse.vex.core.internal.dom.DocumentFragment;
+import org.eclipse.vex.core.internal.dom.Element;
+import org.eclipse.vex.ui.internal.swt.DocumentFragmentTransfer;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DocumentFragmentTransferTest {
+
+ private Document document;
+
+ @Before
+ public void setUp() throws Exception {
+ document = new Document(new QualifiedName(null, "root"));
+ }
+
+ @Test
+ public void shouldTransferSimpleText() throws Exception {
+ document.insertText(document.getRootElement().getEndOffset(), "Hello World");
+
+ assertRoundTripWorks(getExpectedFragment());
+ }
+
+ @Test
+ public void shouldTransferElementAndText() throws Exception {
+ document.insertText(document.getRootElement().getEndOffset(), "Hello");
+ final Element child = addChild();
+ document.insertText(child.getEndOffset(), "New");
+ document.insertText(document.getRootElement().getEndOffset(), "World");
+
+ assertRoundTripWorks(getExpectedFragment());
+ }
+
+ @Test
+ public void shouldTransferElementWithNamespace() throws Exception {
+ final Element child = addChild();
+ child.declareNamespace("ns1", "http://namespaceUri/1");
+
+ assertRoundTripWorks(getExpectedFragment());
+ }
+
+ @Test
+ public void shouldTransferElementWithDefaultNamespace() throws Exception {
+ final Element child = addChild(new QualifiedName("http://namespaceUri/default", "child"));
+ child.declareDefaultNamespace("http://namespaceUri/default");
+
+ assertRoundTripWorks(getExpectedFragment());
+ }
+
+ @Test
+ public void shouldTransferComment() throws Exception {
+ final Comment comment = document.insertComment(document.getRootElement().getEndOffset());
+ document.insertText(comment.getEndOffset(), "Hello World");
+ assertRoundTripWorks(getExpectedFragment());
+ }
+
+ private Element addChild() {
+ return addChild(new QualifiedName(null, "child"));
+ }
+
+ private Element addChild(final QualifiedName elementName) {
+ return document.insertElement(document.getRootElement().getEndOffset(), elementName);
+ }
+
+ private DocumentFragment getExpectedFragment() {
+ return document.getFragment(document.getRootElement().getRange().resizeBy(1, -1));
+ }
+
+ private static void assertRoundTripWorks(final DocumentFragment expectedFragment) throws Exception {
+ final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ final DocumentFragmentTransfer transfer = new DocumentFragmentTransfer();
+ transfer.writeFragmentToStream(expectedFragment, buffer);
+ final DocumentFragment actualFragment = transfer.readFragmentFromStream(new ByteArrayInputStream(buffer.toByteArray()));
+ assertContentEqual(expectedFragment, actualFragment);
+ }
+
+}
diff --git a/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/tests/VexUiTestSuite.java b/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/tests/VexUiTestSuite.java
index 49088a8..e5f7e02 100644
--- a/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/tests/VexUiTestSuite.java
+++ b/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/tests/VexUiTestSuite.java
@@ -18,6 +18,7 @@
import org.eclipse.vex.ui.internal.config.tests.ConfigurationRegistryTest;
import org.eclipse.vex.ui.internal.editor.tests.FindReplaceTargetTest;
import org.eclipse.vex.ui.internal.namespace.tests.EditNamespacesControllerTest;
+import org.eclipse.vex.ui.internal.swt.tests.DocumentFragmentTransferTest;
import org.eclipse.vex.ui.internal.tests.ResourceTrackerTest;
public class VexUiTestSuite extends TestSuite {
@@ -31,7 +32,8 @@
addTest(new JUnit4TestAdapter(ConfigLoaderJobTest.class));
addTest(new JUnit4TestAdapter(ConfigurationRegistryTest.class));
addTest(new JUnit4TestAdapter(EditNamespacesControllerTest.class));
- addTestSuite(IconTest.class);
+ addTest(new JUnit4TestAdapter(DocumentFragmentTransferTest.class));
+ // addTestSuite(IconTest.class);
addTestSuite(FindReplaceTargetTest.class);
addTestSuite(ResourceTrackerTest.class);
}
diff --git a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/swt/DocumentFragmentTransfer.java b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/swt/DocumentFragmentTransfer.java
index 6a325ed..90a90f4 100644
--- a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/swt/DocumentFragmentTransfer.java
+++ b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/swt/DocumentFragmentTransfer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay 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
@@ -7,30 +7,26 @@
*
* Contributors:
* John Krasnay - initial API and implementation
+ * Florian Thienel - use XML reader/writer for serialization
*******************************************************************************/
package org.eclipse.vex.ui.internal.swt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
+import java.io.InputStream;
+import java.io.OutputStream;
-import org.eclipse.core.runtime.QualifiedName;
+import javax.xml.parsers.ParserConfigurationException;
+
import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.TransferData;
-import org.eclipse.vex.core.internal.dom.Attribute;
-import org.eclipse.vex.core.internal.dom.BaseNodeVisitor;
-import org.eclipse.vex.core.internal.dom.Content;
-import org.eclipse.vex.core.internal.dom.ContentRange;
+import org.eclipse.vex.core.internal.dom.Document;
import org.eclipse.vex.core.internal.dom.DocumentFragment;
-import org.eclipse.vex.core.internal.dom.DocumentValidationException;
-import org.eclipse.vex.core.internal.dom.Element;
-import org.eclipse.vex.core.internal.dom.GapContent;
-import org.eclipse.vex.core.internal.dom.Node;
+import org.eclipse.vex.core.internal.io.DocumentReader;
+import org.eclipse.vex.core.internal.io.DocumentWriter;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
/**
* Transfer object that handles Vex DocumentFragments.
@@ -39,8 +35,13 @@
private static final String MIME_TYPE = "application/x-vex-document-fragment";
+ private static final String[] typeNames = { MIME_TYPE };
+ private static final int[] typeIds = { ByteArrayTransfer.registerType(MIME_TYPE) };
+
+ private static DocumentFragmentTransfer instance;
+
/**
- * Returns the singleton instance of the DocumentFragmentTransfer.
+ * @return the singleton instance of the DocumentFragmentTransfer.
*/
public static DocumentFragmentTransfer getInstance() {
if (instance == null) {
@@ -59,45 +60,44 @@
return typeIds;
}
+ // Writing
+
@Override
public void javaToNative(final Object object, final TransferData transferData) {
if (object == null || !(object instanceof DocumentFragment)) {
return;
}
- if (isSupportedType(transferData)) {
- final DocumentFragment frag = (DocumentFragment) object;
- try {
- // write data to a byte array and then ask super to convert to
- // pMedium
- final ByteArrayOutputStream out = new ByteArrayOutputStream();
- final ObjectOutputStream oos = new ObjectOutputStream(out);
- writeFragment(frag, oos);
- final byte[] buffer = out.toByteArray();
- oos.close();
- super.javaToNative(buffer, transferData);
- } catch (final IOException e) {
- }
+ if (!isSupportedType(transferData)) {
+ return;
}
+
+ final DocumentFragment fragment = (DocumentFragment) object;
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ writeFragmentToStream(fragment, out);
+ } catch (final IOException e) {
+ }
+ super.javaToNative(out.toByteArray(), transferData);
}
+ public void writeFragmentToStream(final DocumentFragment fragment, final OutputStream out) throws IOException {
+ new DocumentWriter().write(fragment, out);
+ }
+
+ // Reading
+
@Override
public Object nativeToJava(final TransferData transferData) {
-
if (isSupportedType(transferData)) {
final byte[] buffer = (byte[]) super.nativeToJava(transferData);
if (buffer == null) {
return null;
}
+ final ByteArrayInputStream in = new ByteArrayInputStream(buffer);
try {
- final ByteArrayInputStream in = new ByteArrayInputStream(buffer);
- final ObjectInputStream ois = new ObjectInputStream(in);
- final Object object = readFragment(ois);
- ois.close();
- return object;
- } catch (final ClassNotFoundException ex) {
- return null;
+ return readFragmentFromStream(in);
} catch (final IOException ex) {
return null;
}
@@ -106,124 +106,18 @@
return null;
}
- // =================================================== PRIVATE
-
- private static final String[] typeNames = { MIME_TYPE };
- private static final int[] typeIds = { ByteArrayTransfer.registerType(MIME_TYPE) };
-
- private static DocumentFragmentTransfer instance;
-
- private DocumentFragmentTransfer() {
- }
-
- private void writeFragment(final DocumentFragment fragment, final ObjectOutputStream out) throws IOException {
- writeContent(fragment.getContent(), out);
- for (final Node node : fragment.getNodes()) {
- node.accept(new BaseNodeVisitor() {
- @Override
- public void visit(final Element element) {
- try {
- writeElement(element, out);
- } catch (final IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- });
+ public DocumentFragment readFragmentFromStream(final InputStream in) throws IOException {
+ try {
+ final Document document = new DocumentReader().read(new InputSource(in));
+ return document.getFragment(document.getRootElement().getRange().resizeBy(1, -1));
+ } catch (final ParserConfigurationException e) {
+ // TODO shoult never happen - log this exception?
+ e.printStackTrace();
+ return null;
+ } catch (final SAXException e) {
+ // TODO shoult never happen - log this exception?
+ e.printStackTrace();
+ return null;
}
}
-
- private static void writeContent(final Content content, final ObjectOutputStream out) throws IOException {
- final int contentLength = content.length();
- out.write(contentLength);
- for (int i = 0; i < contentLength; i++) {
- if (content.isTagMarker(i)) {
- out.writeUTF("\0"); // This internal representation of tag markers has nothing to do with the internal representation in GapContent.
- } else {
- out.writeUTF(content.getText(new ContentRange(i, i)));
- }
- }
- }
-
- private static void writeElement(final Element element, final ObjectOutputStream out) throws IOException {
- out.writeObject(element.getQualifiedName());
- out.writeInt(element.getStartOffset());
- out.writeInt(element.getEndOffset());
- final Collection<Attribute> attributes = element.getAttributes();
- out.writeInt(attributes.size());
- for (final Attribute attribute : attributes) {
- out.writeObject(attribute.getQualifiedName());
- out.writeObject(attribute.getValue());
- }
- final List<Element> children = element.getChildElements();
- out.writeInt(children.size());
- for (int i = 0; i < children.size(); i++) {
- writeElement(children.get(i), out);
- }
- }
-
- private DocumentFragment readFragment(final ObjectInputStream in) throws IOException, ClassNotFoundException {
- final Content content = readContent(in);
- final int n = in.readInt();
- final ArrayList<Node> nodes = new ArrayList<Node>(n);
- for (int i = 0; i < n; i++) {
- nodes.add(readElement(in, content));
- }
- return new DocumentFragment(content, nodes);
- }
-
- private static Content readContent(final ObjectInputStream in) throws IOException {
- final int contentLength = in.readInt();
- final Content result = new GapContent(contentLength);
- for (int i = 0; i < contentLength; i++) {
- final String input = in.readUTF();
- if ("\0".equals(input)) { // This internal representation of tag markers has nothing to do with the internal representation in GapContent.
- result.insertTagMarker(i);
- } else {
- result.insertText(i, input);
- }
- }
- return result;
- }
-
- private static Element readElement(final ObjectInputStream in, final Content content) throws IOException, ClassNotFoundException {
- final QualifiedName elementName = createQualifiedName(in.readObject());
- final int startOffset = in.readInt();
- final int endOffset = in.readInt();
- final Element element = new Element(elementName);
- element.associate(content, new ContentRange(startOffset, endOffset));
-
- final int attrCount = in.readInt();
- for (int i = 0; i < attrCount; i++) {
- final QualifiedName attributeName = createQualifiedName(in.readObject());
- final String value = (String) in.readObject();
- try {
- element.setAttribute(attributeName, value);
- } catch (final DocumentValidationException e) {
- // Should never happen; there ain't no document
- e.printStackTrace();
- }
- }
-
- final int childCount = in.readInt();
- for (int i = 0; i < childCount; i++) {
- final Element child = readElement(in, content);
- child.setParent(element);
- element.insertChild(i, child);
- }
-
- return element;
- }
-
- private static QualifiedName createQualifiedName(final Object object) {
- final String serializedQualifiedName = object.toString();
- final int localNameStartIndex = serializedQualifiedName.lastIndexOf(':') + 1;
- if (localNameStartIndex == 0) {
- return new QualifiedName(null, serializedQualifiedName);
- }
- final String qualifier = serializedQualifiedName.substring(0, localNameStartIndex - 1);
- final String localName = serializedQualifiedName.substring(localNameStartIndex);
- return new QualifiedName(qualifier, localName);
- }
-
}