[dna-commits] DNA SVN: r284 - in trunk: sequencers and 17 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Fri Jun 13 10:13:50 EDT 2008


Author: elvisisking
Date: 2008-06-13 10:13:50 -0400 (Fri, 13 Jun 2008)
New Revision: 284

Added:
   trunk/sequencers/dna-sequencer-cnd/
   trunk/sequencers/dna-sequencer-cnd/.classpath
   trunk/sequencers/dna-sequencer-cnd/.project
   trunk/sequencers/dna-sequencer-cnd/pom.xml
   trunk/sequencers/dna-sequencer-cnd/src/
   trunk/sequencers/dna-sequencer-cnd/src/main/
   trunk/sequencers/dna-sequencer-cnd/src/main/antlr/
   trunk/sequencers/dna-sequencer-cnd/src/main/antlr/org/
   trunk/sequencers/dna-sequencer-cnd/src/main/antlr/org/jboss/
   trunk/sequencers/dna-sequencer-cnd/src/main/antlr/org/jboss/dna/
   trunk/sequencers/dna-sequencer-cnd/src/main/antlr/org/jboss/dna/sequencer/
   trunk/sequencers/dna-sequencer-cnd/src/main/antlr/org/jboss/dna/sequencer/cnd/
   trunk/sequencers/dna-sequencer-cnd/src/main/antlr/org/jboss/dna/sequencer/cnd/Cnd.g
   trunk/sequencers/dna-sequencer-cnd/src/main/java/
   trunk/sequencers/dna-sequencer-cnd/src/main/resources/
   trunk/sequencers/dna-sequencer-cnd/src/test/
   trunk/sequencers/dna-sequencer-cnd/src/test/java/
   trunk/sequencers/dna-sequencer-cnd/src/test/java/org/
   trunk/sequencers/dna-sequencer-cnd/src/test/java/org/jboss/
   trunk/sequencers/dna-sequencer-cnd/src/test/java/org/jboss/dna/
   trunk/sequencers/dna-sequencer-cnd/src/test/java/org/jboss/dna/sequencer/
   trunk/sequencers/dna-sequencer-cnd/src/test/java/org/jboss/dna/sequencer/cnd/
   trunk/sequencers/dna-sequencer-cnd/src/test/java/org/jboss/dna/sequencer/cnd/CndParseFilesTest.java
   trunk/sequencers/dna-sequencer-cnd/src/test/java/org/jboss/dna/sequencer/cnd/CndParserTest.java
   trunk/sequencers/dna-sequencer-cnd/src/test/resources/
   trunk/sequencers/dna-sequencer-cnd/src/test/resources/builtin_nodetypes.cnd
   trunk/sequencers/dna-sequencer-cnd/src/test/resources/empty.cnd
   trunk/sequencers/dna-sequencer-cnd/src/test/resources/images.cnd
   trunk/sequencers/dna-sequencer-cnd/src/test/resources/invalid.cnd
   trunk/sequencers/dna-sequencer-cnd/src/test/resources/mp3.cnd
Modified:
   trunk/pom.xml
Log:
DNA-73 Added CND Sequencer project, still incomplete

Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml	2008-06-13 13:49:24 UTC (rev 283)
+++ trunk/pom.xml	2008-06-13 14:13:50 UTC (rev 284)
@@ -63,6 +63,7 @@
 		<module>sequencers/dna-sequencer-images</module>
 		<module>sequencers/dna-sequencer-mp3</module>
 		<!--module>sequencers/dna-sequencer-esbMessage</module-->
+		<module>sequencers/dna-sequencer-cnd</module>
 		<module>connectors/dna-connector-jbosscache</module>
     	<module>dna-integration-tests</module>
 	</modules>


Property changes on: trunk/sequencers/dna-sequencer-cnd
___________________________________________________________________
Name: svn:ignore
   + target


Added: trunk/sequencers/dna-sequencer-cnd/.classpath
===================================================================
--- trunk/sequencers/dna-sequencer-cnd/.classpath	                        (rev 0)
+++ trunk/sequencers/dna-sequencer-cnd/.classpath	2008-06-13 14:13:50 UTC (rev 284)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+	<classpathentry kind="src" path="target/generated-sources/antlr"/>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
+	<classpathentry kind="src" path="src/main/resources"/>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry kind="src" path="src/main/antlr"/>
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

Added: trunk/sequencers/dna-sequencer-cnd/.project
===================================================================
--- trunk/sequencers/dna-sequencer-cnd/.project	                        (rev 0)
+++ trunk/sequencers/dna-sequencer-cnd/.project	2008-06-13 14:13:50 UTC (rev 284)
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>dna-sequencer-cnd</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.antlr.eclipse.core.warningcleanerbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.antlr.eclipse.core.smapbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+	</natures>
+</projectDescription>

Added: trunk/sequencers/dna-sequencer-cnd/pom.xml
===================================================================
--- trunk/sequencers/dna-sequencer-cnd/pom.xml	                        (rev 0)
+++ trunk/sequencers/dna-sequencer-cnd/pom.xml	2008-06-13 14:13:50 UTC (rev 284)
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <parent>
+    <artifactId>dna</artifactId>
+    <groupId>org.jboss.dna</groupId>
+    <version>0.2-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.jboss.dna</groupId>
+  <artifactId>dna-sequencer-cnd</artifactId>
+  <name>JBoss DNA CND Sequencer</name>
+  <version>0.2-SNAPSHOT</version>
+  <description>JBoss DNA Sequencer that processes JCR CND files</description>
+  <dependencies>
+    <dependency>
+      <groupId>org.jboss.dna</groupId>
+      <artifactId>dna-common</artifactId>
+      <version>0.2-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.dna</groupId>
+      <artifactId>dna-spi</artifactId>
+      <version>0.2-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.antlr</groupId>
+      <artifactId>antlr-runtime</artifactId>
+      <version>3.0.1</version>
+    </dependency>
+    
+    <!-- Testing -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-library</artifactId>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>antlr3-maven-plugin</artifactId>
+        <version>1.0</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>antlr</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file

