provide an IValidator with our UniversalTestDocument

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/io/UniversalTestDocument.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/io/UniversalTestDocument.java
index 4a5c4ce..013e016 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/io/UniversalTestDocument.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/io/UniversalTestDocument.java
@@ -10,18 +10,38 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.io;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.eclipse.core.runtime.QualifiedName;
 import org.eclipse.vex.core.internal.dom.Document;
+import org.eclipse.vex.core.provisional.dom.AttributeDefinition;
+import org.eclipse.vex.core.provisional.dom.DocumentContentModel;
+import org.eclipse.vex.core.provisional.dom.IAttribute;
 import org.eclipse.vex.core.provisional.dom.IDocument;
 import org.eclipse.vex.core.provisional.dom.IElement;
 import org.eclipse.vex.core.provisional.dom.IParent;
+import org.eclipse.vex.core.provisional.dom.IValidator;
 
 /**
  * @author Florian Thienel
  */
 public class UniversalTestDocument {
 
+	private static final QualifiedName DOC = new QualifiedName(null, "doc");
+	private static final QualifiedName SECTION = new QualifiedName(null, "section");
+	private static final QualifiedName PARA = new QualifiedName(null, "para");
+	private static final QualifiedName B = new QualifiedName(null, "b");
+	private static final QualifiedName I = new QualifiedName(null, "i");
+
 	private static final String LOREM_IPSUM_LONG = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.";
+
 	private final IDocument document;
 
 	public UniversalTestDocument(final int sampleCount) {
@@ -50,7 +70,9 @@
 	}
 
 	public static IDocument createTestDocument(final int sampleCount) {
-		final Document document = new Document(new QualifiedName(null, "doc"));
+		final Document document = new Document(DOC);
+		document.setValidator(new UniversalTestDocumentValidator());
+
 		for (int i = 0; i < sampleCount; i += 1) {
 			insertSection(document.getRootElement(), i, false);
 		}
@@ -58,7 +80,7 @@
 	}
 
 	private static void insertSection(final IParent parent, final int index, final boolean withInlineElements) {
-		final IElement section = insertElement(parent, "section");
+		final IElement section = insertElement(parent, SECTION);
 		insertParagraph(section, index, withInlineElements);
 		insertEmptyParagraph(section);
 	}
@@ -72,12 +94,12 @@
 	}
 
 	private static IElement insertEmptyParagraph(final IParent parent) {
-		return insertElement(parent, "para");
+		return insertElement(parent, PARA);
 	}
 
-	private static IElement insertElement(final IParent parent, final String localName) {
+	private static IElement insertElement(final IParent parent, final QualifiedName elementName) {
 		final IDocument document = parent.getDocument();
-		return document.insertElement(parent.getEndOffset(), new QualifiedName(null, localName));
+		return document.insertElement(parent.getEndOffset(), elementName);
 	}
 
 	private static void insertText(final IParent parent, final String text) {
@@ -86,7 +108,9 @@
 	}
 
 	public static IDocument createTestDocumentWithInlineElements(final int sampleCount) {
-		final Document document = new Document(new QualifiedName(null, "doc"));
+		final Document document = new Document(DOC);
+		document.setValidator(new UniversalTestDocumentValidator());
+
 		for (int i = 0; i < sampleCount; i += 1) {
 			insertSection(document.getRootElement(), i, true);
 		}
@@ -106,7 +130,7 @@
 				startOffset = text.length();
 			} else {
 				document.insertText(parent.getEndOffset(), text.substring(startOffset, wordStart + 1));
-				final IElement inlineElement = document.insertElement(parent.getEndOffset(), new QualifiedName(null, "b"));
+				final IElement inlineElement = document.insertElement(parent.getEndOffset(), B);
 				document.insertText(inlineElement.getEndOffset(), text.substring(wordStart + 1, wordEnd));
 				document.insertText(parent.getEndOffset(), text.substring(wordEnd, wordEnd + 1));
 				startOffset = wordEnd + 1;
@@ -114,4 +138,87 @@
 		}
 	}
 
+	private static class UniversalTestDocumentValidator implements IValidator {
+
+		private static final Map<QualifiedName, Set<QualifiedName>> VALID_ITEMS = new HashMap<QualifiedName, Set<QualifiedName>>() {
+			private static final long serialVersionUID = 1L;
+
+			{
+				put(DOC, set(SECTION));
+				put(SECTION, set(PARA));
+				put(PARA, set(IValidator.PCDATA, B, I));
+				put(B, set(IValidator.PCDATA, B, I));
+				put(I, set(IValidator.PCDATA, B, I));
+			}
+		};
+
+		private final DocumentContentModel documentContentModel = new DocumentContentModel();
+
+		@Override
+		public DocumentContentModel getDocumentContentModel() {
+			return documentContentModel;
+		}
+
+		@Override
+		public AttributeDefinition getAttributeDefinition(final IAttribute attribute) {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public List<AttributeDefinition> getAttributeDefinitions(final IElement element) {
+			return Collections.emptyList();
+		}
+
+		@Override
+		public Set<QualifiedName> getValidItems(final IElement element) {
+			return VALID_ITEMS.get(element.getQualifiedName());
+		}
+
+		private static Set<QualifiedName> set(final QualifiedName... names) {
+			return new HashSet<QualifiedName>(Arrays.asList(names));
+		}
+
+		@Override
+		public boolean isValidSequence(final QualifiedName element, final List<QualifiedName> nodes, final boolean partial) {
+			final Set<QualifiedName> validItems = VALID_ITEMS.get(element);
+			for (final QualifiedName node : nodes) {
+				if (!validItems.contains(node)) {
+					return false;
+				}
+			}
+			return true;
+		}
+
+		@Override
+		public boolean isValidSequence(final QualifiedName element, final List<QualifiedName> seq1, final List<QualifiedName> seq2, final List<QualifiedName> seq3, final boolean partial) {
+			final List<QualifiedName> joinedSequence = new ArrayList<QualifiedName>();
+			if (seq1 != null) {
+				joinedSequence.addAll(seq1);
+			}
+			if (seq2 != null) {
+				joinedSequence.addAll(seq2);
+			}
+			if (seq3 != null) {
+				joinedSequence.addAll(seq3);
+			}
+			return isValidSequence(element, joinedSequence, partial);
+		}
+
+		@Override
+		public boolean isValidSequenceXInclude(final List<QualifiedName> nodes, final boolean partial) {
+			return true;
+		}
+
+		@Override
+		public Set<QualifiedName> getValidRootElements() {
+			return set(DOC);
+		}
+
+		@Override
+		public Set<String> getRequiredNamespaces() {
+			return Collections.emptySet();
+		}
+
+	}
+
 }