DTD is preferred over the Schema associated with the current namespace.

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/DTDValidatorTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/DTDValidatorTest.java
index 0d600d0..dacf0bc 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/DTDValidatorTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/DTDValidatorTest.java
@@ -143,15 +143,22 @@
 		assertInvalidSequence("document", "preface", "index");
 	}
 
-	private void assertFullyValidSequence(final String element, final String... sequence) {
+	public void testValidateDocumentWithDTDAndNamespaces() throws Exception {
+		final Document doc = new Document(new RootElement(new QualifiedName("http://namespace/uri/is/not/registered", "section")));
+		doc.setValidator(validator);
+		doc.insertElement(1, new Element("title"));
+		doc.insertText(2, "ab");
+		doc.insertElement(5, new Element("para"));
+		
+		validator.getAttributeDefinitions(doc.getRootElement());
+	}
 
+	private void assertFullyValidSequence(final String element, final String... sequence) {
 		// fully includes partially
 		assertValidSequence(true, element, true, true, sequence);
-
 	}
 
 	private void assertPartiallyValidSequence(final String element, final String... sequence) {
-
 		// as partial sequence valid...
 		assertValidSequence(true, element, false, true, sequence);
 
@@ -160,10 +167,8 @@
 	}
 
 	private void assertInvalidSequence(final String element, final String... sequence) {
-
 		// partially _and_ fully
 		assertValidSequence(false, element, true, true, sequence);
-
 	}
 
 	private void assertValidSequence(final boolean expected, final String element, final boolean validateFully, final boolean validatePartially,
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/SchemaValidatorTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/SchemaValidatorTest.java
index 4ac9ec6..806d044 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/SchemaValidatorTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/SchemaValidatorTest.java
@@ -175,7 +175,7 @@
 	

 	@Test

 	public void proposeElementsFromComplexSchema() throws Exception {

-		final Validator validator = new WTPVEXValidator(STRUCTURE_NS);

+		final Validator validator = new WTPVEXValidator();

 		final Document doc = new Document(new RootElement(CHAPTER));

 		doc.setValidator(validator);

 		doc.insertElement(1, new Element(TITLE));

diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java
index 5f77e0d..9781436 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java
@@ -10,8 +10,10 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.widget;
 
-import static org.junit.Assert.*;
-import static org.eclipse.vex.core.tests.TestResources.*;
+import static org.eclipse.vex.core.tests.TestResources.CONTENT_NS;
+import static org.eclipse.vex.core.tests.TestResources.STRUCTURE_NS;
+import static org.eclipse.vex.core.tests.TestResources.TEST_DTD;
+import static org.junit.Assert.assertTrue;
 
 import java.util.Arrays;
 
@@ -22,8 +24,6 @@
 import org.eclipse.vex.core.internal.dom.RootElement;
 import org.eclipse.vex.core.internal.dom.Validator;
 import org.eclipse.vex.core.internal.validator.WTPVEXValidator;
-import org.eclipse.vex.core.internal.widget.IVexWidget;
-import org.eclipse.vex.core.internal.widget.VexWidgetImpl;
 import org.junit.Test;
 
 public class VexWidgetTest {
@@ -31,7 +31,7 @@
 	@Test
 	public void provideOnlyAllowedElementsFromDtd() throws Exception {
 		final VexWidgetImpl widget = new VexWidgetImpl(new MockHostComponent());
-		widget.setDocument(createDocument(TEST_DTD, "section"), StyleSheet.NULL);
+		widget.setDocument(createDocumentWithDTD(TEST_DTD, "section"), StyleSheet.NULL);
 		assertCanInsertOnly(widget, "title", "para");
 		widget.insertElement(new Element("title"));
 		assertCanInsertOnly(widget);
@@ -41,51 +41,57 @@
 		widget.moveBy(1);
 		assertCanInsertOnly(widget, "para");
 	}
-	
+
 	@Test
 	public void provideOnlyAllowedElementsFromSimpleSchema() throws Exception {
 		final VexWidgetImpl widget = new VexWidgetImpl(new MockHostComponent());
 		widget.setDocument(createDocument(CONTENT_NS, "p"), StyleSheet.NULL);
 		assertCanInsertOnly(widget, "b", "i");
-		widget.insertElement(new Element("b"));
+		widget.insertElement(new Element(new QualifiedName(CONTENT_NS, "b")));
 		assertCanInsertOnly(widget, "b", "i");
 		widget.moveBy(1);
 		assertCanInsertOnly(widget, "b", "i");
 	}
-	
+
 	@Test
 	public void provideOnlyAllowedElementFromComplexSchema() throws Exception {
 		final VexWidgetImpl widget = new VexWidgetImpl(new MockHostComponent());
 		widget.setDocument(createDocument(STRUCTURE_NS, "chapter"), StyleSheet.NULL);
 		assertCanInsertOnly(widget, "title", "chapter", "p");
-		widget.insertElement(new Element("title"));
+		widget.insertElement(new Element(new QualifiedName(STRUCTURE_NS, "title")));
 		assertCanInsertOnly(widget);
 		widget.moveBy(1);
-//		assertCanInsertOnly(widget, "chapter", "p");
+		//		assertCanInsertOnly(widget, "chapter", "p");
 		widget.insertElement(new Element(new QualifiedName(CONTENT_NS, "p")));
 		assertCanInsertOnly(widget, "b", "i");
 		widget.moveBy(1);
-//		assertCanInsertOnly(widget, "p");
+		//		assertCanInsertOnly(widget, "p");
 		// FIXME: maybe the schema is still not what I mean
 	}
-	
-	private static Document createDocument(final String rootSchemaIdentifier, final String rootElementName) {
-		final Validator validator = new WTPVEXValidator(rootSchemaIdentifier);
+
+	private static Document createDocumentWithDTD(final String dtdIdentifier, final String rootElementName) {
+		final Validator validator = new WTPVEXValidator(dtdIdentifier);
 		final Document document = new Document(new RootElement(rootElementName));
 		document.setValidator(validator);
 		return document;
 	}
-	
-	private static void assertCanInsertOnly(IVexWidget widget, final String... elementNames) {
+
+	private static Document createDocument(final String rootSchemaIdentifier, final String rootElementName) {
+		final Validator validator = new WTPVEXValidator();
+		final Document document = new Document(new RootElement(new QualifiedName(rootSchemaIdentifier, rootElementName)));
+		document.setValidator(validator);
+		return document;
+	}
+
+	private static void assertCanInsertOnly(final IVexWidget widget, final String... elementNames) {
 		assertTrue(Arrays.equals(sortedCopyOf(elementNames), sortedCopyOf(widget.getValidInsertElements())));
 	}
-	
-	private static String[] sortedCopyOf(String[] strings) {
+
+	private static String[] sortedCopyOf(final String[] strings) {
 		final String[] result = new String[strings.length];
 		System.arraycopy(strings, 0, result, 0, strings.length);
 		Arrays.sort(result);
 		return result;
 	}
 
-	
 }
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/validator/WTPVEXValidator.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/validator/WTPVEXValidator.java
index 5de14f9..59191af 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/validator/WTPVEXValidator.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/validator/WTPVEXValidator.java
@@ -56,18 +56,22 @@
 
 	private static final URIResolver URI_RESOLVER = URIResolverPlugin.createResolver();
 
-	private CMDocument rootSchema;
+	private CMDocument dtd;
 
 	private final CMValidator validator = new CMValidator();
 
-	private final URL rootSchemaUrl;
+	private final URL dtdUrl;
 
-	public WTPVEXValidator(final URL rootSchemaUrl) {
-		this.rootSchemaUrl = rootSchemaUrl;
+	public WTPVEXValidator() {
+		this.dtdUrl = null;
+	}
+	
+	public WTPVEXValidator(final URL dtdUrl) {
+		this.dtdUrl = dtdUrl;
 	}
 
-	public WTPVEXValidator(final String rootSchemaIdentifier) {
-		this(resolveSchemaIdentifier(rootSchemaIdentifier));
+	public WTPVEXValidator(final String dtdIdentifier) {
+		this(resolveSchemaIdentifier(dtdIdentifier));
 	}
 
 	private static URL resolveSchemaIdentifier(final String schemaIdentifier) {
@@ -90,21 +94,33 @@
 		}
 	}
 
-	private CMDocument getSchema(final String schemaIdentifier) {
-		if (schemaIdentifier == null)
-			return getSchema();
-		final URL resolved = resolveSchemaIdentifier(schemaIdentifier);
+	private CMDocument getSchema(final String namespaceURI) {
+		if (isDTDDefined())
+			return getDTD();
+		if (namespaceURI == null)
+			/*
+			 * TODO this is a common case that should be handled somehow
+			 * - a hint should be shown: there is no DTD or Schema referenced in the document
+			 * - an inferred schema should be used, to allow to at least display the document in the editor
+			 * - this is not the right place to either check or handle this
+			 */
+			throw new AssertionError("There is no definition of the document structure available.");
+		final URL resolved = resolveSchemaIdentifier(namespaceURI);
 		final ContentModelManager modelManager = ContentModelManager.getInstance();
 		return modelManager.createCMDocument(resolved.toString(), null);
 	}
 	
-	private CMDocument getSchema() {
-		if (rootSchema == null) {
+	private boolean isDTDDefined() {
+		return getDTD() != null;
+	}
+	
+	private CMDocument getDTD() {
+		if (dtd == null && dtdUrl != null) {
 			final ContentModelManager modelManager = ContentModelManager.getInstance();
-			final String resolved = rootSchemaUrl.toString();
-			rootSchema = modelManager.createCMDocument(resolved, null);
+			final String resolved = dtdUrl.toString();
+			dtd = modelManager.createCMDocument(resolved, null);
 		}
-		return rootSchema;
+		return dtd;
 	}
 	
 	public AttributeDefinition getAttributeDefinition(final Attribute attribute) {
@@ -248,9 +264,9 @@
 		return list;
 	}
 	
-	private Set<CMElementDeclaration> getValidRootElements(final String schemaIdentifier) {
+	private Set<CMElementDeclaration> getValidRootElements(final String namespaceURI) {
 		final HashSet<CMElementDeclaration> result = new HashSet<CMElementDeclaration>();
-		final Iterator<?> iter = getSchema(schemaIdentifier).getElements().iterator();
+		final Iterator<?> iter = getSchema(namespaceURI).getElements().iterator();
 		while (iter.hasNext()) {
 			final CMElementDeclaration element = (CMElementDeclaration) iter.next();
 			result.add(element);