Added: trunk/sequencers/dna-sequencer-cnd/src/main/antlr/org/jboss/dna/sequencer/cnd/Cnd.g
===================================================================
--- trunk/sequencers/dna-sequencer-cnd/src/main/antlr/org/jboss/dna/sequencer/cnd/Cnd.g	                        (rev 0)
+++ trunk/sequencers/dna-sequencer-cnd/src/main/antlr/org/jboss/dna/sequencer/cnd/Cnd.g	2008-06-13 14:13:50 UTC (rev 284)
@@ -0,0 +1,390 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+grammar Cnd;
+
+options {//	backtrack=true;
+//			memoize=true;
+			output=AST;
+		}
+
+tokens {
+	COMMA = ',';
+	DASH = '-';
+	DOT = '.';
+	EQUALS = '=';
+	EXCLAMATION = '!';
+	GREATER_THAN = '>';
+	LEFT_BRACKET = '[';
+	LEFT_PAREN = '(';
+	LESS_THAN = '<';
+	PLUS = '+';
+	RIGHT_BRACKET = ']';
+	RIGHT_PAREN = ')';
+	SINGLE_QUOTE = '\'';
+	SLASH = '/';
+	STAR = '*';
+	
+	ATTRIBUTES;
+	COMMENTS;
+	DEFAULT_TYPE;
+	DEFAULT_VALUES;
+	JCR_NAME;
+	NAME;
+	NAMESPACES;
+	CHILD_NODE_DEFINITION;
+	CHILD_NODE_DEFINITIONS;
+	NODE_TYPE_DEFINITION;
+	NODE_TYPE_DEFINITIONS;
+	NODE_TYPE_OPTIONS;
+	PROPERTIES;
+	PROPERTY_DEFINITION;
+	PROPERTY_TYPE;
+	REQUIRED_TYPES;
+	SUPERTYPES;
+	VALUE_CONSTRAINTS;
+}
+
+ at header {package org.jboss.dna.sequencer.cnd;}
+
+ at lexer::header {package org.jboss.dna.sequencer.cnd;}
+
+// Make the parser exit immediately upon recognition error by overriding the following two methods,
+// and by altering how the parser responds to thrown exceptions.
+ at members {
+    /**
+     * Make the parser exit immediately upon a recognition error by throwing an exception after a mismatch.
+     */
+    @Override
+    protected void mismatch( IntStream input, int ttype, BitSet follow ) throws RecognitionException {
+        throw new MismatchedTokenException(ttype,input);
+    }
+    
+    /**
+     * Make the parser exit immediately upon a recognition error by not recovering from a mismatched set.
+     */
+    @Override
+    public void recoverFromMismatchedSet( IntStream input, RecognitionException e, BitSet follow ) throws RecognitionException {
+        throw e;
+    }
+}
+
+/*-----------------------------------------------------------------------------
+ * PARSER RULES
+ *---------------------------------------------------------------------------*/
+
+cnd
+	:	(	comment
+			| ns_mapping
+			| node_type_def
+		)*
+		
+	->	^(COMMENTS comment*)?
+		^(NAMESPACES ns_mapping*)?
+		^(NODE_TYPE_DEFINITIONS node_type_def*)?
+	;
+
+comment
+	: 	SINGLE_LINE_COMMENT
+		| MULTI_LINE_COMMENT
+	;
+
+ns_mapping
+	: NAMESPACE_MAPPING
+	;
+
+node_type_def
+	: 	(	node_type_name
+			supertypes?
+			node_type_options?
+			(	property_def
+				| child_node_def
+			)*
+		)
+		
+	->	^(	NODE_TYPE_DEFINITION 
+			^(JCR_NAME node_type_name)
+			^(SUPERTYPES supertypes)?
+			^(NODE_TYPE_OPTIONS node_type_options)?
+			^(PROPERTIES property_def*)?
+			^(CHILD_NODE_DEFINITIONS child_node_def*)?
+		)
+	;
+
+node_type_name
+	: 	(	LEFT_BRACKET
+			string
+			RIGHT_BRACKET
+		)
+		
+	-> string
+	;
+
+supertypes
+	:	(	GREATER_THAN
+			string_list
+		)
+		
+	-> string_list
+	;
+
+fragment
+node_type_options
+	:	(abs_opt ord_mix_opt?)
+		| (ord_mix_opt abs_opt?)
+	;
+
+fragment
+abs_opt
+	:	'abstract'
+		| 'abs'
+		| 'a'
+	;
+
+fragment
+ord_mix_opt 
+	:	(orderable_opt mixin_opt?)
+		| (mixin_opt orderable_opt?)
+	;
+
+fragment
+orderable_opt
+	:	'orderable'
+		| 'ord'
+		| 'o'
+	;
+
+fragment
+mixin_opt
+	:	'mixin'
+		| 'mix'
+		| 'm'
+	;
+
+
+property_def
+	: 	(	DASH
+			jcr_name
+			property_type_decl?
+			default_values?
+			attributes*
+			value_constraints?
+		)
+		
+	->	^(	PROPERTY_DEFINITION
+			^(JCR_NAME jcr_name)
+			^(PROPERTY_TYPE property_type_decl)?
+			^(DEFAULT_VALUES default_values)?
+			^(ATTRIBUTES attributes*)?
+			^(VALUE_CONSTRAINTS value_constraints)?
+		)
+	;
+
+child_node_def
+	:	PLUS
+		jcr_name
+		required_types?
+		default_type?
+		attributes?
+
+	->	^(	CHILD_NODE_DEFINITION
+			^(JCR_NAME jcr_name)
+			^(REQUIRED_TYPES required_types)?
+			^(DEFAULT_TYPE default_type)?
+			^(ATTRIBUTES attributes*)?
+		)
+	;
+
+fragment
+jcr_name
+	: 	string
+		| STAR
+	;
+
+fragment
+property_type_decl
+	: 	LEFT_PAREN
+		property_type
+		RIGHT_PAREN
+	
+	-> property_type
+	;
+
+fragment
+property_type
+	: 	'BINARY' | 'Binary' | 'binary'
+		| 'BOOLEAN' | 'Boolean' | 'boolean'
+		| 'DATE' | 'Date' | 'date'
+		| 'DECIMAL' | 'Decimal' | 'decimal'
+		| 'DOUBLE' | 'Double' | 'double'
+		| 'LONG' | 'Long' | 'long'
+		| 'NAME' | 'Name' | 'name'
+		| 'PATH' | 'Path' | 'path'
+		| 'REFERENCE' | 'Reference' | 'reference'
+		| 'STRING' | 'String' | 'string'
+		| 'UNDEFINED' | 'Undefined' | 'undefined'
+		| 'URI' | 'Uri' | 'uri'
+		| 'WEAKREFERENCE' | 'WeakReference' | 'weakreference'
+		| STAR
+	;
+
+fragment
+default_values
+	:	EQUALS
+		string_list
+		
+	->	string_list
+	;
+
+fragment
+value_constraints
+	:	LESS_THAN
+		string_list
+
+	-> string_list
+	;
+
+fragment
+required_types
+	:	LEFT_PAREN
+		string_list
+		RIGHT_PAREN
+		
+	-> string_list
+	;
+
+fragment
+default_type
+	: 	EQUALS
+		string
+		
+	-> string
+	;
+
+fragment
+attributes
+	:	'ABORT' | 'Abort' | 'abort'
+		| 'autocreated' | 'aut' | 'a'
+		| 'COMPUTE' | 'Compute' | 'compute'
+		| 'COPY' | 'Copy' | 'copy'
+		| 'IGNORE' | 'Ignore' | 'ignore'
+		| 'INITIALIZE' | 'Initialize' | 'initialize'
+		| 'mandatory' | 'man' | 'm'
+		| 'multiple' | 'mul' | STAR
+		| 'primary' | 'pri' | EXCLAMATION
+		| 'protected' | 'pro' | 'p'
+		| 'VERSION' | 'Version' | 'version'
+	;
+
+fragment
+string
+	:	QUOTED_STRING
+		| UNQUOTED_STRING
+	;
+
+fragment
+string_list
+	: 	string
+		(	COMMA
+			string
+		)*
+		
+	-> string+
+	;
+
+fragment
+uri_string 
+	:	QUOTED_URI_STRING
+		| UNQUOTED_URI_STRING
+	;
+
+/*-----------------------------------------------------------------------------
+ * LEXER RULES
+ *---------------------------------------------------------------------------*/
+
+MULTI_LINE_COMMENT
+    :   (	'/*'
+    		( options {greedy=false;} : . )*
+    		'*/'
+    	)
+    ;
+
+NAMESPACE_MAPPING
+	: 	(	LESS_THAN
+			(QUOTED_STRING | UNQUOTED_STRING)
+			EQUALS
+			(QUOTED_URI_STRING | UNQUOTED_URI_STRING)
+			GREATER_THAN
+		)
+	;
+
+QUOTED_STRING
+	:	(	SINGLE_QUOTE
+			UNQUOTED_STRING
+			SINGLE_QUOTE
+		)
+	;
+
+
+QUOTED_URI_STRING
+	:	(	SINGLE_QUOTE
+			UNQUOTED_URI_STRING
+			SINGLE_QUOTE
+		)
+	;
+
+SINGLE_LINE_COMMENT
+    : 	'//'
+    	~('\n' | '\r')*
+    ;
+
+
+UNQUOTED_STRING
+	: 	(	'a' .. 'z'
+			| 'A' .. 'Z'
+			| '0' .. '9'
+			| ':'
+			| '_'
+		)+
+	;
+
+fragment
+URI_SPECIAL_CHARS
+	:	SLASH
+		| DOT
+	;
+
+
+UNQUOTED_URI_STRING
+	: 	(	UNQUOTED_STRING
+			| URI_SPECIAL_CHARS
+		)+
+	;
+
+WS
+	:	(	' '
+			| '\r'
+			|'\t'
+			|'\u000C'
+			|'\n'
+		)+
+		{$channel=HIDDEN;}
+	;

