Insertion of elements into comments should not be possible

https://bugs.eclipse.org/bugs/show_bug.cgi?id=407801
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/L1CommentHandlingTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/L1CommentHandlingTest.java
index 59ed959..c076ef3 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/L1CommentHandlingTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/L1CommentHandlingTest.java
@@ -7,6 +7,7 @@
  * 

  * Contributors:

  * 		Florian Thienel - initial API and implementation

+ *      Carsten Hiesserich - handling of elements within comments (bug 407801)

  *******************************************************************************/

 package org.eclipse.vex.core.internal.dom;

 

@@ -30,6 +31,8 @@
  */

 public class L1CommentHandlingTest {

 

+	private static final QualifiedName VALID_CHILD = new QualifiedName(null, "validChild");

+

 	private Document document;

 	private Element rootElement;

 	private Element titleElement;

@@ -97,4 +100,23 @@
 		assertSame(rootElement, actualChildren.next());

 		assertFalse(actualChildren.hasNext());

 	}

+

+	@Test

+	public void shouldIndicateInvalidInsertionInComments() throws Exception {

+		final IComment comment = document.insertComment(titleElement.getStartOffset());

+		assertFalse(document.canInsertElement(comment.getEndOffset(), VALID_CHILD));

+		assertFalse(document.canInsertComment(comment.getEndOffset()));

+	}

+

+	@Test(expected = DocumentValidationException.class)

+	public void shouldNotInsertElementInComment() throws Exception {

+		final IComment comment = document.insertComment(titleElement.getStartOffset());

+		document.insertElement(comment.getEndOffset(), VALID_CHILD);

+	}

+

+	@Test(expected = DocumentValidationException.class)

+	public void shouldNotInsertCommentInComment() throws Exception {

+		final IComment comment = document.insertComment(titleElement.getStartOffset());

+		document.insertComment(comment.getEndOffset());

+	}

 }

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 a712634..d91bb54 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
@@ -75,6 +75,19 @@
 	}
 
 	@Test
+	public void provideNoAllowedElementsForInsertionInComment() throws Exception {
+		final VexWidgetImpl widget = new VexWidgetImpl(new MockHostComponent());
+		final Document document = createDocument(STRUCTURE_NS, "chapter");
+		widget.setDocument(document, StyleSheet.NULL);
+		widget.insertElement(new QualifiedName(STRUCTURE_NS, "title"));
+		widget.moveBy(1);
+		widget.insertElement(new QualifiedName(CONTENT_NS, "p"));
+		widget.insertComment();
+
+		assertCannotInsertAnything(widget);
+	}
+
+	@Test
 	public void undoRemoveCommentTag() throws Exception {
 		final VexWidgetImpl widget = new VexWidgetImpl(new MockHostComponent());
 		widget.setDocument(createDocument(STRUCTURE_NS, "chapter"), StyleSheet.NULL);
@@ -128,6 +141,10 @@
 		assertEquals(Arrays.toString(expected), Arrays.toString(actual));
 	}
 
