Textual content is only available if associated to content.

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/NodeTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/NodeTest.java
index 0ba3865..69bc12f 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/NodeTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/NodeTest.java
@@ -15,6 +15,7 @@
 import static org.junit.Assert.assertNull;

 import static org.junit.Assert.assertSame;

 

+import org.eclipse.core.runtime.AssertionFailedException;

 import org.junit.Before;

 import org.junit.Test;

 

@@ -61,12 +62,27 @@
 		content.insertElementMarker(0);

 

 		node.associate(content, 0, 1);

-		node.dissocate();

+		node.dissociate();

 

 		content.insertText(1, "Hello");

-		assertEquals(Position.NULL.getOffset(), node.getStartOffset());

-		assertEquals(Position.NULL.getOffset(), node.getEndOffset());

 		assertNull(node.getContent());

 	}

 

+	@Test

+	public void hasTextualContent() throws Exception {

+		final GapContent content = new GapContent(3);

+		content.insertElementMarker(0);

+		content.insertElementMarker(0);

+

+		node.associate(content, 0, 1);

+		assertEquals("", node.getText());

+

+		content.insertText(1, "Hello");

+		assertEquals("Hello", node.getText());

+	}

+

+	@Test(expected = AssertionFailedException.class)

+	public void cannotHaveTextualContentIfNotAssociatedToContent() throws Exception {

+		node.getText();

+	}

 }

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Node.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Node.java
index 8c33aea..cc4b29b 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Node.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Node.java
@@ -10,6 +10,8 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
+import org.eclipse.core.runtime.Assert;
+
 /**
  * This class represents one node within the XML structure, which is also associated to a region of the textual content.
  * It is the base class for all representatives of the XML structure in the document object model (DOM).
@@ -49,6 +51,10 @@
 	 *            offset at which the node's content ends
 	 */
 	public void associate(final Content content, final int startOffset, final int endOffset) {
+		if (this.content != null) {
+			dissociate();
+		}
+
 		this.content = content;
 		startPosition = content.createPosition(startOffset);
 		endPosition = content.createPosition(endOffset);
@@ -57,7 +63,9 @@
 	/**
 	 * Dissociates this node from its associated content region.
 	 */
-	public void dissocate() {
+	public void dissociate() {
+		Assert.isNotNull(content, "Node must be associated to a Content region before it can be dissociated.");
+
 		content.removePosition(startPosition);
 		content.removePosition(endPosition);
 		startPosition = Position.NULL;
@@ -78,6 +86,7 @@
 	 * @return the start offset of this node within the textual content
 	 */
 	public int getStartOffset() {
+		Assert.isNotNull(content, "Node must be associated to a Content region to have an start offset.");
 		return startPosition.getOffset();
 	}
 
@@ -87,6 +96,7 @@
 	 * @return the end offset of this node within the textual content
 	 */
 	public int getEndOffset() {
+		Assert.isNotNull(content, "Node must be associated to a Content region to have an end offset.");
 		return endPosition.getOffset();
 	}
 
@@ -96,6 +106,7 @@
 	 * @return the textual content of this node
 	 */
 	public String getText() {
+		Assert.isNotNull(content, "Node must be associated to a Content region to have textual content.");
 		return content.getText(getStartOffset(), getEndOffset() - getStartOffset());
 	}