Added: trunk/sequencers/dna-sequencer-cnd/src/test/java/org/jboss/dna/sequencer/cnd/CndParseFilesTest.java
===================================================================
--- trunk/sequencers/dna-sequencer-cnd/src/test/java/org/jboss/dna/sequencer/cnd/CndParseFilesTest.java	                        (rev 0)
+++ trunk/sequencers/dna-sequencer-cnd/src/test/java/org/jboss/dna/sequencer/cnd/CndParseFilesTest.java	2008-06-13 14:13:50 UTC (rev 284)
@@ -0,0 +1,365 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.sequencer.cnd;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.junit.Assert.assertThat;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import org.antlr.runtime.ANTLRInputStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RuleReturnScope;
+import org.antlr.runtime.tree.Tree;
+import org.junit.After;
+import org.junit.Test;
+
+public class CndParseFilesTest {
+
+    /*
+     * AST looks like this:
+     * 
+     * root (nil)
+     *      COMMENTS (*)
+     *           comment-1
+     *           comment-2
+     *           ...
+     *      NAMESPACES (*)
+     *           namespace_mapping-1
+     *           namespace_mapping-2
+     *           ...
+     *      NODE_TYPE_DEFINITIONS (*)
+     *           NODE_TYPE_DEFINITION
+     *                JCR_NAME
+     *                     node_type_definition_name-1
+     *                SUPERTYPES (*)
+     *                     supertype-1
+     *                     supertype-2
+     *                     ...
+     *                NODE_TYPE_OPTIONS (*)
+     *                     option-1
+     *                     option-2
+     *                     ...
+     *                PROPERTIES (*)
+     *                     PROPERTY_DEFINITION
+     *                          JCR_NAME
+     *                               property_name-1
+     *                          PROPERTY_TYPE (*)
+     *                               property type
+     *                          ATTRIBUTES (*)
+     *                               attribute-1
+     *                               attribute-2
+     *                               ...
+     *                     PROPERTY_DEFINITION
+     *                          JCR_NAME
+     *                               property_name-2
+     *                          ...
+     *                     ...
+     *                CHILD_NODE_DEFINTIONS (*)
+     *                     CHILD_NODE_DEFINTION
+     *                          JCR_NAME
+     *                              child_node_name-1
+     *                          REQUIRED_TYPES (*)
+     *                              required_type-1
+     *                              required_type-2
+     *                              ...
+     *                          DEFAULT_TYPE (*)
+     *                              default_type
+     *                          ATTRIBUTES (*)
+     *                              attribute-1
+     *                              attribute-2
+     *                              ...
+     *                     CHILD_NODE_DEFINTION
+     *                          JCR_NAME
+     *                              child_node_name-2
+     *                          ...
+     *                     ...
+     *           NODE_TYPE_DEFINITION
+     *                JCR_NAME
+     *                     node_type_definition_name-2
+     *                ...
+     *           ...
+     *           
+     *  Note: (*) indicates node only appears if a child node exists
+     */
+
+    // =============================================================================================================================
+    // Constants
+    // =============================================================================================================================
+    private static final String TEST_DATA_PATH = "./src/test/resources/";
+
+    private static final String BUILTIN_NODETYPES_CND = TEST_DATA_PATH + "builtin_nodetypes.cnd";
+    private static final String EMPTY_CND = TEST_DATA_PATH + "empty.cnd";
+    private static final String IMAGES_CND = TEST_DATA_PATH + "images.cnd";
+    private static final String INVALID_CND = TEST_DATA_PATH + "invalid.cnd";
+    private static final String MP3_CND = TEST_DATA_PATH + "mp3.cnd";
+
+    private static final int COMMENTS_INDEX = 0;
+    private static final int NAMESPACES_INDEX = 1;
+    private static final int NODE_TYPE_DEFINITIONS_INDEX = 2;
+    private static final int PROPERTIES_INDEX = 2;
+
+    // =============================================================================================================================
+    // Fields
+    // =============================================================================================================================
+
+    private InputStream stream;
+
+    // =============================================================================================================================
+    // Methods
+    // =============================================================================================================================
+
+    @After
+    public void afterEach() throws IOException {
+        if (this.stream != null) {
+            try {
+                this.stream.close();
+            } finally {
+                this.stream = null;
+            }
+        }
+    }
+
+    private void assertCommentsCount( Tree root,
+                                      int count ) {
+        Tree comments = root.getChild(COMMENTS_INDEX);
+        assertThat("Tree type was not CndParser.COMMENTS", comments.getType(), is(CndParser.COMMENTS));
+
+        // make sure right number of comments
+        assertThat("Incorrect number of comments", comments.getChildCount(), is(count));
+    }
+
+    private void assertNamespacesCount( Tree root,
+                                        int count ) {
+        Tree namespaces = getNamespaces(root);
+        assertThat("Incorrect number of namespaces", namespaces.getChildCount(), is(count));
+    }
+
+    private void assertNodeTypeDefinitionsCount( Tree root,
+                                                 int count ) {
+        Tree nodeTypeDefinitions = getNodeTypeDefinitions(root);
+        assertThat("Incorrect number of node type definitions", nodeTypeDefinitions.getChildCount(), is(count));
+    }
+
+    private void assertNodeTypeDefinitionsPropertiesCount( Tree root,
+                                                           int nodeTypeDefinitionIndex,
+                                                           int count ) {
+        Tree nodeTypeDefinitions = getNodeTypeDefinitions(root);
+
+        Tree nodeType = nodeTypeDefinitions.getChild(nodeTypeDefinitionIndex);
+        assertThat("Tree type was not CndParser.NODE_TYPE_DEFINITION", nodeType.getType(), is(CndParser.NODE_TYPE_DEFINITION));
+
+        Tree properties = nodeType.getChild(PROPERTIES_INDEX); // properties container node
+        assertThat("Tree type was not CndParser.PROPERTIES", properties.getType(), is(CndParser.PROPERTIES));
+
+        // make sure right number of properties
+        assertThat("Incorrect number of node type properties for first node type", properties.getChildCount(), is(count));
+    }
+
+    private CndParser createParser( File file ) throws IOException {
+        afterEach(); // make sure previous stream is closed
+        assertThat('\'' + file.getAbsolutePath() + "' does not exist", file.exists(), is(true));
+
+        this.stream = new FileInputStream(file);
+        CndLexer lexer = new CndLexer(new ANTLRInputStream(this.stream));
+        CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+        return new CndParser(tokens);
+    }
+
+    /**
+     * @param root the AST root
+     * @return the NAMESPACES tree node
+     */
+    private Tree getNamespaces( Tree root ) {
+        Tree namespaces = root.getChild(NAMESPACES_INDEX);
+
+        if (namespaces != null) {
+            assertThat("Tree type was not CndParser.NAMESPACES", namespaces.getType(), is(CndParser.NAMESPACES));
+        }
+
+        return namespaces;
+    }
+
+    /**
+     * @param root the AST root
+     * @return the NODE_TYPE_DEFINITIONS tree node
+     */
+    private Tree getNodeTypeDefinitions( Tree root ) {
+        Tree nodeTypeDefinitions = root.getChild(NODE_TYPE_DEFINITIONS_INDEX);
+
+        if (nodeTypeDefinitions != null) {
+            assertThat("Tree type was not CndParser.NODE_TYPE_DEFINITIONS",
+                       nodeTypeDefinitions.getType(),
+                       is(CndParser.NODE_TYPE_DEFINITIONS));
+        }
+
+        return nodeTypeDefinitions;
+    }
+
+    /**
+     * @param fileName the name of the file to parse
+     * @return the root node of the AST
+     * @throws Exception if root is null
+     */
+    private Tree parse( String fileName ) throws Exception {
+        return parse(new File(fileName).getCanonicalFile());
+    }
+
+    /**
+     * @param file the file to parse
+     * @return the root node of the AST
+     * @throws Exception if root is null
+     */
+    private Tree parse( File file ) throws Exception {
+        CndParser parser = createParser(file);
+        RuleReturnScope result = parser.cnd();
+        Tree root = (Tree)result.getTree();
+        assertThat(root, notNullValue());
+
+        return root;
+    }
+
+    // =============================================================================================================================
+    // Tests
+    // =============================================================================================================================
+
+    @Test
+    public void shouldParseEmptyCnd() throws Exception {
+        Tree root = parse(EMPTY_CND);
+
+        // make sure no children
+        assertThat(root.getChildCount(), is(0));
+
+        // make sure nothing got parsed
+        assertThat(root.getTokenStartIndex(), is(-1));
+    }
+
+    @Test
+    public void shouldNotParseInvalidCnd() throws Exception {
+        Tree root = parse(INVALID_CND);
+
+        // make sure nothing got parsed
+        assertThat(root.getTokenStopIndex(), is(0));
+    }
+
+    // @Test
+    public void shouldParseBuiltinNodeTypesCndComments() throws Exception {
+        Tree root = parse(BUILTIN_NODETYPES_CND);
+        assertCommentsCount(root, 16);
+    }
+
+    @Test
+    public void shouldParseBuiltinNodeTypesCndNamespaces() throws Exception {
+        Tree root = parse(BUILTIN_NODETYPES_CND);
+        assertNamespacesCount(root, 4);
+    }
+
+    // @Test
+    public void shouldParseBuiltinNodeTypesCndNodeTypeDefinitions() throws Exception {
+        Tree root = parse(BUILTIN_NODETYPES_CND);
+
+        // make sure correct number of node type definitions
+        assertNodeTypeDefinitionsCount(root, 23);
+
+        // make sure right number of node type definitions for each node type
+        assertNodeTypeDefinitionsPropertiesCount(root, 0, 2); // [nt:base]
+        assertNodeTypeDefinitionsPropertiesCount(root, 1, 2); // [nt:unstructured]
+        assertNodeTypeDefinitionsPropertiesCount(root, 2, 1); // [mix:referenceable]
+        assertNodeTypeDefinitionsPropertiesCount(root, 3, 2); // [mix:lockable]
+        assertNodeTypeDefinitionsPropertiesCount(root, 4, 5); // [mix:versionable]
+        assertNodeTypeDefinitionsPropertiesCount(root, 5, 1); // [nt:versionHistory]
+        assertNodeTypeDefinitionsPropertiesCount(root, 6, 1); // [nt:versionLabels]
+        assertNodeTypeDefinitionsPropertiesCount(root, 7, 3); // [nt:version]
+        assertNodeTypeDefinitionsPropertiesCount(root, 8, 5); // [nt:frozenNode]
+        assertNodeTypeDefinitionsPropertiesCount(root, 9, 1); // [nt:versionedChild]
+        assertNodeTypeDefinitionsPropertiesCount(root, 10, 5); // [nt:nodeType]
+        assertNodeTypeDefinitionsPropertiesCount(root, 11, 9); // [nt:propertyDefinition]
+        assertNodeTypeDefinitionsPropertiesCount(root, 12, 8); // [nt:childNodeDefinition]
+        assertNodeTypeDefinitionsPropertiesCount(root, 13, 1); // [nt:hierarchyNode]
+        assertNodeTypeDefinitionsPropertiesCount(root, 14, 0); // [nt:folder]
+        assertNodeTypeDefinitionsPropertiesCount(root, 15, 0); // [nt:file]
+        assertNodeTypeDefinitionsPropertiesCount(root, 16, 1); // [nt:linkedFile]
+        assertNodeTypeDefinitionsPropertiesCount(root, 17, 4); // [nt:resource]
+        assertNodeTypeDefinitionsPropertiesCount(root, 18, 2); // [nt:query]
+        assertNodeTypeDefinitionsPropertiesCount(root, 19, 0); // [rep:nodeTypes]
+        assertNodeTypeDefinitionsPropertiesCount(root, 20, 0); // [rep:root]
+        assertNodeTypeDefinitionsPropertiesCount(root, 21, 0); // [rep:system]
+        assertNodeTypeDefinitionsPropertiesCount(root, 22, 0); // [rep:versionStorage]
+    }
+
+    @Test
+    public void shouldParseImagesCndComments() throws Exception {
+        Tree root = parse(IMAGES_CND);
+        assertCommentsCount(root, 11);
+    }
+
+    @Test
+    public void shouldParseImagesCndNamespaces() throws Exception {
+        Tree root = parse(IMAGES_CND);
+        assertNamespacesCount(root, 4);
+    }
+
+    @Test
+    public void shouldParseImagesCndNodeTypeDefinitions() throws Exception {
+        Tree root = parse(IMAGES_CND);
+
+        // make sure correct number of node type definitions
+        assertNodeTypeDefinitionsCount(root, 2);
+
+        // make sure right number of node type definitions for each node type
+        assertNodeTypeDefinitionsPropertiesCount(root, 0, 2); // [mix:mimeType]
+        assertNodeTypeDefinitionsPropertiesCount(root, 1, 10); // [image:metadata]
+    }
+
+    @Test
+    public void shouldParseMp3CndComments() throws Exception {
+        Tree root = parse(MP3_CND);
+
+        // this will be the COMMENTS imaginary container token
+        Tree comments = root.getChild(COMMENTS_INDEX);
+        assertThat("Tree type was not CndParser.COMMENTS", comments.getType(), is(CndParser.COMMENTS));
+
+        // make sure right number of comments
+        assertThat("Incorrect number of comments", comments.getChildCount(), is(10));
+    }
+
+    @Test
+    public void shouldParseMp3CndNamespaces() throws Exception {
+        Tree root = parse(MP3_CND);
+        assertNamespacesCount(root, 4);
+    }
+
+    @Test
+    public void shouldParseMp3CndNodeTypeDefinitions() throws Exception {
+        Tree root = parse(MP3_CND);
+
+        // make sure correct number of node type definitions
+        assertNodeTypeDefinitionsCount(root, 2);
+
+        // make sure right number of node type definitions for each node type
+        assertNodeTypeDefinitionsPropertiesCount(root, 0, 2); // [mix:mimeType]
+        assertNodeTypeDefinitionsPropertiesCount(root, 1, 5); // [mp3:metadata]
+    }
+}