+	public static void assertCannotInsertAnything(final IVexWidget widget) {
+		assertCanInsertOnly(widget /* nothing */);
+	}
+
 	public static String[] sortedCopyOf(final Object[] objects) {
 		final String[] result = new String[objects.length];
 		for (int i = 0; i < result.length; i++) {
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Document.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Document.java
index 778332a..1c3620a 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Document.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Document.java
@@ -9,6 +9,7 @@
  *     John Krasnay - initial API and implementation
  *     Igor Jacy Lino Campista - Java 5 warnings fixed (bug 311325)
  *     Florian Thienel - refactoring to full fledged DOM
+ *     Carsten Hiesserich - handling of elements within comments (bug 407801)
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
@@ -212,6 +213,11 @@
 
 			@Override
 			public Boolean visit(final IComment comment) {
+				for (final QualifiedName nodeName : nodeNames) {
+					if (!nodeName.equals(IValidator.PCDATA)) {
+						return false;
+					}
+				}
 				return true;
 			}
 
@@ -307,7 +313,7 @@
 	}
 
 	public boolean canInsertElement(final int offset, final QualifiedName elementName) {
-		return canInsertAt(getElementForInsertionAt(offset), offset, elementName);
+		return canInsertAt(getNodeForInsertionAt(offset), offset, elementName);
 	}
 
 	public Element insertElement(final int offset, final QualifiedName elementName) throws DocumentValidationException {
@@ -315,7 +321,8 @@
 				MessageFormat.format("Offset must be in [{0}, {1}]", rootElement.getStartOffset() + 1, rootElement.getEndOffset()));
 
 		final Element parent = getElementForInsertionAt(offset);
-		if (!canInsertAt(parent, offset, elementName)) {
+		final INode node = getNodeForInsertionAt(offset);
+		if (!canInsertAt(node, offset, elementName)) {
 			throw new DocumentValidationException(MessageFormat.format("Cannot insert element {0} at offset {1}.", elementName, offset));
 		}
 
@@ -334,14 +341,15 @@
 	}
 
 	public boolean canInsertFragment(final int offset, final IDocumentFragment fragment) {
-		return canInsertAt(getElementForInsertionAt(offset), offset, fragment.getNodeNames());
+		return canInsertAt(getNodeForInsertionAt(offset), offset, fragment.getNodeNames());
 	}
 
 	public void insertFragment(final int offset, final IDocumentFragment fragment) throws DocumentValidationException {
 		Assert.isTrue(isInsertionPointIn(this, offset), "Cannot insert fragment outside of the document range.");
 
 		final Element parent = getElementForInsertionAt(offset);
-		if (!canInsertAt(parent, offset, fragment.getNodeNames())) {
+		final INode node = getNodeForInsertionAt(offset);
+		if (!canInsertAt(node, offset, fragment.getNodeNames())) {
 			throw new DocumentValidationException(MessageFormat.format("Cannot insert document fragment at offset {0}.", offset));
 		}
 
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/VexWidgetImpl.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/VexWidgetImpl.java
index ae18e92..ddd7ab4 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/VexWidgetImpl.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/VexWidgetImpl.java
@@ -10,6 +10,7 @@
  *     Igor Jacy Lino Campista - Java 5 warnings fixed (bug 311325)
  *     Holger Voormann - bug 315914: content assist should only show elements 
  *			valid in the current context
+ *     Carsten Hiesserich - handling of elements within comments (bug 407801)
  *******************************************************************************/
 package org.eclipse.vex.core.internal.widget;
 
@@ -61,6 +62,7 @@
 import org.eclipse.vex.core.provisional.dom.ContentChangeEvent;
 import org.eclipse.vex.core.provisional.dom.ContentRange;
 import org.eclipse.vex.core.provisional.dom.DocumentValidationException;
+import org.eclipse.vex.core.provisional.dom.Filters;
 import org.eclipse.vex.core.provisional.dom.IComment;
 import org.eclipse.vex.core.provisional.dom.IDocument;
 import org.eclipse.vex.core.provisional.dom.IDocumentFragment;
@@ -621,11 +623,14 @@
 		final int startOffset = getStartOffset();
 		final int endOffset = getEndOffset();
 
-		final IElement parent = doc.getElementForInsertionAt(startOffset);
-		if (parent == null) {
+		final INode parentNode = doc.getNodeForInsertionAt(startOffset);
+		final boolean parentNodeIsElement = Filters.elements().matches(parentNode);
+		if (!parentNodeIsElement) {
 			return new ElementName[0];
 		}
 
+		final IElement parent = (IElement) parentNode;
+
 		final List<QualifiedName> nodesBefore = Node.getNodeNames(parent.children().before(startOffset));
 		final List<QualifiedName> nodesAfter = Node.getNodeNames(parent.children().after(endOffset));
 		final List<QualifiedName> selectedNodes = Node.getNodeNames(parent.children().in(new ContentRange(startOffset, endOffset)));