Author: elvisisking
Date: 2012-04-25 16:39:45 -0400 (Wed, 25 Apr 2012)
New Revision: 40501
Added:
trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/testdata/commentsTest.cnd
Modified:
trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/CndImporter.java
trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/CndImporterTest.java
trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/testdata/aircraft.cnd
Log:
JBIDE-11586 ModeShape Tools JCR CND Editor Deletes Comments And Vendor Extensions.
Corrected some instances where comments were not getting assigned to the right CND
elements.
Modified:
trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/CndImporter.java
===================================================================
---
trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/CndImporter.java 2012-04-25
20:03:22 UTC (rev 40500)
+++
trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/CndImporter.java 2012-04-25
20:39:45 UTC (rev 40501)
@@ -14,6 +14,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.NoSuchElementException;
import java.util.Stack;
import org.eclipse.osgi.util.NLS;
@@ -63,10 +64,12 @@
private final boolean jcr170 = true;
- private final Stack<CndElement> cndElements = new Stack<CndElement>();
+ private final Stack<CommentedCndElement> cndElements = new
Stack<CommentedCndElement>();
private String currentComment;
+ private CommentedCndElement previousElement;
+
/**
* Import the CND content from the supplied stream, placing the content into the
importer's destination.
*
@@ -129,8 +132,6 @@
final CompactNodeTypeDefinition cnd = new CompactNodeTypeDefinition();
- // start processing CND
- push(cnd);
final Tokenizer tokenizer = new CndTokenizer();
final TokenStream tokens = new TokenStream(content, tokenizer, false);
tokens.start();
@@ -155,9 +156,6 @@
}
}
- // finished processing CND
- final CndElement cndElement = pop();
- assert (cnd == cndElement) : "CND Element not the expected CND: " +
cndElement.toCndNotation(NotationType.LONG); //$NON-NLS-1$
return cnd;
}
@@ -209,16 +207,67 @@
assert (childNodeDefn == cndElement) : "Element not expected child node:
" + cndElement.toCndNotation(NotationType.LONG); //$NON-NLS-1$
}
- private void parseComment( final TokenStream tokens ) {
+ private boolean parseComment( final TokenStream tokens ) {
if (tokens.matches(CndTokenizer.COMMENT)) {
- final String newComment =
CommentedCndElement.Helper.removeCommentCharacters(tokens.consume());
+ do {
+ boolean sameLine = false;
- if (Utils.isEmpty(this.currentComment)) {
- this.currentComment = newComment;
- } else {
- this.currentComment += '\n' + newComment;
- }
+ try {
+ sameLine = tokens.nextPosition().getLine() ==
tokens.previousPosition().getLine();
+ } catch (NoSuchElementException e) {
+ // ignore
+ }
+
+ String newComment =
CommentedCndElement.Helper.removeCommentCharacters(tokens.consume());
+
+ // same line comment
+ if (sameLine || (!Utils.isEmpty(this.currentComment) &&
!this.cndElements.isEmpty())) {
+ // concatenate this comment with existing comment
+ if (Utils.isEmpty(this.currentComment)) {
+ this.currentComment = Utils.EMPTY_STRING;
+ } else if (!this.currentComment.endsWith("\n")) {
//$NON-NLS-1$
+ this.currentComment += '\n';
+ }
+
+ this.currentComment += newComment;
+
+ CommentedCndElement cndElement = null;
+
+ if (this.cndElements.isEmpty()) {
+ cndElement = this.previousElement;
+ } else {
+ cndElement = this.cndElements.peek();
+ }
+
+ String comment = cndElement.getComment();
+
+ if (Utils.isEmpty(comment)) {
+ comment = this.currentComment;
+ } else {
+ if (!comment.endsWith("\n")) { //$NON-NLS-1$
+ comment += '\n';
+ }
+
+ comment += this.currentComment;
+ }
+
+ cndElement.setComment(comment);
+ this.currentComment = null;
+ } else {
+ if (this.currentComment == null) {
+ this.currentComment = Utils.EMPTY_STRING;
+ } else if (!this.currentComment.endsWith("\n")) {
//$NON-NLS-1$
+ this.currentComment += '\n';
+ }
+
+ this.currentComment += newComment;
+ }
+ } while (tokens.matches(CndTokenizer.COMMENT));
+
+ return true;
}
+
+ return false;
}
/**
@@ -233,9 +282,6 @@
assert (tokens != null) : "tokens is null"; //$NON-NLS-1$
assert (defaultType != null) : "defaultType is null"; //$NON-NLS-1$
- // start processing default type
- push(defaultType);
-
if (tokens.canConsume(DefaultType.NOTATION)) {
if (tokens.canConsume(AttributeState.VARIANT_CHAR)) {
defaultType.set(Value.VARIANT);
@@ -247,10 +293,6 @@
}
}
}
-
- // finished processing default type
- final CndElement cndElement = pop();
- assert (defaultType == cndElement) : "Element not expected default type:
" + cndElement.toCndNotation(NotationType.LONG); //$NON-NLS-1$
}
/**
@@ -265,6 +307,8 @@
assert (tokens != null) : "tokens is null"; //$NON-NLS-1$
assert (propDefn != null) : "propDefn is null"; //$NON-NLS-1$
+ parseComment(tokens);
+
if (tokens.canConsume(DefaultValues.NOTATION_PREFIX)) {
final List<String> values = parseStringList(tokens);
@@ -308,9 +352,22 @@
names.add(AttributeState.VARIANT_STRING);
} else {
// Read names until we see a ','
+ boolean foundComma = false;
+ boolean saveComma = false;
+
do {
- names.add(parseName(tokens));
- } while (tokens.canConsume(','));
+ if (tokens.matches(CndTokenizer.COMMENT)) {
+ parseComment(tokens);
+ saveComma = true;
+ } else {
+ names.add(parseName(tokens));
+ saveComma = false;
+ }
+
+ if (!saveComma) {
+ foundComma = tokens.matches(',');
+ }
+ } while (tokens.canConsume(',') ||
tokens.matches(CndTokenizer.COMMENT) || foundComma);
}
return names;
@@ -415,6 +472,8 @@
} else if (tokens.matchesAnyOf(Utils.toUpperCase(OnParentVersion.toArray())))
{
final String opv = tokens.consume();
childNodeDefn.setOnParentVersion(opv);
+ } else if (tokens.matches(CndTokenizer.COMMENT)) {
+ parseComment(tokens);
} else if (tokens.canConsumeAnyOf("PRIMARYITEM",
"PRIMARY", "PRI", "!")) { //$NON-NLS-1$ //$NON-NLS-2$
//$NON-NLS-3$ //$NON-NLS-4$
if (!this.jcr170) {
final Position pos = tokens.previousPosition();
@@ -493,6 +552,8 @@
} else {
nodeTypeDefn.setPrimaryItemName(removeQuotes(tokens.consume()));
}
+ } else if (tokens.matches(CndTokenizer.COMMENT)) {
+ parseComment(tokens);
} else {
// No more valid options on the stream, so stop ...
break;
@@ -524,6 +585,8 @@
nodeType.setName(name);
}
+ parseComment(tokens); // comment before supertypes
+
// supertypes
final List<String> superTypes = parseSupertypes(tokens);
@@ -642,6 +705,8 @@
QueryOperators.NOTATION[NotationType.COMPRESSED_INDEX].toUpperCase(),
QueryOperators.NOTATION[NotationType.COMPACT_INDEX].toUpperCase())) {
parseQueryOperators(tokens, propDefn);
+ } else if (tokens.matches(CndTokenizer.COMMENT)) {
+ parseComment(tokens);
} else if (tokens.canConsumeAnyOf("PRIMARY", "PRI",
"!")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
// these keywords are no longer property attributes in JCR 2.0
if (!this.jcr170) {
@@ -731,7 +796,18 @@
} else if (tokens.matches(ChildNodeDefinition.NOTATION_PREFIX)) {
parseChildNodeDefinition(tokens, nodeTypeDefn);
} else if (tokens.matches(CndTokenizer.COMMENT)) {
- parseComment(tokens);
+ if (parseComment(tokens) && (this.previousElement != null)) {
+ String comment = this.previousElement.getComment();
+
+ if (comment == null) {
+ comment = Utils.EMPTY_STRING;
+ } else if (!comment.endsWith("\n")) { //$NON-NLS-1$
+ comment += '\n';
+ }
+
+ this.previousElement.setComment(comment + this.currentComment);
+ this.currentComment = null;
+ }
} else {
// The next token does not signal either one of these, so stop ...
break;
@@ -751,6 +827,8 @@
assert (tokens != null) : "tokens is null"; //$NON-NLS-1$
assert (propDefn != null) : "propDefn is null"; //$NON-NLS-1$
+ parseComment(tokens);
+
if (tokens.canConsume(PropertyType.NOTATION_PREFIX)) {
// Parse the (optional) property type ...
if (tokens.matchesAnyOf(Utils.toUpperCase(PropertyType.validValues()))) {
@@ -777,6 +855,8 @@
if (tokens.canConsume(AttributeState.VARIANT_CHAR)) {
propDefn.changeState(PropertyDefinition.PropertyName.QUERY_OPS,
Value.VARIANT);
} else {
+ parseComment(tokens);
+
// The query operators are expected to be enclosed in a single quote, so
therefore will be a single token ...
final String operatorList = removeQuotes(tokens.consume());
final List<String> operators = new ArrayList<String>();
@@ -811,6 +891,8 @@
assert (tokens != null) : "tokens is null"; //$NON-NLS-1$
assert (childNodeDefn != null) : "childNodeDefn is null";
//$NON-NLS-1$
+ parseComment(tokens);
+
if (tokens.canConsume(RequiredTypes.NOTATION_PREFIX)) {
final List<String> requiredTypeNames = parseNameList(tokens);
@@ -845,9 +927,25 @@
strings.add(AttributeState.VARIANT_STRING);
} else {
// Read names until we see a ','
+ boolean foundComma = false;
+ boolean saveComma = false;
+ boolean firstTime = true;
+
do {
- strings.add(removeQuotes(tokens.consume()));
- } while (tokens.canConsume(','));
+ if (tokens.matches(CndTokenizer.COMMENT)) {
+ parseComment(tokens);
+ saveComma = true;
+ } else if (firstTime || foundComma) {
+ strings.add(removeQuotes(tokens.consume()));
+ saveComma = false;
+ }
+
+ if (!saveComma) {
+ foundComma = tokens.matches(',');
+ }
+
+ firstTime = false;
+ } while (tokens.canConsume(',') || parseComment(tokens) ||
foundComma);
}
return strings;
@@ -863,6 +961,8 @@
private List<String> parseSupertypes( final TokenStream tokens ) {
assert (tokens != null) : "tokens is null"; //$NON-NLS-1$
+ parseComment(tokens);
+
if (tokens.canConsume(SuperTypes.NOTATION_PREFIX)) {
// There is at least one supertype ...
return parseNameList(tokens);
@@ -899,40 +999,26 @@
}
private CndElement pop() {
- return this.cndElements.pop();
+ this.previousElement = this.cndElements.pop();
+ return this.previousElement;
}
- private void push( final CndElement cndElement ) {
+ private void push( final CommentedCndElement commentedElement ) {
// set comment if one exists
if (!Utils.isEmpty(this.currentComment)) {
- CommentedCndElement commentedElement = null;
+ String cndElementComment = commentedElement.getComment();
- if (cndElement instanceof CommentedCndElement) {
- commentedElement = (CommentedCndElement)cndElement;
- } else if (!this.cndElements.isEmpty()) {
- // this should probably look back in the stack until it finds a
CommentedCndElement
- CndElement top = this.cndElements.peek();
-
- if (top instanceof CommentedCndElement) {
- commentedElement = (CommentedCndElement)top;
- }
+ if (cndElementComment == null) {
+ cndElementComment = Utils.EMPTY_STRING;
+ } else if (!cndElementComment.endsWith("\n")) { //$NON-NLS-1$
+ cndElementComment += '\n';
}
- if (commentedElement != null) {
- String cndElementComment = commentedElement.getComment();
-
- if (cndElementComment == null) {
- cndElementComment = Utils.EMPTY_STRING;
- } else if (!cndElementComment.endsWith("\n")) { //$NON-NLS-1$
- cndElementComment += '\n';
- }
-
- commentedElement.setComment(cndElementComment + this.currentComment);
- this.currentComment = null;
- }
+ commentedElement.setComment(cndElementComment + this.currentComment);
+ this.currentComment = null;
}
- this.cndElements.push(cndElement);
+ this.cndElements.push(commentedElement);
}
private final String removeQuotes( final String text ) {
Modified:
trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/CndImporterTest.java
===================================================================
---
trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/CndImporterTest.java 2012-04-25
20:03:22 UTC (rev 40500)
+++
trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/CndImporterTest.java 2012-04-25
20:39:45 UTC (rev 40501)
@@ -26,6 +26,7 @@
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.version.OnParentVersionAction;
+import org.jboss.tools.modeshape.jcr.ChildNodeDefinition;
import org.jboss.tools.modeshape.jcr.NamespaceMapping;
import org.jboss.tools.modeshape.jcr.NodeTypeDefinition;
import org.jboss.tools.modeshape.jcr.PropertyDefinition;
@@ -388,6 +389,75 @@
}
@Test
+ public void shouldImportCndForCommentsTest() throws Exception {
+ final CompactNodeTypeDefinition cnd =
this.importer.importFrom(openCndFile("commentsTest.cnd"), this.problems);
//$NON-NLS-1$
+ final NodeTypeDefinition nodeType = cnd.getNodeTypeDefinitions().get(0);
+
+ if (this.problems.size() != 0) {
+ printProblems();
+ }
+
+ assertEquals(0, this.problems.size());
+
+ { // check node type comments
+ final String expected = "comment above node type\n" + "comment
same line as node type name\n" + "comment above supertypes\n" //$NON-NLS-1$
//$NON-NLS-2$ //$NON-NLS-3$
+ + "comment same line as first supertype\n" + "comment
between 2 supertypes\n" //$NON-NLS-1$ //$NON-NLS-2$
+ + "comment same line as last supertype\n" + "comment
above node type attributes\n" //$NON-NLS-1$ //$NON-NLS-2$
+ + "comment same line as abstract node type attribute\n"
//$NON-NLS-1$
+ + "comment between abstract and orderable node type
attributes\n" //$NON-NLS-1$
+ + "comment same line as orderable node type attribute\n"
//$NON-NLS-1$
+ + "comment between orderable and mixin node type
attributes\n" //$NON-NLS-1$
+ + "comment same line as mixin node type attribute\n"
//$NON-NLS-1$
+ + "comment between mixin and noquery node type
attributes\n" //$NON-NLS-1$
+ + "comment same line as noquery node type attribute\n"
//$NON-NLS-1$
+ + "comment between noquery and primaryitem node type
attributes\n" //$NON-NLS-1$
+ + "comment same line as primaryitem node type attribute";
//$NON-NLS-1$
+ assertEquals(expected, nodeType.getComment());
+ }
+
+ { // check property comments
+ final PropertyDefinition property =
nodeType.getPropertyDefinitions().get(0);
+ final String expected = "comment above property\n" + "comment
same line as property name\n" + "comment above property type\n"
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ + "comment above default values\n" + "comment same
line as first default value\n" //$NON-NLS-1$ //$NON-NLS-2$
+ + "comment between default values\n" + "comment same
line as last default value\n" //$NON-NLS-1$ //$NON-NLS-2$
+ + "comment above property attributes\n" + "comment
same line as mandatory property attribute\n" //$NON-NLS-1$ //$NON-NLS-2$
+ + "comment between mandatory and autocreated property
attributes\n" //$NON-NLS-1$
+ + "comment same line as autocreated property attribute\n"
//$NON-NLS-1$
+ + "comment between autocreated and protected property
attributes\n" //$NON-NLS-1$
+ + "comment same line as protected property attribute\n"
//$NON-NLS-1$
+ + "comment between protected and multiple property
attributes\n" //$NON-NLS-1$
+ + "comment same line as multiple property attribute\n"
//$NON-NLS-1$
+ + "comment between multiple and VERSION property
attributes\n" //$NON-NLS-1$
+ + "comment same line as VERSION property attribute\n"
//$NON-NLS-1$
+ + "comment between VERSION and queryops property
attributes\n" //$NON-NLS-1$
+ + "comment same line as queryops property attribute\n"
//$NON-NLS-1$
+ + "comment between queryops and nofulltext property
attributes\n" //$NON-NLS-1$
+ + "comment same line as nofulltext property attribute\n"
//$NON-NLS-1$
+ + "comment between nofulltext and noqueryorder property
attributes\n" //$NON-NLS-1$
+ + "comment same line as noqueryorder property attribute\n"
+ "comment above value constraints\n" //$NON-NLS-1$ //$NON-NLS-2$
+ + "comment same line as first value constraint\n" +
"comment between value constraints\n" //$NON-NLS-1$ //$NON-NLS-2$
+ + "comment same line as last value constraint";
//$NON-NLS-1$
+ assertEquals(expected, property.getComment());
+ }
+
+ { // check child node comments
+ final ChildNodeDefinition childNode =
nodeType.getChildNodeDefinitions().get(0);
+ final String expected = "comment above child node\n" +
"comment same line as child node name\n" //$NON-NLS-1$ //$NON-NLS-2$
+ + "comment above required types\n" + "comment same
line as required types\n" + "comment above default type\n" //$NON-NLS-1$
//$NON-NLS-2$ //$NON-NLS-3$
+ + "comment same line as default type\n" + "comment
above child node attributes\n" //$NON-NLS-1$ //$NON-NLS-2$
+ + "comment same line as mandatory child node attribute\n"
//$NON-NLS-1$
+ + "comment between mandatory and autocreated child node
attributes\n" //$NON-NLS-1$
+ + "comment same line as autocreated child node attribute\n"
//$NON-NLS-1$
+ + "comment between autocreated and protected child node
attributes\n" //$NON-NLS-1$
+ + "comment same line as protected child node attribute\n"
//$NON-NLS-1$
+ + "comment between protected and sns child node
attributes\n" //$NON-NLS-1$
+ + "comment same line as sns child node attribute\n" +
"comment between sns and version child node attributes\n" //$NON-NLS-1$
//$NON-NLS-2$
+ + "comment same line as version child node attribute";
//$NON-NLS-1$
+ assertEquals(expected, childNode.getComment());
+ }
+ }
+
+ @Test
public void shouldImportCndForImageSequencer() throws Exception {
this.importer.importFrom(openCndFile("images.cnd"), this.problems);
//$NON-NLS-1$
Modified: trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/testdata/aircraft.cnd
===================================================================
---
trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/testdata/aircraft.cnd 2012-04-25
20:03:22 UTC (rev 40500)
+++
trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/testdata/aircraft.cnd 2012-04-25
20:39:45 UTC (rev 40501)
@@ -59,6 +59,6 @@
< '\d{1,3}(,?\d{3})*\s*(lb|kg|gal|L)' // followed by
'lb', 'kg', 'gal', or 'L'
- air:crew (long) < '[0,)' // any
non-negative value
- air:numberBuilt (string) // any integer (with optional
',' every 1000s place)
- < '\d{1,3}(,?\d{3})*\s*[+]?' ,
- '([<>]\s*)?\d{1,3}(,?\d{3})*' // optionally
followed by '+' or prefixed by '<' or '>'
+ < '\d{1,3}(,?\d{3})*\s*[+]?' , // optionally
followed by '+'
+ '([<>]\s*)?\d{1,3}(,?\d{3})*' // or prefixed
by '<' or '>'
- air:url (string)
\ No newline at end of file
Added: trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/testdata/commentsTest.cnd
===================================================================
--- trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/testdata/commentsTest.cnd
(rev 0)
+++
trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/testdata/commentsTest.cnd 2012-04-25
20:39:45 UTC (rev 40501)
@@ -0,0 +1,84 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * See the LEGAL.txt file distributed with this work for information regarding copyright
ownership and licensing.
+ *
+ * See the AUTHORS.txt file distributed with this work for a full listing of individual
contributors.
+ */
+<ex = 'http://namespace.com/ns'>
+
+// comment above node type
+[ex:NodeType] // comment same line as node type name
+
+// comment above supertypes
+> ex:ParentType1, // comment same line as first supertype
+
+// comment between 2 supertypes
+ex:ParentType2 // comment same line as last supertype
+
+// comment above node type attributes
+abstract // comment same line as abstract node type attribute
+// comment between abstract and orderable node type attributes
+orderable // comment same line as orderable node type attribute
+// comment between orderable and mixin node type attributes
+mixin // comment same line as mixin node type attribute
+// comment between mixin and noquery node type attributes
+noquery // comment same line as noquery node type attribute
+// comment between noquery and primaryitem node type attributes
+primaryitem ex:property // comment same line as primaryitem node type attribute
+
+// comment above property
+- ex:property // comment same line as property name
+
+// comment above property type
+(STRING)
+
+// comment above default values
+= 'default1', // comment same line as first default value
+
+// comment between default values
+'default2' // comment same line as last default value
+
+// comment above property attributes
+mandatory // comment same line as mandatory property attribute
+// comment between mandatory and autocreated property attributes
+autocreated // comment same line as autocreated property attribute
+// comment between autocreated and protected property attributes
+protected // comment same line as protected property attribute
+// comment between protected and multiple property attributes
+multiple // comment same line as multiple property attribute
+// comment between multiple and VERSION property attributes
+VERSION // comment same line as VERSION property attribute
+// comment between VERSION and queryops property attributes
+queryops '=, <>, <, <=, >, >=, LIKE' // comment same line as
queryops property attribute
+// comment between queryops and nofulltext property attributes
+nofulltext // comment same line as nofulltext property attribute
+// comment between nofulltext and noqueryorder property attributes
+noqueryorder // comment same line as noqueryorder property attribute
+
+// comment above value constraints
+< 'constraint1', // comment same line as first value constraint
+
+// comment between value constraints
+'constraint2' // comment same line as last value constraint
+
+// comment above child node
++ ex:node // comment same line as child node name
+
+// comment above required types
+(ex:reqType1, ex:reqType2) // comment same line as required types
+
+// comment above default type
+= ex:defaultType // comment same line as default type
+
+// comment above child node attributes
+mandatory // comment same line as mandatory child node attribute
+// comment between mandatory and autocreated child node attributes
+autocreated // comment same line as autocreated child node attribute
+// comment between autocreated and protected child node attributes
+protected // comment same line as protected child node attribute
+// comment between protected and sns child node attributes
+sns // comment same line as sns child node attribute
+// comment between sns and version child node attributes
+version // comment same line as version child node attribute
+
\ No newline at end of file