Added: trunk/sequencers/dna-sequencer-cnd/src/test/java/org/jboss/dna/sequencer/cnd/CndParserTest.java
===================================================================
--- trunk/sequencers/dna-sequencer-cnd/src/test/java/org/jboss/dna/sequencer/cnd/CndParserTest.java	                        (rev 0)
+++ trunk/sequencers/dna-sequencer-cnd/src/test/java/org/jboss/dna/sequencer/cnd/CndParserTest.java	2008-06-13 14:13:50 UTC (rev 284)
@@ -0,0 +1,766 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.dna.sequencer.cnd;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.junit.Assert.assertThat;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import org.antlr.runtime.ANTLRInputStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RuleReturnScope;
+import org.antlr.runtime.tree.RewriteEmptyStreamException;
+import org.junit.After;
+import org.junit.Test;
+
+public class CndParserTest {
+
+    // =============================================================================================================================
+    // Fields
+    // =============================================================================================================================
+
+    private InputStream stream;
+
+    // =============================================================================================================================
+    // Methods
+    // =============================================================================================================================
+
+    @After
+    public void afterEach() throws IOException {
+        if (this.stream != null) {
+            try {
+                this.stream.close();
+            } finally {
+                this.stream = null;
+            }
+        }
+    }
+
+    private CndParser createParser( String input ) throws IOException {
+        afterEach(); // make sure previous stream is closed
+        this.stream = new ByteArrayInputStream(input.getBytes("UTF-8"));
+        CndLexer lexer = new CndLexer(new ANTLRInputStream(this.stream));
+        CommonTokenStream tokens = new CommonTokenStream(lexer);
+        return new CndParser(tokens);
+    }
+
+    // =============================================================================================================================
+    // Comment Parsing Tests
+    // =============================================================================================================================
+
+    private void parseComment( String option,
+                               boolean success ) throws Exception {
+        CndParser parser = createParser(option);
+        RuleReturnScope scope = parser.comment();
+
+        if (success) {
+            assertThat("Value '" + option + "' did not parse and should have", scope.getTree(), notNullValue());
+            assertThat(option, is(((org.antlr.runtime.tree.CommonTree)scope.getTree()).getText()));
+        } else {
+            assertThat("Value '" + option + "' should not parse and did", scope.getTree(), nullValue());
+        }
+    }
+
+    @Test
+    public void shouldParseSingleLineComment() throws Exception {
+        parseComment("// This is a single line comment", true);
+    }
+
+    @Test
+    public void shouldParseMultiLineComment() throws Exception {
+        parseComment("/* This\nis\na\nmulti-line\ncomment */", true);
+    }
+
+    @Test
+    public void shouldNotParseNonComment() throws Exception {
+        parseComment("This is not a valid comment", false);
+    }
+
+    @Test
+    public void shouldNotParseMalformedComment() throws Exception {
+        parseComment("/* This comment is missing ending delimeters", false);
+    }
+
+    // =============================================================================================================================
+    // Node Type Name Parsing Tests
+    // =============================================================================================================================
+
+    private void parseNodeTypeName( String name,
+                                    boolean success ) throws Exception {
+        CndParser parser = createParser(name);
+        RuleReturnScope scope = parser.node_type_name();
+
+        if (success) {
+            assertThat("Value '" + name + "' did not parse and should have", scope.getTree(), notNullValue());
+
+            // strip off brackets
+            assertThat(name.substring(1, name.length() - 1), is(((org.antlr.runtime.tree.CommonTree)scope.getTree()).getText()));
+        } else {
+            assertThat("Value '" + name + "' should not parse", scope.getTree(), nullValue());
+        }
+    }
+
+    @Test
+    public void shouldParseUnquotedNodeTypeName() throws Exception {
+        parseNodeTypeName("[typeName]", true);
+    }
+
+    @Test
+    public void shouldParseQuotedNodeTypeName() throws Exception {
+        parseNodeTypeName("['quotedName']", true);
+    }
+
+    @Test
+    public void shouldNotParseNodeTypeNameWithSpaces() throws Exception {
+        parseNodeTypeName("[no spaces allowed]", false);
+    }
+
+    @Test
+    public void shouldNotParseNodeTypeNameWithMissingEndBracket() throws Exception {
+        parseNodeTypeName("[missingClosingBracket", false);
+    }
+
+    @Test( expected = RewriteEmptyStreamException.class )
+    public void shouldNotParseNodeTypeNameWithMissingBracketsButNoName() throws Exception {
+        parseNodeTypeName("[]", false);
+    }
+
+    // =============================================================================================================================
+    // Node Type Abstract Option Parsing Tests
+    // =============================================================================================================================
+
+    private void parseAbstractOption( String option,
+                                      boolean success ) throws Exception {
+        CndParser parser = createParser(option);
+        RuleReturnScope scope = parser.abs_opt();
+
+        if (success) {
+            assertThat("Value '" + option + "' did not parse and should have", scope.getTree(), notNullValue());
+            assertThat(option, is(((org.antlr.runtime.tree.CommonTree)scope.getTree()).getText()));
+        } else {
+            assertThat("Value '" + option + "' should not parse and did", scope.getTree(), nullValue());
+        }
+    }
+
+    @Test
+    public void shouldParseAbstractOption() throws Exception {
+        parseAbstractOption("abstract", true);
+        parseAbstractOption("abs", true);
+        parseAbstractOption("a", true);
+    }
+
+    @Test
+    public void shouldNotParseInvalidAbstractOption() throws Exception {
+        parseAbstractOption("abstractoption", false);
+        parseAbstractOption("A", false);
+    }
+
+    // =============================================================================================================================
+    // Node Type Orderable Option Parsing Tests
+    // =============================================================================================================================
+
+    private void parseOrderableOption( String option,
+                                       boolean success ) throws Exception {
+        CndParser parser = createParser(option);
+        RuleReturnScope scope = parser.orderable_opt();
+
+        if (success) {
+            assertThat("Value '" + option + "' did not parse and should have", scope.getTree(), notNullValue());
+            assertThat(option, is(((org.antlr.runtime.tree.CommonTree)scope.getTree()).getText()));
+        } else {
+            assertThat("Value '" + option + "' should not parse and did", scope.getTree(), nullValue());
+        }
+    }
+
+    @Test
+    public void shouldParseOrderableOption() throws Exception {
+        parseOrderableOption("orderable", true);
+        parseOrderableOption("ord", true);
+        parseOrderableOption("o", true);
+    }
+
+    @Test
+    public void shouldNotParseInvalidOrderableOption() throws Exception {
+        parseOrderableOption("orderableoption", false);
+        parseOrderableOption("O", false);
+    }
+
+    // =============================================================================================================================
+    // Node Type Mixin Option Parsing Tests
+    // =============================================================================================================================
+
+    private void parseMixinOption( String option,
+                                   boolean success ) throws Exception {
+        CndParser parser = createParser(option);
+        RuleReturnScope scope = parser.mixin_opt();
+
+        if (success) {
+            assertThat("Value '" + option + "' did not parse and should have", scope.getTree(), notNullValue());
+            assertThat(option, is(((org.antlr.runtime.tree.CommonTree)scope.getTree()).getText()));
+        } else {
+            assertThat("Value '" + option + "' should not parse and did", scope.getTree(), nullValue());
+        }
+    }
+
+    @Test
+    public void shouldParseMixinOption() throws Exception {
+        parseMixinOption("mixin", true);
+        parseMixinOption("mix", true);
+        parseMixinOption("m", true);
+    }
+
+    @Test
+    public void shouldNotParseInvalidMixinOption() throws Exception {
+        parseMixinOption("mixinoption", false);
+        parseMixinOption("M", false);
+    }
+
+    // =============================================================================================================================
+    // Node Type Orderable Mixin Options Parsing Tests
+    // =============================================================================================================================
+
+    private void parseNodeTypeOrderableMixinOptions( String options,
+                                                     boolean success,
+                                                     int numChildren ) throws Exception {
+        CndParser parser = createParser(options);
+        RuleReturnScope scope = parser.ord_mix_opt();
+
+        if (success) {
+            assertThat("Value '" + options + "' did not parse and should have", scope.getTree(), notNullValue());
+
+            if (numChildren == 0) {
+                assertThat(options, is(((org.antlr.runtime.tree.CommonTree)scope.getTree()).getText()));
+            } else {
+                assertThat(numChildren, is(((org.antlr.runtime.tree.CommonTree)scope.getTree()).getChildCount()));
+            }
+        } else {
+            assertThat("Value '" + options + "' should not parse and did", scope.getTree(), nullValue());
+        }
+    }
+
+    @Test
+    public void shouldParseNodeTypeOrderableMixinOptions() throws Exception {
+        parseNodeTypeOrderableMixinOptions("orderable", true, 0);
+        parseNodeTypeOrderableMixinOptions("orderable mixin", true, 2);
+        parseNodeTypeOrderableMixinOptions("orderable mix", true, 2);
+        parseNodeTypeOrderableMixinOptions("orderable m", true, 2);
+
+        parseNodeTypeOrderableMixinOptions("ord", true, 0);
+        parseNodeTypeOrderableMixinOptions("ord mixin", true, 2);
+        parseNodeTypeOrderableMixinOptions("ord mix", true, 2);
+        parseNodeTypeOrderableMixinOptions("ord m", true, 2);
+
+        parseNodeTypeOrderableMixinOptions("o", true, 0);
+        parseNodeTypeOrderableMixinOptions("o mixin", true, 2);
+        parseNodeTypeOrderableMixinOptions("o mix", true, 2);
+        parseNodeTypeOrderableMixinOptions("o m", true, 2);
+
+        parseNodeTypeOrderableMixinOptions("mixin", true, 0);
+        parseNodeTypeOrderableMixinOptions("mixin orderable", true, 2);
+        parseNodeTypeOrderableMixinOptions("mixin ord", true, 2);
+        parseNodeTypeOrderableMixinOptions("mixin o", true, 2);
+
+        parseNodeTypeOrderableMixinOptions("mix", true, 0);
+        parseNodeTypeOrderableMixinOptions("mix orderable", true, 2);
+        parseNodeTypeOrderableMixinOptions("mix ord", true, 2);
+        parseNodeTypeOrderableMixinOptions("mix o", true, 2);
+
+        parseNodeTypeOrderableMixinOptions("m", true, 0);
+        parseNodeTypeOrderableMixinOptions("m orderable", true, 2);
+        parseNodeTypeOrderableMixinOptions("m ord", true, 2);
+        parseNodeTypeOrderableMixinOptions("m o", true, 2);
+    }
+
+    // =============================================================================================================================
+    // Node Type Options Parsing Tests
+    // =============================================================================================================================
+
+    private void parseNodeTypeOptions( String options,
+                                       boolean success,
+                                       int numChildren ) throws Exception {
+        CndParser parser = createParser(options);
+        RuleReturnScope scope = parser.node_type_options();
+
+        if (success) {
+            assertThat("Value '" + options + "' did not parse and should have", scope.getTree(), notNullValue());
+
+            if (numChildren == 0) {
+                assertThat(options, is(((org.antlr.runtime.tree.CommonTree)scope.getTree()).getText()));
+            } else {
+                assertThat(numChildren, is(((org.antlr.runtime.tree.CommonTree)scope.getTree()).getChildCount()));
+            }
+        } else {
+            assertThat("Value '" + options + "' should not parse and did", scope.getTree(), nullValue());
+        }
+    }
+
+    @Test
+    public void shouldParseNodeTypeOptions() throws Exception {
+        parseNodeTypeOptions("abstract", true, 0);
+        parseNodeTypeOptions("abs", true, 0);
+        parseNodeTypeOptions("a", true, 0);
+
+        parseNodeTypeOptions("abstract orderable", true, 2);
+        parseNodeTypeOptions("abstract ord", true, 2);
+        parseNodeTypeOptions("abstract o", true, 2);
+
+        parseNodeTypeOptions("abs orderable", true, 2);
+        parseNodeTypeOptions("abs ord", true, 2);
+        parseNodeTypeOptions("abs o", true, 2);
+
+        parseNodeTypeOptions("a orderable", true, 2);
+        parseNodeTypeOptions("a ord", true, 2);
+        parseNodeTypeOptions("a o", true, 2);
+
+        parseNodeTypeOptions("abstract mixin", true, 2);
+        parseNodeTypeOptions("abstract mix", true, 2);
+        parseNodeTypeOptions("abstract m", true, 2);
+
+        parseNodeTypeOptions("abs mixin", true, 2);
+        parseNodeTypeOptions("abs mix", true, 2);
+        parseNodeTypeOptions("abs m", true, 2);
+
+        parseNodeTypeOptions("a mixin", true, 2);
+        parseNodeTypeOptions("a mix", true, 2);
+        parseNodeTypeOptions("a m", true, 2);
+
+        parseNodeTypeOptions("abstract orderable mixin", true, 3);
+        parseNodeTypeOptions("abstract orderable mix", true, 3);
+        parseNodeTypeOptions("abstract orderable m", true, 3);
+
+        parseNodeTypeOptions("abstract ord mixin", true, 3);
+        parseNodeTypeOptions("abstract ord mix", true, 3);
+        parseNodeTypeOptions("abstract ord m", true, 3);
+
+        parseNodeTypeOptions("abstract o mixin", true, 3);
+        parseNodeTypeOptions("abstract o mix", true, 3);
+        parseNodeTypeOptions("abstract o m", true, 3);
+
+        parseNodeTypeOptions("abs orderable mixin", true, 3);
+        parseNodeTypeOptions("abs orderable mix", true, 3);
+        parseNodeTypeOptions("abs orderable m", true, 3);
+
+        parseNodeTypeOptions("abs ord mixin", true, 3);
+        parseNodeTypeOptions("abs ord mix", true, 3);
+        parseNodeTypeOptions("abs ord m", true, 3);
+
+        parseNodeTypeOptions("abs o mixin", true, 3);
+        parseNodeTypeOptions("abs o mix", true, 3);
+        parseNodeTypeOptions("abs o m", true, 3);
+
+        parseNodeTypeOptions("a orderable mixin", true, 3);
+        parseNodeTypeOptions("a orderable mix", true, 3);
+        parseNodeTypeOptions("a orderable m", true, 3);
+
+        parseNodeTypeOptions("a ord mixin", true, 3);
+        parseNodeTypeOptions("a ord mix", true, 3);
+        parseNodeTypeOptions("a ord m", true, 3);
+
+        parseNodeTypeOptions("a o mixin", true, 3);
+        parseNodeTypeOptions("a o mix", true, 3);
+        parseNodeTypeOptions("a o m", true, 3);
+
+        parseNodeTypeOptions("abstract mixin orderable", true, 3);
+        parseNodeTypeOptions("abstract mixin ord", true, 3);
+        parseNodeTypeOptions("abstract mixin o", true, 3);
+
+        parseNodeTypeOptions("abstract mix orderable", true, 3);
+        parseNodeTypeOptions("abstract mix ord", true, 3);
+        parseNodeTypeOptions("abstract mix o", true, 3);
+
+        parseNodeTypeOptions("abstract m orderable", true, 3);
+        parseNodeTypeOptions("abstract m ord", true, 3);
+        parseNodeTypeOptions("abstract m o", true, 3);
+
+        parseNodeTypeOptions("abs mixin orderable", true, 3);
+        parseNodeTypeOptions("abs mixin ord", true, 3);
+        parseNodeTypeOptions("abs mixin o", true, 3);
+
+        parseNodeTypeOptions("abs mix orderable", true, 3);
+        parseNodeTypeOptions("abs mix ord", true, 3);
+        parseNodeTypeOptions("abs mix o", true, 3);
+
+        parseNodeTypeOptions("abs m orderable", true, 3);
+        parseNodeTypeOptions("abs m ord", true, 3);
+        parseNodeTypeOptions("abs m o", true, 3);
+
+        parseNodeTypeOptions("a mixin orderable", true, 3);
+        parseNodeTypeOptions("a mixin ord", true, 3);
+        parseNodeTypeOptions("a mixin o", true, 3);
+
+        parseNodeTypeOptions("a mix orderable", true, 3);
+        parseNodeTypeOptions("a mix ord", true, 3);
+        parseNodeTypeOptions("a mix o", true, 3);
+
+        parseNodeTypeOptions("a m orderable", true, 3);
+        parseNodeTypeOptions("a m ord", true, 3);
+        parseNodeTypeOptions("a m o", true, 3);
+
+        parseNodeTypeOptions("orderable abstract", true, 2);
+        parseNodeTypeOptions("ord abstract", true, 2);
+        parseNodeTypeOptions("o abstract", true, 2);
+
+        parseNodeTypeOptions("orderable abs", true, 2);
+        parseNodeTypeOptions("ord abs", true, 2);
+        parseNodeTypeOptions("o abs", true, 2);
+
+        parseNodeTypeOptions("orderable a", true, 2);
+        parseNodeTypeOptions("ord a", true, 2);
+        parseNodeTypeOptions("o a", true, 2);
+
+        parseNodeTypeOptions("mixin abstract", true, 2);
+        parseNodeTypeOptions("mix abstract", true, 2);
+        parseNodeTypeOptions("m abstract", true, 2);
+
+        parseNodeTypeOptions("mixin abs", true, 2);
+        parseNodeTypeOptions("mix abs", true, 2);
+        parseNodeTypeOptions("m abs", true, 2);
+
+        parseNodeTypeOptions("mixin a", true, 2);
+        parseNodeTypeOptions("mix a", true, 2);
+        parseNodeTypeOptions("m a", true, 2);
+
+        parseNodeTypeOptions("orderable mixin abstract", true, 3);
+        parseNodeTypeOptions("orderable mix abstract", true, 3);
+        parseNodeTypeOptions("orderable m abstract", true, 3);
+
+        parseNodeTypeOptions("ord mixin abstract", true, 3);
+        parseNodeTypeOptions("ord mix abstract", true, 3);
+        parseNodeTypeOptions("ord m abstract", true, 3);
+
+        parseNodeTypeOptions("o mixin abstract", true, 3);
+        parseNodeTypeOptions("o mix abstract", true, 3);
+        parseNodeTypeOptions("o m abstract", true, 3);
+
+        parseNodeTypeOptions("orderable mixin abs", true, 3);
+        parseNodeTypeOptions("orderable mix abs", true, 3);
+        parseNodeTypeOptions("orderable m abs", true, 3);
+
+        parseNodeTypeOptions("ord mixin abs", true, 3);
+        parseNodeTypeOptions("ord mix abs", true, 3);
+        parseNodeTypeOptions("ord m abs", true, 3);
+
+        parseNodeTypeOptions("o mixin abs", true, 3);
+        parseNodeTypeOptions("o mix abs", true, 3);
+        parseNodeTypeOptions("o m abs", true, 3);
+
+        parseNodeTypeOptions("orderable mixin a", true, 3);
+        parseNodeTypeOptions("orderable mix a", true, 3);
+        parseNodeTypeOptions("orderable m a", true, 3);
+
+        parseNodeTypeOptions("ord mixin a", true, 3);
+        parseNodeTypeOptions("ord mix a", true, 3);
+        parseNodeTypeOptions("ord m a", true, 3);
+
+        parseNodeTypeOptions("o mixin a", true, 3);
+        parseNodeTypeOptions("o mix a", true, 3);
+        parseNodeTypeOptions("o m a", true, 3);
+
+        parseNodeTypeOptions("mixin orderable abstract", true, 3);
+        parseNodeTypeOptions("mixin ord abstract", true, 3);
+        parseNodeTypeOptions("mixin o abstract", true, 3);
+
+        parseNodeTypeOptions("mix orderable abstract", true, 3);
+        parseNodeTypeOptions("mix ord abstract", true, 3);
+        parseNodeTypeOptions("mix o abstract", true, 3);
+
+        parseNodeTypeOptions("m orderable abstract", true, 3);
+        parseNodeTypeOptions("m ord abstract", true, 3);
+        parseNodeTypeOptions("m o abstract", true, 3);
+
+        parseNodeTypeOptions("mixin orderable abs", true, 3);
+        parseNodeTypeOptions("mixin ord abs", true, 3);
+        parseNodeTypeOptions("mixin o abs", true, 3);
+
+        parseNodeTypeOptions("mix orderable abs", true, 3);
+        parseNodeTypeOptions("mix ord abs", true, 3);
+        parseNodeTypeOptions("mix o abs", true, 3);
+
+        parseNodeTypeOptions("m orderable abs", true, 3);
+        parseNodeTypeOptions("m ord abs", true, 3);
+        parseNodeTypeOptions("m o abs", true, 3);
+
+        parseNodeTypeOptions("mixin orderable a", true, 3);
+        parseNodeTypeOptions("mixin ord a", true, 3);
+        parseNodeTypeOptions("mixin o a", true, 3);
+
+        parseNodeTypeOptions("mix orderable a", true, 3);
+        parseNodeTypeOptions("mix ord a", true, 3);
+        parseNodeTypeOptions("mix o a", true, 3);
+
+        parseNodeTypeOptions("m orderable a", true, 3);
+        parseNodeTypeOptions("m ord a", true, 3);
+        parseNodeTypeOptions("m o a", true, 3);
+
+        parseNodeTypeOptions("orderable", true, 0);
+        parseNodeTypeOptions("ord", true, 0);
+        parseNodeTypeOptions("o", true, 0);
+
+        parseNodeTypeOptions("mixin", true, 0);
+        parseNodeTypeOptions("mix", true, 0);
+        parseNodeTypeOptions("m", true, 0);
+
+        parseNodeTypeOptions("orderable mixin", true, 2);
+        parseNodeTypeOptions("orderable mix", true, 2);
+        parseNodeTypeOptions("orderable m", true, 2);
+
+        parseNodeTypeOptions("ord mixin", true, 2);
+        parseNodeTypeOptions("ord mix", true, 2);
+        parseNodeTypeOptions("ord m", true, 2);
+
+        parseNodeTypeOptions("o mixin", true, 2);
+        parseNodeTypeOptions("o mix", true, 2);
+        parseNodeTypeOptions("o m", true, 2);
+
+        parseNodeTypeOptions("mixin orderable", true, 2);
+        parseNodeTypeOptions("mixin ord", true, 2);
+        parseNodeTypeOptions("mixin o", true, 2);
+
+        parseNodeTypeOptions("mix orderable", true, 2);
+        parseNodeTypeOptions("mix ord", true, 2);
+        parseNodeTypeOptions("mix o", true, 2);
+
+        parseNodeTypeOptions("m orderable", true, 2);
+        parseNodeTypeOptions("m ord", true, 2);
+        parseNodeTypeOptions("m o", true, 2);
+    }
+
+    // =============================================================================================================================
+    // Property Type Parsing Tests
+    // =============================================================================================================================
+
+    private void parsePropertyType( String propertyType,
+                                    boolean success ) throws Exception {
+        CndParser parser = createParser(propertyType);
+        RuleReturnScope scope = parser.property_type();
+
+        if (success) {
+            assertThat("Value '" + propertyType + "' did not parse and should have", scope.getTree(), notNullValue());
+            assertThat(propertyType, is(((org.antlr.runtime.tree.CommonTree)scope.getTree()).getText()));
+        } else {
+            assertThat("Value '" + propertyType + "' should not parse and did", scope.getTree(), nullValue());
+        }
+    }
+
+    @Test
+    public void shouldParseStringPropertyType() throws Exception {
+        parsePropertyType("STRING", true);
+        parsePropertyType("String", true);
+        parsePropertyType("string", true);
+    }
+
+    @Test
+    public void shouldParseBinaryPropertyType() throws Exception {
+        parsePropertyType("BINARY", true);
+        parsePropertyType("Binary", true);
+        parsePropertyType("binary", true);
+    }
+
+    @Test
+    public void shouldParseLongPropertyType() throws Exception {
+        parsePropertyType("LONG", true);
+        parsePropertyType("Long", true);
+        parsePropertyType("long", true);
+    }
+
+    @Test
+    public void shouldParseDoublePropertyType() throws Exception {
+        parsePropertyType("DOUBLE", true);
+        parsePropertyType("Double", true);
+        parsePropertyType("double", true);
+    }
+
+    @Test
+    public void shouldParseDecimalPropertyType() throws Exception {
+        parsePropertyType("DECIMAL", true);
+        parsePropertyType("Decimal", true);
+        parsePropertyType("decimal", true);
+    }
+
+    @Test
+    public void shouldParseBooleanPropertyType() throws Exception {
+        parsePropertyType("BOOLEAN", true);
+        parsePropertyType("Boolean", true);
+        parsePropertyType("boolean", true);
+    }
+
+    @Test
+    public void shouldParseDatePropertyType() throws Exception {
+        parsePropertyType("DATE", true);
+        parsePropertyType("Date", true);
+        parsePropertyType("date", true);
+    }
+
+    @Test
+    public void shouldParseNamePropertyType() throws Exception {
+        parsePropertyType("NAME", true);
+        parsePropertyType("Name", true);
+        parsePropertyType("name", true);
+    }
+
+    @Test
+    public void shouldParsePathPropertyType() throws Exception {
+        parsePropertyType("PATH", true);
+        parsePropertyType("Path", true);
+        parsePropertyType("path", true);
+    }
+
+    @Test
+    public void shouldParseReferencePropertyType() throws Exception {
+        parsePropertyType("REFERENCE", true);
+        parsePropertyType("Reference", true);
+        parsePropertyType("reference", true);
+    }
+
+    @Test
+    public void shouldParseWeakReferencePropertyType() throws Exception {
+        parsePropertyType("WEAKREFERENCE", true);
+        parsePropertyType("WeakReference", true);
+        parsePropertyType("weakreference", true);
+    }
+
+    @Test
+    public void shouldParseUriPropertyType() throws Exception {
+        parsePropertyType("URI", true);
+        parsePropertyType("Uri", true);
+        parsePropertyType("uri", true);
+    }
+
+    @Test
+    public void shouldParseUndefinedPropertyType() throws Exception {
+        parsePropertyType("UNDEFINED", true);
+        parsePropertyType("Undefined", true);
+        parsePropertyType("undefined", true);
+    }
+
+    @Test
+    public void shouldNotParseInvalidPropertyType() throws Exception {
+        parsePropertyType("B", false);
+        parsePropertyType("b", false);
+        parsePropertyType("binarytype", false);
+    }
+
+    // =============================================================================================================================
+    // Attributes Parsing Tests
+    // =============================================================================================================================
+
+    private void parseAttribute( String attribute,
+                                 boolean success ) throws Exception {
+        CndParser parser = createParser(attribute);
+        RuleReturnScope scope = parser.attributes();
+
+        if (success) {
+            assertThat("Value '" + attribute + "' did not parse and should have", scope.getTree(), notNullValue());
+            assertThat(attribute, is(((org.antlr.runtime.tree.CommonTree)scope.getTree()).getText()));
+        } else {
+            assertThat("Value '" + attribute + "' should not parse and did", scope.getTree(), nullValue());
+        }
+    }
+
+    @Test
+    public void shouldParsePrimaryAttribute() throws Exception {
+        parseAttribute("primary", true);
+        parseAttribute("pri", true);
+        parseAttribute("!", true);
+    }
+
+    @Test
+    public void shouldParseAutoCreatedAttribute() throws Exception {
+        parseAttribute("autocreated", true);
+        parseAttribute("aut", true);
+        parseAttribute("a", true);
+    }
+
+    @Test
+    public void shouldParseMandatoryAttribute() throws Exception {
+        parseAttribute("mandatory", true);
+        parseAttribute("man", true);
+        parseAttribute("m", true);
+    }
+
+    @Test
+    public void shouldParseProtectedAttribute() throws Exception {
+        parseAttribute("protected", true);
+        parseAttribute("pro", true);
+        parseAttribute("p", true);
+    }
+
+    @Test
+    public void shouldParseMultipleAttribute() throws Exception {
+        parseAttribute("multiple", true);
+        parseAttribute("mul", true);
+        parseAttribute("*", true);
+    }
+
+    @Test
+    public void shouldParseCopyAttribute() throws Exception {
+        parseAttribute("COPY", true);
+        parseAttribute("Copy", true);
+        parseAttribute("copy", true);
+    }
+
+    @Test
+    public void shouldParseVersionAttribute() throws Exception {
+        parseAttribute("VERSION", true);
+        parseAttribute("Version", true);
+        parseAttribute("version", true);
+    }
+
+    @Test
+    public void shouldParseInitializeAttribute() throws Exception {
+        parseAttribute("INITIALIZE", true);
+        parseAttribute("Initialize", true);
+        parseAttribute("initialize", true);
+    }
+
+    @Test
+    public void shouldParseComputeAttribute() throws Exception {
+        parseAttribute("COMPUTE", true);
+        parseAttribute("Compute", true);
+        parseAttribute("compute", true);
+    }
+
+    @Test
+    public void shouldParseIgnoreAttribute() throws Exception {
+        parseAttribute("IGNORE", true);
+        parseAttribute("Ignore", true);
+        parseAttribute("ignore", true);
+    }
+
+    @Test
+    public void shouldParseAbortAttribute() throws Exception {
+        parseAttribute("ABORT", true);
+        parseAttribute("Abort", true);
+        parseAttribute("abort", true);
+    }
+
+    @Test
+    public void shouldNotParseInvalidAttribute() throws Exception {
+        parsePropertyType("P", false);
+        parsePropertyType("A", false);
+        parsePropertyType("PRIMARY", false);
+    }
+}

Added: trunk/sequencers/dna-sequencer-cnd/src/test/resources/builtin_nodetypes.cnd
===================================================================
--- trunk/sequencers/dna-sequencer-cnd/src/test/resources/builtin_nodetypes.cnd	                        (rev 0)
+++ trunk/sequencers/dna-sequencer-cnd/src/test/resources/builtin_nodetypes.cnd	2008-06-13 14:13:50 UTC (rev 284)
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+<rep='internal'>
+<jcr='http://www.jcp.org/jcr/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+
+//------------------------------------------------------------------------------
+// B A S E  T Y P E S
+//------------------------------------------------------------------------------
+
+[nt:base]
+  - jcr:primaryType (name) mandatory autocreated protected compute
+  - jcr:mixinTypes (name) protected multiple compute
+
+[nt:unstructured]
+  orderable
+  - * (undefined) multiple
+  - * (undefined)
+  + * (nt:base) = nt:unstructured multiple version
+
+[mix:referenceable]
+  mixin
+  - jcr:uuid (string) mandatory autocreated protected initialize
+
+[mix:lockable]
+  mixin
+  - jcr:lockOwner (string) protected ignore
+  - jcr:lockIsDeep (boolean) protected ignore
+
+//------------------------------------------------------------------------------
+// V E R S I O N I N G
+//------------------------------------------------------------------------------
+
+[mix:versionable] > mix:referenceable
+  mixin
+  - jcr:versionHistory (reference) mandatory protected
+    < 'nt:versionHistory'
+  - jcr:baseVersion (reference) mandatory protected ignore
+    < 'nt:version'
+  - jcr:isCheckedOut (boolean) = 'true' mandatory autocreated protected ignore
+  - jcr:predecessors (reference) mandatory protected multiple
+    < 'nt:version'
+  - jcr:mergeFailed (reference) protected multiple abort
+
+[nt:versionHistory] > mix:referenceable
+  - jcr:versionableUuid (string) mandatory autocreated protected abort
+  + jcr:rootVersion (nt:version) = nt:version mandatory autocreated protected abort
+  + jcr:versionLabels (nt:versionLabels) = nt:versionLabels mandatory autocreated protected abort
+  + * (nt:version) = nt:version protected abort
+
+[nt:versionLabels]
+  - * (reference) protected abort
+    < 'nt:version'
+
+[nt:version] > mix:referenceable
+  - jcr:created (date) mandatory autocreated protected abort
+  - jcr:predecessors (reference) protected multiple abort
+    < 'nt:version'
+  - jcr:successors (reference) protected multiple abort
+    < 'nt:version'
+  + jcr:frozenNode (nt:frozenNode) protected abort
+
+[nt:frozenNode] > mix:referenceable
+  orderable
+  - jcr:frozenPrimaryType (name) mandatory autocreated protected abort
+  - jcr:frozenMixinTypes (name) protected multiple abort
+  - jcr:frozenUuid (string) mandatory autocreated protected abort
+  - * (undefined) protected abort
+  - * (undefined) protected multiple abort
+  + * (nt:base) protected multiple abort
+
+[nt:versionedChild]
+  - jcr:childVersionHistory (reference) mandatory autocreated protected abort
+    < 'nt:versionHistory'
+
+//------------------------------------------------------------------------------
+// N O D E T Y P E S
+//------------------------------------------------------------------------------
+
+[nt:nodeType]
+  - jcr:nodeTypeName (name) mandatory
+  - jcr:supertypes (name) multiple
+  - jcr:isMixin (boolean) mandatory
+  - jcr:hasOrderableChildNodes (boolean) mandatory
+  - jcr:primaryItemName (name)
+  + jcr:propertyDefinition (nt:propertyDefinition) = nt:propertyDefinition multiple version
+  + jcr:childNodeDefinition (nt:childNodeDefinition) = nt:childNodeDefinition multiple version
+
+[nt:propertyDefinition]
+  - jcr:name (name)
+  - jcr:autoCreated (boolean) mandatory
+  - jcr:mandatory (boolean) mandatory
+  - jcr:onParentVersion (string) mandatory
+    < 'COPY', 'VERSION', 'INITIALIZE', 'COMPUTE', 'IGNORE', 'ABORT'
+  - jcr:protected (boolean) mandatory
+  - jcr:requiredType (string) mandatory
+    < 'STRING', 'BINARY', 'LONG', 'DOUBLE', 'BOOLEAN', 'DATE', 'NAME', 'PATH', 'REFERENCE', 'UNDEFINED'
+  - jcr:valueConstraints (string) multiple
+  - jcr:defaultValues (undefined) multiple
+  - jcr:multiple (boolean) mandatory
+
+[nt:childNodeDefinition]
+  - jcr:name (name)
+  - jcr:autoCreated (boolean) mandatory
+  - jcr:mandatory (boolean) mandatory
+  - jcr:onParentVersion (string) mandatory
+    < 'COPY', 'VERSION', 'INITIALIZE', 'COMPUTE', 'IGNORE', 'ABORT'
+  - jcr:protected (boolean) mandatory
+  - jcr:requiredPrimaryTypes (name) = 'nt:base' mandatory multiple
+  - jcr:defaultPrimaryType (name)
+  - jcr:sameNameSiblings (boolean) mandatory
+
+//------------------------------------------------------------------------------
+// M I S C
+//------------------------------------------------------------------------------
+
+[nt:hierarchyNode]
+  - jcr:created (date) autocreated protected initialize
+
+[nt:folder] > nt:hierarchyNode
+  + * (nt:hierarchyNode) version
+
+[nt:file] > nt:hierarchyNode
+  + jcr:content (nt:base) primary mandatory
+
+[nt:linkedFile] > nt:hierarchyNode
+  - jcr:content (reference) primary mandatory
+
+[nt:resource] > mix:referenceable
+  - jcr:encoding (string)
+  - jcr:mimeType (string) mandatory
+  - jcr:data (binary) primary mandatory
+  - jcr:lastModified (date) mandatory ignore
+
+[nt:query]
+  - jcr:statement (string)
+  - jcr:language (string)
+
+//------------------------------------------------------------------------------
+// J A C K R A B B I T   I N T E R N A L S
+//------------------------------------------------------------------------------
+
+[rep:nodeTypes]
+  + * (nt:nodeType) = nt:nodeType protected abort
+
+[rep:root] > nt:unstructured
+  orderable
+  + jcr:system (rep:system) = rep:system mandatory ignore
+
+[rep:system]
+  orderable
+  + jcr:versionStorage (rep:versionStorage) = rep:versionStorage mandatory protected abort
+  + jcr:nodeTypes (rep:nodeTypes) = rep:nodeTypes mandatory protected abort
+  + * (nt:base) = nt:unstructured multiple ignore
+
+[rep:versionStorage]
+  + * (nt:versionHistory) = nt:versionHistory protected multiple abort
+  + * (rep:versionStorage) = rep:versionStorage protected multiple abort

Added: trunk/sequencers/dna-sequencer-cnd/src/test/resources/empty.cnd
===================================================================

Added: trunk/sequencers/dna-sequencer-cnd/src/test/resources/images.cnd
===================================================================
--- trunk/sequencers/dna-sequencer-cnd/src/test/resources/images.cnd	                        (rev 0)
+++ trunk/sequencers/dna-sequencer-cnd/src/test/resources/images.cnd	2008-06-13 14:13:50 UTC (rev 284)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+ 
+//------------------------------------------------------------------------------
+// N A M E S P A C E S
+//------------------------------------------------------------------------------
+<jcr='http://www.jcp.org/jcr/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+<image='http://jboss.org/dna/images/1.0'>
+
+// ----------------------------------------------------------
+// JCR Pre-defined Mixin Types that are not loaded by default
+// ----------------------------------------------------------
+
+[mix:mimeType] mixin 
+  - jcr:mimeType (string)  
+  - jcr:encoding (string)
+
+
+//------------------------------------------------------------------------------
+// N O D E T Y P E S
+//------------------------------------------------------------------------------
+
+/**
+ * Mixin that defines the metadata for an image
+ */
+[image:metadata] > nt:unstructured, mix:mimeType
+  - image:formatName (string) mandatory
+    < 'JPEG', 'GIF', 'PNG', 'BMP', 'PCX', 'IFF', 'RAS', 'PBM', 'PGM', 'PPM', 'PSD'
+  - image:width (long)
+  - image:height (long)
+  - image:bitsPerPixel (long)
+  - image:progressive (boolean)
+  - image:numberOfImages (long)
+  - image:physicalWidthDpi (long)
+  - image:physicalHeightDpi (long)
+  - image:physicalWidthInches (long)
+  - image:physicalHeightInches (long)
+
+
+ 
\ No newline at end of file

Added: trunk/sequencers/dna-sequencer-cnd/src/test/resources/invalid.cnd
===================================================================
--- trunk/sequencers/dna-sequencer-cnd/src/test/resources/invalid.cnd	                        (rev 0)
+++ trunk/sequencers/dna-sequencer-cnd/src/test/resources/invalid.cnd	2008-06-13 14:13:50 UTC (rev 284)
@@ -0,0 +1 @@
+This is not a valid cnd file.
\ No newline at end of file

Added: trunk/sequencers/dna-sequencer-cnd/src/test/resources/mp3.cnd
===================================================================
--- trunk/sequencers/dna-sequencer-cnd/src/test/resources/mp3.cnd	                        (rev 0)
+++ trunk/sequencers/dna-sequencer-cnd/src/test/resources/mp3.cnd	2008-06-13 14:13:50 UTC (rev 284)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+ 
+//------------------------------------------------------------------------------
+// N A M E S P A C E S
+//------------------------------------------------------------------------------
+<jcr='http://www.jcp.org/jcr/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+<mp3='http://jboss.org/dna/mp3/1.0'>
+
+// ----------------------------------------------------------
+// JCR Pre-defined Mixin Types that are not loaded by default
+// ----------------------------------------------------------
+
+[mix:mimeType] mixin 
+  - jcr:mimeType (string)  
+  - jcr:encoding (string)
+
+
+//------------------------------------------------------------------------------
+// N O D E T Y P E S
+//------------------------------------------------------------------------------
+
+[mp3:metadata] > nt:unstructured, mix:mimeTyped
+  - mp3:title (string)
+  - mp3:author (string)
+  - mp3:album (string)
+  - mp3:year (long)
+  - mp3:comment (string)
+ 
+ 
\ No newline at end of file




More information about the dna-commits mailing list