Author: rhauch
Date: 2009-04-20 15:07:48 -0400 (Mon, 20 Apr 2009)
New Revision: 840
Added:
trunk/dna-cnd/
trunk/dna-cnd/.classpath
trunk/dna-cnd/.project
trunk/dna-cnd/.settings/
trunk/dna-cnd/.settings/org.eclipse.jdt.core.prefs
trunk/dna-cnd/pom.xml
trunk/dna-cnd/src/
trunk/dna-cnd/src/main/
trunk/dna-cnd/src/main/antlr/
trunk/dna-cnd/src/main/antlr/org/
trunk/dna-cnd/src/main/antlr/org/jboss/
trunk/dna-cnd/src/main/antlr/org/jboss/dna/
trunk/dna-cnd/src/main/antlr/org/jboss/dna/cnd/
trunk/dna-cnd/src/main/antlr/org/jboss/dna/cnd/Cnd.g
trunk/dna-cnd/src/main/antlr3/
trunk/dna-cnd/src/main/antlr3/org/
trunk/dna-cnd/src/main/antlr3/org/jboss/
trunk/dna-cnd/src/main/antlr3/org/jboss/dna/
trunk/dna-cnd/src/main/antlr3/org/jboss/dna/cnd/
trunk/dna-cnd/src/main/antlr3/org/jboss/dna/cnd/Cnd.g
trunk/dna-cnd/src/main/java/
trunk/dna-cnd/src/main/java/org/
trunk/dna-cnd/src/main/java/org/jboss/
trunk/dna-cnd/src/main/java/org/jboss/dna/
trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/
trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/CndI18n.java
trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/CndImporter.java
trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/QueryOperator.java
trunk/dna-cnd/src/main/resources/
trunk/dna-cnd/src/main/resources/org/
trunk/dna-cnd/src/main/resources/org/jboss/
trunk/dna-cnd/src/main/resources/org/jboss/dna/
trunk/dna-cnd/src/main/resources/org/jboss/dna/cnd/
trunk/dna-cnd/src/main/resources/org/jboss/dna/cnd/CndI18n.properties
trunk/dna-cnd/src/test/
trunk/dna-cnd/src/test/java/
trunk/dna-cnd/src/test/java/org/
trunk/dna-cnd/src/test/java/org/jboss/
trunk/dna-cnd/src/test/java/org/jboss/dna/
trunk/dna-cnd/src/test/java/org/jboss/dna/cnd/
trunk/dna-cnd/src/test/java/org/jboss/dna/cnd/CndImporterTest.java
trunk/dna-cnd/src/test/resources/
trunk/dna-cnd/src/test/resources/cnd/
trunk/dna-cnd/src/test/resources/cnd/empty.cnd
trunk/dna-cnd/src/test/resources/cnd/images.cnd
trunk/dna-cnd/src/test/resources/cnd/invalid.cnd
trunk/dna-cnd/src/test/resources/cnd/jcr-builtins-170.cnd
trunk/dna-cnd/src/test/resources/cnd/jcr-builtins-283-early-draft.cnd
trunk/dna-cnd/src/test/resources/cnd/mp3.cnd
trunk/dna-cnd/src/test/resources/log4j.properties
Modified:
trunk/pom.xml
Log:
DNA-363 Define node types via CND files
Added a new 'dna-cnd' project containing a graph importer that reads JCR CND files
and populates a repository with the content (based upon the JCR 'nt:nodeType',
'nt:propertyDefinition', and 'nt:childNodeDefinition').
Property changes on: trunk/dna-cnd
___________________________________________________________________
Name: svn:ignore
+ target
Added: trunk/dna-cnd/.classpath
===================================================================
--- trunk/dna-cnd/.classpath (rev 0)
+++ trunk/dna-cnd/.classpath 2009-04-20 19:07:48 UTC (rev 840)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="src" path="src/main/resources"/>
+ <classpathentry kind="src" path="src/main/antlr3"/>
+ <classpathentry kind="src" output="target/test-classes"
path="src/test/java"/>
+ <classpathentry kind="src" output="target/test-classes"
path="src/test/resources"/>
+ <classpathentry kind="src"
path="target/generated-sources/antlr3"/>
+ <classpathentry kind="con"
path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con"
path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
Added: trunk/dna-cnd/.project
===================================================================
--- trunk/dna-cnd/.project (rev 0)
+++ trunk/dna-cnd/.project 2009-04-20 19:07:48 UTC (rev 840)
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>dna-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/dna-cnd/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- trunk/dna-cnd/.settings/org.eclipse.jdt.core.prefs (rev 0)
+++ trunk/dna-cnd/.settings/org.eclipse.jdt.core.prefs 2009-04-20 19:07:48 UTC (rev 840)
@@ -0,0 +1,60 @@
+#Fri Apr 17 14:06:37 CDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=error
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=error
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=disabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=ignore
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=ignore
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
Added: trunk/dna-cnd/pom.xml
===================================================================
--- trunk/dna-cnd/pom.xml (rev 0)
+++ trunk/dna-cnd/pom.xml 2009-04-20 19:07:48 UTC (rev 840)
@@ -0,0 +1,107 @@
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>dna</artifactId>
+ <groupId>org.jboss.dna</groupId>
+ <version>0.4-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-cnd</artifactId>
+ <name>JBoss DNA CND Utility</name>
+ <description>JBoss DNA utility for processing and working with JCR CND
files</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-graph</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr-runtime</artifactId>
+ <version>3.1.3</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.antlr</groupId>
+ <artifactId>stringtemplate</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-graph</artifactId>
+ <version>${pom.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr</artifactId>
+ <version>3.1.3</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.antlr</groupId>
+ <artifactId>stringtemplate</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ </exclusion>
+ </exclusions>
+ <!-- we try to use scope to hide it from transitivity -->
+ <scope>test</scope> <!-- or perhaps 'provided' (see later
discussion) or 'import' (maven >= 2.0.9) -->
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-library</artifactId>
+ </dependency>
+ <!--
+ Logging (require SLF4J API for compiling, but use Log4J and its SLF4J binding for
testing)
+ -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <!--
+ Java Concurrency in Practice annotations
+ -->
+ <dependency>
+ <groupId>net.jcip</groupId>
+ <artifactId>jcip-annotations</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr3-maven-plugin</artifactId>
+ <version>3.1.3-1</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>antlr</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
Added: trunk/dna-cnd/src/main/antlr/org/jboss/dna/cnd/Cnd.g
===================================================================
--- trunk/dna-cnd/src/main/antlr/org/jboss/dna/cnd/Cnd.g (rev 0)
+++ trunk/dna-cnd/src/main/antlr/org/jboss/dna/cnd/Cnd.g 2009-04-20 19:07:48 UTC (rev
840)
@@ -0,0 +1,360 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 {
+ output=AST;
+}
+
+
+tokens {
+ NAMESPACES;
+ PREFIX;
+ URI;
+ NODE;
+ NAME;
+ PRIMARY_TYPE;
+ SUPERTYPES;
+ NODE_TYPES;
+ NODE_TYPE_ATTRIBUTES;
+ HAS_ORDERABLE_CHILD_NODES;
+ IS_MIXIN;
+ IS_ABSTRACT;
+ IS_QUERYABLE;
+ PRIMARY_ITEM_NAME;
+ PROPERTY_DEFINITION;
+ REQUIRED_TYPE;
+ DEFAULT_VALUES;
+ VALUE_CONSTRAINTS;
+ AUTO_CREATED;
+ MANDATORY;
+ PROTECTED;
+ REQUIRED_TYPE;
+ ON_PARENT_VERSION;
+ MULTIPLE;
+ QUERY_OPERATORS;
+ IS_FULL_TEXT_SEARCHABLE;
+ IS_QUERY_ORDERERABLE;
+ CHILD_NODE_DEFINITION;
+ REQUIRED_PRIMARY_TYPES;
+ DEFAULT_PRIMARY_TYPE;
+ SAME_NAME_SIBLINGS;
+}
+
+@header {
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.cnd;
+}
+
+@members {
+@Override
+public void emitErrorMessage( String msg ) {
+ // don't write messages to System.err ...
+ //super.emitErrorMessage(msg);
+}
+}
+
+@lexer::header {
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.cnd;
+}
+
+@rulecatch {
+ catch (RecognitionException re) {
+ reportError(re);
+ }
+}
+
+// ------------
+// Parser rules
+// ------------
+
+// These rules generate an AST that was designed with a structure that may be
+// automatically processed into a graph structure. This structure is:
+//
+// NAMESPACES
+// +- NODE (multiple)
+// +- PREFIX
+// +- string value
+// +- URI
+// +- string value
+// NODE_TYPES
+// +- NODE (multiple)
+// +- NAME [nt:nodeType/@jcr:name]
+// +- string value
+// +- PRIMARY_TYPE [nt:base/@jcr:primaryType]
+// +- string with value 'nt:nodeType'
+// +- SUPERTYPES [nt:nodeType/@jcr:supertypes]
+// +- string value(s)
+// +- IS_ABSTRACT [nt:nodeType/@jcr:isAbstract]
+// +- string containing boolean value (or false if not present)
+// +- HAS_ORDERABLE_CHILD_NODES
[nt:nodeType/@jcr:hasOrderableChildNodes]
+// +- string containing boolean value (or false if not present)
+// +- IS_MIXIN [nt:nodeType/@jcr:isMixin]
+// +- string containing boolean value (or false if not present)
+// +- IS_QUERYABLE [nt:nodeType/@jcr:isQueryable]
+// +- string containing boolean value (or true if not present)
+// +- PRIMARY_ITEM_NAME [nt:nodeType/@jcr:primaryItemName]
+// +- string containing string value
+// +- PROPERTY_DEFINITION [nt:nodeType/@jcr:propertyDefinition]
+// +- NODE (multiple)
+// +- NAME [nt:propertyDefinition/@jcr:name]
+// +- string value
+// +- PRIMARY_TYPE [nt:base/@jcr:primaryType]
+// +- string with value 'nt:propertyDefinition'
+// +- REQUIRED_TYPE
[nt:propertyDefinition/@jcr:propertyType]
+// +- string value (limited to one of the predefined types)
+// +- DEFAULT_VALUES
[nt:propertyDefinition/@jcr:defaultValues]
+// +- string value(s)
+// +- MULTIPLE [nt:propertyDefinition/@jcr:multiple]
+// +- string containing boolean value (or false if not present)
+// +- MANDATORY [nt:propertyDefinition/@jcr:mandatory]
+// +- string containing boolean value (or false if not present)
+// +- AUTO_CREATED
[nt:propertyDefinition/@jcr:autoCreated]
+// +- string containing boolean value (or false if not present)
+// +- PROTECTED [nt:propertyDefinition/@jcr:protected]
+// +- string containing boolean value (or false if not present)
+// +- ON_PARENT_VERSION
[nt:propertyDefinition/@jcr:onParentVersion]
+// +- string value (limited to one of the predefined literal values)
+// +- QUERY_OPERATORS
+// +- string value (containing a comma-separated list of operator
literals)
+// +- IS_FULL_TEXT_SEARCHABLE
[nt:propertyDefinition/@jcr:isFullTextSearchable]
+// +- string containing boolean value (or true if not present)
+// +- IS_QUERY_ORDERABLE
[nt:propertyDefinition/@jcr:isQueryOrderable]
+// +- string containing boolean value (or true if not present)
+// +- VALUE_CONSTRAINTS
[nt:propertyDefinition/@jcr:valueConstraints]
+// +- string value(s)
+// +- CHILD_NODE_DEFINITION [nt:nodeType/@jcr:childNodeDefinition]
+// +- NODE (multiple)
+// +- NAME [nt:childNodeDefinition/@jcr:name]
+// +- string value
+// +- PRIMARY_TYPE [nt:base/@jcr:primaryType]
+// +- string with value 'nt:childNodeDefinition'
+// +- REQUIRED_PRIMARY_TYPES
[nt:childNodeDefinition/@jcr:requiredPrimaryTypes]
+// +- string values (limited to names)
+// +- DEFAULT_PRIMARY_TYPE
[nt:childNodeDefinition/@jcr:defaultPrimaryType]
+// +- string value (limited to a name)
+// +- MANDATORY
[nt:childNodeDefinition/@jcr:mandatory]
+// +- string containing boolean value (or false if not present)
+// +- AUTO_CREATED
[nt:childNodeDefinition/@jcr:autoCreated]
+// +- string containing boolean value (or false if not present)
+// +- PROTECTED
[nt:childNodeDefinition/@jcr:protected]
+// +- string containing boolean value (or false if not present)
+// +- SAME_NAME_SIBLINGS
[nt:childNodeDefinition/@jcr:sameNameSiblings]
+// +- string containing boolean value (or false if not present)
+// +- ON_PARENT_VERSION
[nt:childNodeDefinition/@jcr:onParentVersion]
+// +- string value (limited to one of the predefined literal values)
+//
+// Comments
+// --------
+// The JSR-283 specification states that comments are allowed in CND files but are to be
removed prior
+// to parsing and processing. This grammar accomplishes this by sending the
MULTI_LINE_COMMENT and
+// SINGLE_LINE_COMMENT tokens to the HIDDEN channel (along with all whitespace tokens).
+//
+// Case sensitivity
+// ----------------
+// ANTLR 3 has no way of generating a case-insensitive lexer/parser (since this is
dependent upon locale).
+// However, it's possible to do this as outlined at
http://www.antlr.org/wiki/pages/viewpage.action?pageId=1782.
+// Note that the approach that overrides the "LT" method does not change the
content but merely changes the
+// character returned by the method, which are the characters used to match the rules.
+//
+// And this must be done for this grammar, since the CND tokens are case-insensitive.
Note that this
+// grammar defines all tokens as lower-case, so the ANTLRFileStream subclass must perform
a 'toLowerCase()'
+// rather than a 'toUpperCase()'.
+//
+// Post Processing
+// ---------------
+// A number of the values in the AST must be post-processed to perform the requisite
validation.
+//
+// The string values may or may not be wrapped in quotes (single or double). Any quotes
will
+// need to be removed in post-processing.
+//
+// Also, the QUERY_OPERATORS string value should contain a comma-separated list of
operators
+// wrapped by single quotes. As noted below, this is a side effect of how this
grammar's lexer
+// automatically produces a STRING token whenever single-quoted strings are found, so by
the
+// time the parser rules are run, the operators are encapsulated in a STRING token.
+// (It's arguable whether this is a defect in the CND grammar, or a side effect of
how this grammar
+// uses ANTLR; other parser and lexer rules were considered, but most caused a massive
increase in
+// the size of the generated code and a massive decrease in performance.) In short,
these
+// operators must be validated in a post-processing step.
+//
+// Generating JCR content
+// ----------------------
+//
+// The resulting AST's structure was designed such that it directly corresponds to
the "nt:nodeType",
+// "nt:propertyDefinition", and "nt:childNodeDefinition" node types
that are specified in JSR-283
+// (proposed draft), in the hopes that this approach could be used with a
"standard" AST tree walker
+// that could automatically generate the JCR content.
+//
+// First of all, the structure follows a repeating multi-level pattern, where the
"NODE" appears
+// in the AST when a new node should be created, with JCR properties
+// identified by AST nodes under "NODE" that have a single child (e.g., the
property's value),
+// or with JCR child nodes identified by AST nodes under "NODE" that also
contain an AST "NODE"
+// (with properties below it).
+//
+// The AST node names were designed to be easily translated into property names. ANTLR
uses
+// all-caps for AST node names and '_' to separate words in those names. To
produce the JCR name,
+// simply convert the first word to lowercase, and convert to lowercase all but the first
character
+// of each remaining word, and finally remove all '_' characters.
+//
+// This grammar (mostly) uses the "jcr" prefix (the namespaces should probably
be "dna").
+// This could be automated by defining a mapping between the AST node names and the
property names
+// (as well as defining a default namespace for any AST node name that is to be converted
automatically).
+//
+cnd : (namespaceMapping|nodeTypeDefinition)* EOF
+ -> ^(NAMESPACES namespaceMapping*)? ^(NODE_TYPES nodeTypeDefinition*)? ;
+
+// Namespace mappings
+namespaceMapping : '<' prefix '=' uri '>' -> ^(NODE
prefix uri);
+prefix : STRING -> ^(PREFIX STRING);
+uri : STRING -> ^(URI STRING);
+
+// Node type definitions
+nodeTypeDefinition : nodeTypeName supertypes? nodeTypeOptions? ( propertyDefinition |
childNodeDefinition )*
+ -> ^(NODE nodeTypeName ^(PRIMARY_TYPE STRING["nt:nodeType"]) supertypes?
nodeTypeOptions? ^(PROPERTY_DEFINITION propertyDefinition*) ^(CHILD_NODE_DEFINITION
childNodeDefinition*)) ;
+nodeTypeName : '[' STRING ']' -> ^(NAME STRING) ;
+supertypes : '>' stringList -> ^(SUPERTYPES stringList);
+nodeTypeOptions : nodeTypeOption+;
+nodeTypeOption : orderable | mixin | isAbstract | noQuery | primaryItem ;
+orderable : ('o'|'ord'|'orderable') ->
^(HAS_ORDERABLE_CHILD_NODES STRING["true"]);
+mixin : ('m' | 'mix' | 'mixin') -> ^(IS_MIXIN
STRING["true"]);
+isAbstract : ('a'|'abs'|'abstract') -> ^(IS_ABSTRACT
STRING["true"]);
+noQuery : ('nq'|'noquery') -> ^(IS_QUERYABLE
STRING["false"]);
+primaryItem : ('primaryitem'|'!') STRING -> ^(PRIMARY_ITEM_NAME
STRING);
+
+// Property definitions ...
+propertyDefinition : propertyName propertyType? defaultValues? ( propertyAttributes |
valueConstraints )*
+ -> ^(NODE propertyName ^(PRIMARY_TYPE STRING["nt:propertyDefinition"])
propertyType? defaultValues? propertyAttributes* valueConstraints*);
+propertyName : '-' STRING -> ^(NAME STRING);
+propertyType : '(' propertyTypeLiteral ')' -> ^(REQUIRED_TYPE
propertyTypeLiteral);
+propertyTypeLiteral :
('string'|'binary'|'long'|'double'|'boolean'|'date'|'name'|'path'|'reference'|'*');
+defaultValues : '=' stringList -> ^(DEFAULT_VALUES stringList);
+propertyAttributes : ( (onParentVersioningLiteral)=>onParentVersioning |
(autoCreated)=> autoCreated | (multiple)=>multiple | (mandatory)=>mandatory |
(isProtected)=>isProtected | (queryOperators)=>queryOperators |
(noFullText)=>noFullText | (noQueryOrder)=>noQueryOrder)+ ;
+//propertyAttributes : ( (onParentVersioning)=> onParentVersioning |
('a')=>autoCreated | ('m')=>mandatory |('p')=>isProtected
| ('mul'|'*')=>multiple | ('q')=>queryOperators |
('nof')=>noFullText | ('nqord'|'noq')=>noQueryOrder)+ ;
+valueConstraints : '<' stringList -> ^(VALUE_CONSTRAINTS stringList);
+autoCreated : ('a'|'aut'|'autocreated') -> ^(AUTO_CREATED
STRING["true"]);
+mandatory : ('m'|'man'|'mandatory') -> ^(MANDATORY
STRING["true"]);
+isProtected : ('p'|'pro'|'protected') -> ^(PROTECTED
STRING["true"]);
+onParentVersioning : onParentVersioningLiteral -> ^(ON_PARENT_VERSION
onParentVersioningLiteral);
+onParentVersioningLiteral :
('copy'|'version'|'initialize'|'compute'|'ignore'|'abort');
+multiple : ('*'|'mul'|'multiple') -> ^(MULTIPLE
STRING["true"]);
+noFullText : ('nof'|'nofulltext') -> ^(IS_FULL_TEXT_SEARCHABLE
STRING["false"]);
+noQueryOrder : ('nqord'|'noqueryorder') -> ^(IS_QUERY_ORDERERABLE
STRING["false"]);
+queryOperators : ('qop'|'queryops') STRING -> ^(QUERY_OPERATORS
STRING);
+// The grammar defines the query operators to be wrapped by single quotes, and therefore
the lexer produces a single STRING token.
+// Since we cannot break this token up, we simply store the operators as a STRING
literal, and will have to process
+// at a later step.
+
+// Child node definitions ...
+childNodeDefinition : nodeName requiredTypes? defaultType? nodeAttributes?
+ -> ^(NODE nodeName ^(PRIMARY_TYPE STRING["nt:childNodeDefinition"])
requiredTypes? defaultType? nodeAttributes?);
+nodeName : '+' STRING -> ^(NAME STRING);
+requiredTypes :'(' stringList ')' -> ^(REQUIRED_PRIMARY_TYPES
stringList);
+defaultType : '=' STRING -> ^(DEFAULT_PRIMARY_TYPE STRING);
+nodeAttributes : nodeAttribute+;
+nodeAttribute : autoCreated | mandatory | isProtected | onParentVersioning | sns ;
+sns : ('sns'|'*') -> ^(SAME_NAME_SIBLINGS STRING["true"]) ;
+
+// General rules
+stringList : STRING (',' STRING )* -> STRING*;
+
+// ------------
+// Lexer rules
+// ------------
+
+// Comments are currently sent to a separate channel
+MULTI_LINE_COMMENT : ('/*' (options {greedy=false;} : . )* '*/') {
$channel=HIDDEN;};
+SINGLE_LINE_COMMENT : '//' ~('\n' | '\r')* { $channel=HIDDEN;};
+
+// Quoted strings allow for strings containing characters that otherwise would be CND
delimiters.
+// Note that the single- and double-quote characters must be escaped within the string.
+// Also note that escape sequences are allowed as well.
+STRING : QUOTED_STRING | UNQUOTED_STRING;
+
+// Quoted strings may contain escaped characters.
+fragment QUOTED_STRING
+ : '"' ( EscapeSequence | ~('\\'|'"'))*
'"'
+ | '\'' ( EscapeSequence | ~('\\'|'\''))*
'\''
+ ;
+
+fragment EscapeSequence
+ : '\\'
('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\'
+ |('0'..'3') (('0'..'7')
('0'..'7')?)?
+ |'u'(('0'..'9')|('a'..'f'))
(('0'..'9')|('a'..'f'))
(('0'..'9')|('a'..'f'))
+ )
+;
+
+// An unquoted string is a word delimited by whitespace and CND tokens.
+fragment UNQUOTED_STRING
+: (~(' '|'\r'|'\t'|'\u000C'|'\n' // whitespace
+
|'='|'<'|'>'|'['|']'|','|'-'|'('|')' //
tokens
+ ))+;
+
+WS : ('
'|'\r'|'\t'|'\u000C'|'\n')+ {$channel=HIDDEN;} ;
+
+
Added: trunk/dna-cnd/src/main/antlr3/org/jboss/dna/cnd/Cnd.g
===================================================================
--- trunk/dna-cnd/src/main/antlr3/org/jboss/dna/cnd/Cnd.g (rev 0)
+++ trunk/dna-cnd/src/main/antlr3/org/jboss/dna/cnd/Cnd.g 2009-04-20 19:07:48 UTC (rev
840)
@@ -0,0 +1,368 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 {
+ output=AST;
+}
+
+
+tokens {
+ NAMESPACES;
+ PREFIX;
+ URI;
+ NODE;
+ NAME;
+ PRIMARY_TYPE;
+ SUPERTYPES;
+ NODE_TYPES;
+ NODE_TYPE_ATTRIBUTES;
+ HAS_ORDERABLE_CHILD_NODES;
+ IS_MIXIN;
+ IS_ABSTRACT;
+ IS_QUERYABLE;
+ PRIMARY_ITEM_NAME;
+ PROPERTY_DEFINITION;
+ REQUIRED_TYPE;
+ DEFAULT_VALUES;
+ VALUE_CONSTRAINTS;
+ AUTO_CREATED;
+ MANDATORY;
+ PROTECTED;
+ REQUIRED_TYPE;
+ ON_PARENT_VERSION;
+ MULTIPLE;
+ IS_PRIMARY_PROPERTY;
+ QUERY_OPERATORS;
+ IS_FULL_TEXT_SEARCHABLE;
+ IS_QUERY_ORDERERABLE;
+ CHILD_NODE_DEFINITION;
+ REQUIRED_PRIMARY_TYPES;
+ DEFAULT_PRIMARY_TYPE;
+ SAME_NAME_SIBLINGS;
+}
+
+@header {
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.cnd;
+}
+
+@members {
+@Override
+public void emitErrorMessage( String msg ) {
+ // don't write messages to System.err ...
+ //super.emitErrorMessage(msg);
+}
+}
+
+@lexer::header {
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.cnd;
+}
+
+@rulecatch {
+ catch (RecognitionException re) {
+ reportError(re);
+ }
+}
+
+// ------------
+// Parser rules
+// ------------
+
+// These rules generate an AST that was designed with a structure that may be
+// automatically processed into a graph structure. This structure is:
+//
+// NAMESPACES
+// +- NODE (multiple)
+// +- PREFIX
+// +- string value
+// +- URI
+// +- string value
+// NODE_TYPES
+// +- NODE (multiple)
+// +- NAME [nt:nodeType/@jcr:name]
+// +- string value
+// +- PRIMARY_TYPE [nt:base/@jcr:primaryType]
+// +- string with value 'nt:nodeType'
+// +- SUPERTYPES [nt:nodeType/@jcr:supertypes]
+// +- string value(s)
+// +- IS_ABSTRACT [nt:nodeType/@jcr:isAbstract]
+// +- string containing boolean value (or false if not present)
+// +- HAS_ORDERABLE_CHILD_NODES
[nt:nodeType/@jcr:hasOrderableChildNodes]
+// +- string containing boolean value (or false if not present)
+// +- IS_MIXIN [nt:nodeType/@jcr:isMixin]
+// +- string containing boolean value (or false if not present)
+// +- IS_QUERYABLE [nt:nodeType/@jcr:isQueryable]
+// +- string containing boolean value (or true if not present)
+// +- PRIMARY_ITEM_NAME [nt:nodeType/@jcr:primaryItemName]
+// +- string containing string value
+// +- PROPERTY_DEFINITION [nt:nodeType/@jcr:propertyDefinition]
+// +- NODE (multiple)
+// +- NAME [nt:propertyDefinition/@jcr:name]
+// +- string value
+// +- PRIMARY_TYPE [nt:base/@jcr:primaryType]
+// +- string with value 'nt:propertyDefinition'
+// +- REQUIRED_TYPE
[nt:propertyDefinition/@jcr:propertyType]
+// +- string value (limited to one of the predefined types)
+// +- DEFAULT_VALUES
[nt:propertyDefinition/@jcr:defaultValues]
+// +- string value(s)
+// +- MULTIPLE [nt:propertyDefinition/@jcr:multiple]
+// +- string containing boolean value (or false if not present)
+// +- MANDATORY [nt:propertyDefinition/@jcr:mandatory]
+// +- string containing boolean value (or false if not present)
+// +- AUTO_CREATED
[nt:propertyDefinition/@jcr:autoCreated]
+// +- string containing boolean value (or false if not present)
+// +- PROTECTED [nt:propertyDefinition/@jcr:protected]
+// +- string containing boolean value (or false if not present)
+// +- ON_PARENT_VERSION
[nt:propertyDefinition/@jcr:onParentVersion]
+// +- string value (limited to one of the predefined literal values)
+// +- QUERY_OPERATORS
+// +- string value (containing a comma-separated list of operator
literals)
+// +- IS_FULL_TEXT_SEARCHABLE
[nt:propertyDefinition/@jcr:isFullTextSearchable]
+// +- string containing boolean value (or true if not present)
+// +- IS_QUERY_ORDERABLE
[nt:propertyDefinition/@jcr:isQueryOrderable]
+// +- string containing boolean value (or true if not present)
+// +- VALUE_CONSTRAINTS
[nt:propertyDefinition/@jcr:valueConstraints]
+// +- string value(s)
+// +- CHILD_NODE_DEFINITION [nt:nodeType/@jcr:childNodeDefinition]
+// +- NODE (multiple)
+// +- NAME [nt:childNodeDefinition/@jcr:name]
+// +- string value
+// +- PRIMARY_TYPE [nt:base/@jcr:primaryType]
+// +- string with value 'nt:childNodeDefinition'
+// +- REQUIRED_PRIMARY_TYPES
[nt:childNodeDefinition/@jcr:requiredPrimaryTypes]
+// +- string values (limited to names)
+// +- DEFAULT_PRIMARY_TYPE
[nt:childNodeDefinition/@jcr:defaultPrimaryType]
+// +- string value (limited to a name)
+// +- MANDATORY
[nt:childNodeDefinition/@jcr:mandatory]
+// +- string containing boolean value (or false if not present)
+// +- AUTO_CREATED
[nt:childNodeDefinition/@jcr:autoCreated]
+// +- string containing boolean value (or false if not present)
+// +- PROTECTED
[nt:childNodeDefinition/@jcr:protected]
+// +- string containing boolean value (or false if not present)
+// +- SAME_NAME_SIBLINGS
[nt:childNodeDefinition/@jcr:sameNameSiblings]
+// +- string containing boolean value (or false if not present)
+// +- ON_PARENT_VERSION
[nt:childNodeDefinition/@jcr:onParentVersion]
+// +- string value (limited to one of the predefined literal values)
+//
+// JSR-283 node types
+// ------------------
+// This grammar does support reading in the new 'decimal',
'weakreference' and 'uri' property types. Therefore, it
+// is up to the calling component to verify that these types are allowed. Supporting
these new types means
+// that this CND grammar can be used for both JSR-170 and JSR-283.
+//
+// Comments
+// --------
+// The JSR-283 specification states that comments are allowed in CND files but are to be
removed prior
+// to parsing and processing. This grammar accomplishes this by sending the
MULTI_LINE_COMMENT and
+// SINGLE_LINE_COMMENT tokens to the HIDDEN channel (along with all whitespace tokens).
+//
+// Case sensitivity
+// ----------------
+// ANTLR 3 has no way of generating a case-insensitive lexer/parser (since this is
dependent upon locale).
+// However, it's possible to do this as outlined at
http://www.antlr.org/wiki/pages/viewpage.action?pageId=1782.
+// Note that the approach that overrides the "LT" method does not change the
content but merely changes the
+// character returned by the method, which are the characters used to match the rules.
+//
+// And this must be done for this grammar, since the CND tokens are case-insensitive.
Note that this
+// grammar defines all tokens as lower-case, so the ANTLRFileStream subclass must perform
a 'toLowerCase()'
+// rather than a 'toUpperCase()'.
+//
+// Post Processing
+// ---------------
+// A number of the values in the AST must be post-processed to perform the requisite
validation.
+//
+// The string values may or may not be wrapped in quotes (single or double). Any quotes
will
+// need to be removed in post-processing.
+//
+// Also, the QUERY_OPERATORS string value should contain a comma-separated list of
operators
+// wrapped by single quotes. As noted below, this is a side effect of how this
grammar's lexer
+// automatically produces a STRING token whenever single-quoted strings are found, so by
the
+// time the parser rules are run, the operators are encapsulated in a STRING token.
+// (It's arguable whether this is a defect in the CND grammar, or a side effect of
how this grammar
+// uses ANTLR; other parser and lexer rules were considered, but most caused a massive
increase in
+// the size of the generated code and a massive decrease in performance.) In short,
these
+// operators must be validated in a post-processing step.
+//
+// Generating JCR content
+// ----------------------
+//
+// The resulting AST's structure was designed such that it directly corresponds to
the "nt:nodeType",
+// "nt:propertyDefinition", and "nt:childNodeDefinition" node types
that are specified in JSR-283
+// (proposed draft), in the hopes that this approach could be used with a
"standard" AST tree walker
+// that could automatically generate the JCR content.
+//
+// First of all, the structure follows a repeating multi-level pattern, where the
"NODE" appears
+// in the AST when a new node should be created, with JCR properties
+// identified by AST nodes under "NODE" that have a single child (e.g., the
property's value),
+// or with JCR child nodes identified by AST nodes under "NODE" that also
contain an AST "NODE"
+// (with properties below it).
+//
+// The AST node names were designed to be easily translated into property names. ANTLR
uses
+// all-caps for AST node names and '_' to separate words in those names. To
produce the JCR name,
+// simply convert the first word to lowercase, and convert to lowercase all but the first
character
+// of each remaining word, and finally remove all '_' characters.
+//
+// This grammar (mostly) uses the "jcr" prefix (the namespaces should probably
be "dna").
+// This could be automated by defining a mapping between the AST node names and the
property names
+// (as well as defining a default namespace for any AST node name that is to be converted
automatically).
+//
+cnd : (namespaceMapping|nodeTypeDefinition)* EOF
+ -> ^(NAMESPACES namespaceMapping*)? ^(NODE_TYPES nodeTypeDefinition*)? ;
+
+// Namespace mappings
+namespaceMapping : '<' prefix '=' uri '>' -> ^(NODE
prefix uri);
+prefix :
+ | 'mix' -> ^(PREFIX 'mix') // Must break out this built-in prefix
because it happens to be a keyword
+ | STRING -> ^(PREFIX STRING);
+uri : STRING -> ^(URI STRING);
+
+// Node type definitions
+nodeTypeDefinition : nodeTypeName supertypes? nodeTypeOptions? ( propertyDefinition |
childNodeDefinition )*
+ -> ^(NODE nodeTypeName ^(PRIMARY_TYPE STRING["nt:nodeType"]) supertypes?
nodeTypeOptions? ^(PROPERTY_DEFINITION propertyDefinition*) ^(CHILD_NODE_DEFINITION
childNodeDefinition*)) ;
+nodeTypeName : '[' STRING ']' -> ^(NAME STRING) ;
+supertypes : '>' stringList -> ^(SUPERTYPES stringList);
+nodeTypeOptions : nodeTypeOption+;
+nodeTypeOption : orderable | mixin | isAbstract | noQuery | primaryItem ;
+orderable : ('o'|'ord'|'orderable') ->
^(HAS_ORDERABLE_CHILD_NODES STRING["true"]);
+mixin : ('m' | 'mix' | 'mixin') -> ^(IS_MIXIN
STRING["true"]);
+isAbstract : ('a'|'abs'|'abstract') -> ^(IS_ABSTRACT
STRING["true"]);
+noQuery : ('nq'|'noquery') -> ^(IS_QUERYABLE
STRING["false"]);
+primaryItem : ('primaryitem'|'!') STRING -> ^(PRIMARY_ITEM_NAME
STRING);
+
+// Property definitions ...
+propertyDefinition : propertyName propertyType? defaultValues? ( propertyAttributes |
valueConstraints )*
+ -> ^(NODE propertyName ^(PRIMARY_TYPE STRING["nt:propertyDefinition"])
propertyType? defaultValues? propertyAttributes* valueConstraints*);
+propertyName : '-' ('*' -> ^(NAME '*') | STRING -> ^(NAME
STRING));
+propertyType : '(' propertyTypeLiteral ')' -> ^(REQUIRED_TYPE
propertyTypeLiteral);
+propertyTypeLiteral :
('string'|'binary'|'long'|'double'|'boolean'|'decimal'|'date'|'name'|'path'|'reference'|'*'|'undefined'|'weakreference'|'uri');
+defaultValues : '=' stringList -> ^(DEFAULT_VALUES stringList);
+propertyAttributes : ( (isPrimary)=>isPrimary |
(onParentVersioningLiteral)=>onParentVersioning | (autoCreated)=> autoCreated |
(multiple)=>multiple | (mandatory)=>mandatory | (isProtected)=>isProtected |
(queryOperators)=>queryOperators | (noFullText)=>noFullText |
(noQueryOrder)=>noQueryOrder)+ ;
+//propertyAttributes : ( (onParentVersioning)=> onParentVersioning |
('a')=>autoCreated | ('m')=>mandatory |('p')=>isProtected
| ('mul'|'*')=>multiple | ('q')=>queryOperators |
('nof')=>noFullText | ('nqord'|'noq')=>noQueryOrder)+ ;
+valueConstraints : '<' stringList -> ^(VALUE_CONSTRAINTS stringList);
+isPrimary : ('!'|'pri'|'primary') -> ^(IS_PRIMARY_PROPERTY
STRING["true"]);
+autoCreated : ('a'|'aut'|'autocreated') -> ^(AUTO_CREATED
STRING["true"]);
+mandatory : ('m'|'man'|'mandatory') -> ^(MANDATORY
STRING["true"]);
+isProtected : ('p'|'pro'|'protected') -> ^(PROTECTED
STRING["true"]);
+onParentVersioning : onParentVersioningLiteral -> ^(ON_PARENT_VERSION
onParentVersioningLiteral);
+onParentVersioningLiteral :
('copy'|'version'|'initialize'|'compute'|'ignore'|'abort');
+multiple : ('*'|'mul'|'multiple') -> ^(MULTIPLE
STRING["true"]);
+noFullText : ('nof'|'nofulltext') -> ^(IS_FULL_TEXT_SEARCHABLE
STRING["false"]);
+noQueryOrder : ('nqord'|'noqueryorder') -> ^(IS_QUERY_ORDERERABLE
STRING["false"]);
+queryOperators : ('qop'|'queryops') STRING -> ^(QUERY_OPERATORS
STRING);
+// The grammar defines the query operators to be wrapped by single quotes, and therefore
the lexer produces a single STRING token.
+// Since we cannot break this token up, we simply store the operators as a STRING
literal, and will have to process
+// at a later step.
+
+// Child node definitions ...
+childNodeDefinition : nodeName requiredTypes? defaultType? nodeAttributes?
+ -> ^(NODE nodeName ^(PRIMARY_TYPE STRING["nt:childNodeDefinition"])
requiredTypes? defaultType? nodeAttributes?);
+nodeName : '+' ('*' -> ^(NAME '*') | STRING -> ^(NAME
STRING));
+requiredTypes :'(' stringList ')' -> ^(REQUIRED_PRIMARY_TYPES
stringList);
+defaultType : '=' STRING -> ^(DEFAULT_PRIMARY_TYPE STRING);
+nodeAttributes : nodeAttribute+;
+nodeAttribute : autoCreated | mandatory | (isPrimary)=>isPrimary|
(isProtected)=>isProtected | onParentVersioning | sns ;
+sns : ('sns'|'*'|'multiple') -> ^(SAME_NAME_SIBLINGS
STRING["true"]) ;
+
+// General rules
+stringList : STRING (',' STRING )* -> STRING*;
+
+// ------------
+// Lexer rules
+// ------------
+
+// Comments are currently sent to a separate channel
+MULTI_LINE_COMMENT : ('/*' (options {greedy=false;} : . )* '*/') {
$channel=HIDDEN;};
+SINGLE_LINE_COMMENT : '//' ~('\n' | '\r')* { $channel=HIDDEN;};
+
+// Quoted strings allow for strings containing characters that otherwise would be CND
delimiters.
+// Note that the single- and double-quote characters must be escaped within the string.
+// Also note that escape sequences are allowed as well.
+STRING : QUOTED_STRING | UNQUOTED_STRING;
+
+// Quoted strings may contain escaped characters.
+fragment QUOTED_STRING
+ : '"' ( EscapeSequence | ~('\\'|'"'))*
'"'
+ | '\'' ( EscapeSequence | ~('\\'|'\''))*
'\''
+ ;
+
+fragment EscapeSequence
+ : '\\'
('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\'
+ |('0'..'3') (('0'..'7')
('0'..'7')?)?
+ |'u'(('0'..'9')|('a'..'f'))
(('0'..'9')|('a'..'f'))
(('0'..'9')|('a'..'f'))
+ )
+;
+
+// An unquoted string is a word delimited by whitespace and CND tokens.
+fragment UNQUOTED_STRING
+: (~(' '|'\r'|'\t'|'\u000C'|'\n' //
whitespace
+
|'='|'<'|'>'|'['|']'|','|'-'|'('|')'
// tokens
+ ))+;
+
+WS : (' '|'\r'|'\t'|'\u000C'|'\n')+
{$channel=HIDDEN;} ;
\ No newline at end of file
Added: trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/CndI18n.java
===================================================================
--- trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/CndI18n.java
(rev 0)
+++ trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/CndI18n.java 2009-04-20 19:07:48 UTC
(rev 840)
@@ -0,0 +1,51 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+* See the AUTHORS.txt file in the distribution for a full listing of
+* individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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.cnd;
+
+import org.jboss.dna.common.i18n.I18n;
+
+/**
+ * @author John Verhaeg
+ * @author Randall Hauch
+ */
+public final class CndI18n {
+
+ public static I18n passthrough;
+ public static I18n errorImportingCndContent;
+ public static I18n expectedBooleanLiteral;
+ public static I18n expectedStringLiteral;
+ public static I18n expectedValidNameLiteral;
+ public static I18n expectedValidQueryOperator;
+ public static I18n expectedValidPropertyTypeName;
+ public static I18n expectedValidOnParentVersion;
+ public static I18n locationFromLineNumberAndCharacter;
+
+ static {
+ try {
+ I18n.initialize(CndI18n.class);
+ } catch (final Exception err) {
+ System.err.println(err);
+ }
+ }
+}
Added: trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/CndImporter.java
===================================================================
--- trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/CndImporter.java
(rev 0)
+++ trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/CndImporter.java 2009-04-20 19:07:48 UTC
(rev 840)
@@ -0,0 +1,743 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * Unless otherwise indicated, all code in JBoss DNA is licensed
+ * to you 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.
+ *
+ * JBoss DNA 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.cnd;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import net.jcip.annotations.NotThreadSafe;
+import org.antlr.runtime.ANTLRFileStream;
+import org.antlr.runtime.ANTLRInputStream;
+import org.antlr.runtime.CharStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RecognitionException;
+import org.antlr.runtime.TokenStream;
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.tree.RewriteCardinalityException;
+import org.jboss.dna.common.collection.Problems;
+import org.jboss.dna.common.i18n.I18n;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.JcrLexicon;
+import org.jboss.dna.graph.JcrNtLexicon;
+import org.jboss.dna.graph.io.Destination;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.NameFactory;
+import org.jboss.dna.graph.property.NamespaceRegistry;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.PathFactory;
+import org.jboss.dna.graph.property.PropertyFactory;
+import org.jboss.dna.graph.property.ValueFactory;
+import org.jboss.dna.graph.property.ValueFormatException;
+import org.jboss.dna.graph.property.basic.LocalNamespaceRegistry;
+
+/**
+ * A class that imports the node types contained in a JCR Compact Node Definition (CND)
file into graph content. The content is
+ * written using the graph structured defined by JCR and the "{@code
nt:nodeType}", "{@code nt:propertyDefinition}", and "{@code
+ * nt:childNodeDefinition}" node types.
+ * <p>
+ * Although instances of this class never change their behavior and all processing is
done in local contexts, {@link Destination}
+ * is not thread-safe and therefore this component may not be considered thread-safe.
+ * </p>
+ */
+@NotThreadSafe
+public class CndImporter {
+
+ private static final Set<String> VALID_PROPERTY_TYPES =
Collections.unmodifiableSet(new HashSet<String>(
+
Arrays.asList(new String[] {
+
"STRING",
+
"BINARY", "LONG",
+
"DOUBLE",
+
"BOOLEAN",
+
"DECIMAL",
+
"DATE", "NAME",
+
"PATH",
+
"REFERENCE",
+
"WEAKREFERENCE",
+
"URI",
+
"UNDEFINED"})));
+ private static final Set<String> VALID_ON_PARENT_VERSION =
Collections.unmodifiableSet(new HashSet<String>(
+
Arrays.asList(new String[] {
+
"COPY",
+
"VERSION",
+
"INITIALIZE",
+
"COMPUTE",
+
"IGNORE",
+
"ABORT"})));
+ protected final Destination destination;
+ protected final Path parentPath;
+ private boolean debug = false;
+
+ /**
+ * Create a new importer that will place the content in the supplied destination
under the supplied path.
+ *
+ * @param destination the destination where content is to be written
+ * @param parentPath the path in the destination below which the generated content is
to appear
+ * @throws IllegalArgumentException if either parameter is null
+ */
+ public CndImporter( Destination destination,
+ Path parentPath ) {
+ CheckArg.isNotNull(destination, "destination");
+ CheckArg.isNotNull(parentPath, "parentPath");
+ this.destination = destination;
+ this.parentPath = parentPath;
+ }
+
+ void setDebug( boolean value ) {
+ this.debug = value;
+ }
+
+ protected ExecutionContext context() {
+ return this.destination.getExecutionContext();
+ }
+
+ protected NamespaceRegistry namespaces() {
+ return context().getNamespaceRegistry();
+ }
+
+ protected NameFactory nameFactory() {
+ return context().getValueFactories().getNameFactory();
+ }
+
+ protected ValueFactory<String> stringFactory() {
+ return context().getValueFactories().getStringFactory();
+ }
+
+ protected ValueFactory<Boolean> booleanFactory() {
+ return context().getValueFactories().getBooleanFactory();
+ }
+
+ /**
+ * Import the CND content from the supplied stream, placing the content into the
importer's destination.
+ *
+ * @param stream the stream containing the CND content
+ * @param problems where any problems encountered during import should be reported
+ * @param resourceName a logical name for the resource name to be used when reporting
problems; may be null if there is no
+ * useful name
+ * @throws IOException if there is a problem reading from the supplied stream
+ */
+ public void importFrom( InputStream stream,
+ Problems problems,
+ String resourceName ) throws IOException {
+ CndLexer lex = new CndLexer(new CaseInsensitiveInputStream(stream));
+ importFrom(lex, resourceName, problems);
+ }
+
+ /**
+ * Import the CND content from the supplied stream, placing the content into the
importer's destination.
+ *
+ * @param content the string containing the CND content
+ * @param problems where any problems encountered during import should be reported
+ * @param resourceName a logical name for the resource name to be used when reporting
problems; may be null if there is no
+ * useful name
+ * @throws IOException if there is a problem reading from the supplied stream
+ */
+ public void importFrom( String content,
+ Problems problems,
+ String resourceName ) throws IOException {
+ ByteArrayInputStream stream = new ByteArrayInputStream(content.getBytes());
+ importFrom(stream, problems, resourceName);
+ }
+
+ /**
+ * Import the CND content from the supplied stream, placing the content into the
importer's destination.
+ *
+ * @param file the file containing the CND content
+ * @param problems where any problems encountered during import should be reported
+ * @throws IOException if there is a problem reading from the supplied stream
+ */
+ public void importFrom( File file,
+ Problems problems ) throws IOException {
+ CndLexer lex = new CndLexer(new
CaseInsensitiveFileStream(file.getAbsolutePath()));
+ importFrom(lex, file.getCanonicalPath(), problems);
+ }
+
+ protected void importFrom( CndLexer lexer,
+ String resourceName,
+ Problems problems ) {
+ CommonTokenStream tokens = new CommonTokenStream(lexer);
+ CndParser parser = new Parser(tokens, problems, resourceName);
+
+ // Create a new context with our own namespace registry ...
+ ImportContext context = new ImportContext(context(), problems, resourceName);
+ CommonTree ast = null;
+ try {
+ ast = (CommonTree)parser.cnd().getTree();
+ } catch (RecognitionException e) {
+ // already handled by Parser, so we should not handle twice
+ } catch (RewriteCardinalityException e) {
+ // already handled by Parser, so we should not handle twice
+ } catch (RuntimeException e) {
+ problems.addError(e, CndI18n.errorImportingCndContent, (Object)resourceName,
e.getMessage());
+ }
+
+ if (ast != null && problems.isEmpty()) {
+
+ // --------------
+ // Namespaces ...
+ // --------------
+
+ /*
+ NAMESPACES
+ +- NODE (multiple)
+ +- PREFIX
+ +- string value
+ +- URI
+ +- string value
+ */
+
+ // Get the namespaces before we do anything else ...
+ CommonTree namespaces =
(CommonTree)ast.getFirstChildWithType(CndLexer.NAMESPACES);
+ if (namespaces != null) {
+ for (int i = 0; i != namespaces.getChildCount(); ++i) {
+ CommonTree namespace = (CommonTree)namespaces.getChild(i);
+ String prefix =
namespace.getFirstChildWithType(CndLexer.PREFIX).getChild(0).getText();
+ String uri =
namespace.getFirstChildWithType(CndLexer.URI).getChild(0).getText();
+ // Register the namespace ...
+ context.namespaces().register(removeQuotes(prefix),
removeQuotes(uri));
+ }
+ }
+
+ // --------------
+ // Node Types ...
+ // --------------
+
+ /*
+ NODE_TYPES
+ +- NODE (multiple)
+ +- NAME [nt:nodeType/@jcr:name]
+ +- string value
+ +- PRIMARY_TYPE [nt:base/@jcr:primaryType]
+ +- string with value 'nt:nodeType'
+ +- SUPERTYPES [nt:nodeType/@jcr:supertypes]
+ +- string value(s)
+ +- IS_ABSTRACT [nt:nodeType/@jcr:isAbstract]
+ +- string containing boolean value (or false if not present)
+ +- HAS_ORDERABLE_CHILD_NODES
[nt:nodeType/@jcr:hasOrderableChildNodes]
+ +- string containing boolean value (or false if not present)
+ +- IS_MIXIN [nt:nodeType/@jcr:isMixin]
+ +- string containing boolean value (or false if not present)
+ +- IS_QUERYABLE [nt:nodeType/@jcr:isQueryable]
+ +- string containing boolean value (or true if not present)
+ +- PRIMARY_ITEM_NAME
[nt:nodeType/@jcr:primaryItemName]
+ +- string containing string value
+ +- PROPERTY_DEFINITION
[nt:nodeType/@jcr:propertyDefinition]
+ +- NODE (multiple)
+ +- NAME
[nt:propertyDefinition/@jcr:name]
+ +- string value
+ +- PRIMARY_TYPE [nt:base/@jcr:primaryType]
+ +- string with value 'nt:propertyDefinition'
+ +- REQUIRED_TYPE
[nt:propertyDefinition/@jcr:propertyType]
+ +- string value (limited to one of the predefined types)
+ +- DEFAULT_VALUES
[nt:propertyDefinition/@jcr:defaultValues]
+ +- string value(s)
+ +- MULTIPLE
[nt:propertyDefinition/@jcr:multiple]
+ +- string containing boolean value (or false if not
present)
+ +- MANDATORY
[nt:propertyDefinition/@jcr:mandatory]
+ +- string containing boolean value (or false if not
present)
+ +- AUTO_CREATED
[nt:propertyDefinition/@jcr:autoCreated]
+ +- string containing boolean value (or false if not
present)
+ +- PROTECTED
[nt:propertyDefinition/@jcr:protected]
+ +- string containing boolean value (or false if not
present)
+ +- ON_PARENT_VERSION
[nt:propertyDefinition/@jcr:onParentVersion]
+ +- string value (limited to one of the predefined literal
values)
+ +- QUERY_OPERATORS
+ +- string value (containing a comma-separated list of
operator literals)
+ +- IS_FULL_TEXT_SEARCHABLE
[nt:propertyDefinition/@jcr:isFullTextSearchable]
+ +- string containing boolean value (or true if not present)
+ +- IS_QUERY_ORDERABLE
[nt:propertyDefinition/@jcr:isQueryOrderable]
+ +- string containing boolean value (or true if not present)
+ +- VALUE_CONSTRAINTS
[nt:propertyDefinition/@jcr:valueConstraints]
+ +- string value(s)
+ +- CHILD_NODE_DEFINITION
[nt:nodeType/@jcr:childNodeDefinition]
+ +- NODE (multiple)
+ +- NAME
[nt:childNodeDefinition/@jcr:name]
+ +- string value
+ +- PRIMARY_TYPE [nt:base/@jcr:primaryType]
+ +- string with value 'nt:childNodeDefinition'
+ +- REQUIRED_PRIMARY_TYPES
[nt:childNodeDefinition/@jcr:requiredPrimaryTypes]
+ +- string values (limited to names)
+ +- DEFAULT_PRIMARY_TYPE
[nt:childNodeDefinition/@jcr:defaultPrimaryType]
+ +- string value (limited to a name)
+ +- MANDATORY
[nt:childNodeDefinition/@jcr:mandatory]
+ +- string containing boolean value (or false if not
present)
+ +- AUTO_CREATED
[nt:childNodeDefinition/@jcr:autoCreated]
+ +- string containing boolean value (or false if not
present)
+ +- PROTECTED
[nt:childNodeDefinition/@jcr:protected]
+ +- string containing boolean value (or false if not
present)
+ +- SAME_NAME_SIBLINGS
[nt:childNodeDefinition/@jcr:sameNameSiblings]
+ +- string containing boolean value (or false if not
present)
+ +- ON_PARENT_VERSION
[nt:childNodeDefinition/@jcr:onParentVersion]
+ +- string value (limited to one of the predefined literal
values)
+ */
+
+ // Get the node types ...
+ CommonTree nodeTypes =
(CommonTree)ast.getFirstChildWithType(CndLexer.NODE_TYPES);
+ if (nodeTypes != null) {
+ int numNodeTypes = 0;
+ // Walk each of the nodes underneath the NODE_TYPES parent node ...
+ for (int i = 0; i != nodeTypes.getChildCount(); ++i) {
+ CommonTree nodeType = (CommonTree)nodeTypes.getChild(i);
+ if (this.debug) System.out.println(nodeType.toStringTree());
+ Path nodeTypePath = context.createNodeType(nodeType, parentPath);
+ if (nodeTypePath == null) continue;
+ ++numNodeTypes;
+
+ CommonTree propertyDefinitions =
(CommonTree)nodeType.getFirstChildWithType(CndLexer.PROPERTY_DEFINITION);
+ if (propertyDefinitions != null) {
+ // Walk each of the nodes under PROPERTY_DEFINITION ...
+ for (int j = 0; j != propertyDefinitions.getChildCount(); ++j) {
+ CommonTree propDefn =
(CommonTree)propertyDefinitions.getChild(j);
+ context.createPropertyDefinition(propDefn, nodeTypePath);
+ }
+ }
+
+ CommonTree childNodeDefinitions =
(CommonTree)nodeType.getFirstChildWithType(CndLexer.CHILD_NODE_DEFINITION);
+ if (childNodeDefinitions != null) {
+ // Walk each of the nodes under CHILD_NODE_DEFINITION ...
+ for (int j = 0; j != childNodeDefinitions.getChildCount(); ++j)
{
+ CommonTree childDefn =
(CommonTree)childNodeDefinitions.getChild(j);
+ context.createChildDefinition(childDefn, nodeTypePath);
+ }
+ }
+ }
+
+ // Submit the destination
+ destination.submit();
+ }
+ }
+ }
+
+ protected final String removeQuotes( String text ) {
+ // Remove leading and trailing quotes, if there are any ...
+ return text.replaceFirst("^['\"]+",
"").replaceAll("['\"]+$", "");
+ }
+
+ /**
+ * Utility class that uses a context with a local namespace registry, along with the
problems and resource name.
+ */
+ protected final class ImportContext {
+ private final ExecutionContext context;
+ private final Problems problems;
+ private final String resourceName;
+
+ protected ImportContext( ExecutionContext context,
+ Problems problems,
+ String resourceName ) {
+ // Create a context that has a local namespace registry
+ NamespaceRegistry localNamespaces = new
LocalNamespaceRegistry(context.getNamespaceRegistry());
+ this.context = context.with(localNamespaces);
+ this.problems = problems;
+ this.resourceName = resourceName;
+ }
+
+ protected ExecutionContext context() {
+ return this.context;
+ }
+
+ protected NamespaceRegistry namespaces() {
+ return this.context.getNamespaceRegistry();
+ }
+
+ protected NameFactory nameFactory() {
+ return this.context.getValueFactories().getNameFactory();
+ }
+
+ protected PathFactory pathFactory() {
+ return this.context.getValueFactories().getPathFactory();
+ }
+
+ protected ValueFactory<String> stringFactory() {
+ return this.context.getValueFactories().getStringFactory();
+ }
+
+ protected ValueFactory<Boolean> booleanFactory() {
+ return this.context.getValueFactories().getBooleanFactory();
+ }
+
+ protected void recordError( CommonTree node,
+ I18n msg,
+ Object... params ) {
+ String location =
CndI18n.locationFromLineNumberAndCharacter.text(node.getLine(),
node.getCharPositionInLine());
+ problems.addError(msg, resourceName, location, params);
+ }
+
+ protected void recordError( Throwable throwable,
+ CommonTree node,
+ I18n msg,
+ Object... params ) {
+ String location =
CndI18n.locationFromLineNumberAndCharacter.text(node.getLine(),
node.getCharPositionInLine());
+ problems.addError(throwable, msg, resourceName, location, params);
+ }
+
+ protected Name nameFrom( CommonTree node,
+ int childType ) {
+ CommonTree childNode = (CommonTree)node.getFirstChildWithType(childType);
+ if (childNode != null && childNode.getChildCount() > 0) {
+ CommonTree textNode = (CommonTree)childNode.getChild(0);
+ if (textNode.getToken().getTokenIndex() < 0) return null;
+ String text = removeQuotes(childNode.getChild(0).getText());
+ try {
+ return nameFactory().create(text);
+ } catch (ValueFormatException e) {
+ recordError(e, node, CndI18n.expectedValidNameLiteral, text);
+ }
+ }
+ return null;
+ }
+
+ protected Name[] namesFrom( CommonTree node,
+ int childType ) {
+ CommonTree childNode = (CommonTree)node.getFirstChildWithType(childType);
+ if (childNode != null && childNode.getChildCount() > 0) {
+ List<Name> names = new ArrayList<Name>();
+ for (int i = 0; i != childNode.getChildCount(); ++i) {
+ String text = removeQuotes(childNode.getChild(i).getText());
+ try {
+ names.add(nameFactory().create(text));
+ } catch (ValueFormatException e) {
+ recordError(e, node, CndI18n.expectedValidNameLiteral, text);
+ }
+ }
+ return names.toArray(new Name[names.size()]);
+ }
+ return new Name[] {};
+ }
+
+ protected String stringFrom( CommonTree node,
+ int childType ) {
+ CommonTree childNode = (CommonTree)node.getFirstChildWithType(childType);
+ if (childNode != null && childNode.getChildCount() > 0) {
+ String text = removeQuotes(childNode.getChild(0).getText().trim());
+ try {
+ return stringFactory().create(text);
+ } catch (ValueFormatException e) {
+ recordError(e, node, CndI18n.expectedStringLiteral, text);
+ }
+ }
+ return null;
+ }
+
+ protected String[] stringsFrom( CommonTree node,
+ int childType ) {
+ CommonTree childNode = (CommonTree)node.getFirstChildWithType(childType);
+ if (childNode != null && childNode.getChildCount() > 0) {
+ List<String> names = new ArrayList<String>();
+ for (int i = 0; i != childNode.getChildCount(); ++i) {
+ String text = removeQuotes(childNode.getChild(i).getText().trim());
+ try {
+ names.add(stringFactory().create(text));
+ } catch (ValueFormatException e) {
+ recordError(e, node, CndI18n.expectedStringLiteral, text);
+ }
+ }
+ return names.toArray(new String[names.size()]);
+ }
+ return new String[] {};
+ }
+
+ protected boolean booleanFrom( CommonTree node,
+ int childType,
+ boolean defaultValue ) {
+ CommonTree childNode = (CommonTree)node.getFirstChildWithType(childType);
+ if (childNode != null && childNode.getChildCount() > 0) {
+ String text = removeQuotes(childNode.getChild(0).getText());
+ try {
+ return booleanFactory().create(text);
+ } catch (ValueFormatException e) {
+ recordError(e, node, CndI18n.expectedBooleanLiteral, text);
+ }
+ }
+ return defaultValue;
+ }
+
+ protected QueryOperator[] queryOperatorsFrom( CommonTree node,
+ int childType ) {
+ String text = stringFrom(node, childType);
+ if (text != null) {
+ String[] literals = text.split(",");
+ if (literals.length != 0) {
+ Set<QueryOperator> operators = new
HashSet<QueryOperator>();
+ for (String literal : literals) {
+ literal = literal.trim();
+ if (literal.length() == 0) continue;
+ QueryOperator operator = QueryOperator.forText(literal);
+ if (operator != null) {
+ operators.add(operator);
+ } else {
+ recordError(node, CndI18n.expectedValidQueryOperator,
literal);
+ }
+ }
+ return operators.toArray(new QueryOperator[operators.size()]);
+ }
+ }
+ return new QueryOperator[] {};
+ }
+
+ protected String propertyTypeNameFrom( CommonTree node,
+ int childType ) {
+ String text = stringFrom(node, childType);
+ if (text.equals("*")) text = "undefined";
+ String upperText = text.toUpperCase();
+ if (!VALID_PROPERTY_TYPES.contains(upperText)) {
+ recordError(node, CndI18n.expectedValidPropertyTypeName, text,
VALID_PROPERTY_TYPES);
+ return null;
+ }
+ return upperText;
+ }
+
+ protected String onParentVersionFrom( CommonTree node,
+ int childType ) {
+ String text = stringFrom(node, childType);
+ if (text == null) return "COPY";
+ String upperText = text.toUpperCase();
+ if (!VALID_ON_PARENT_VERSION.contains(upperText)) {
+ recordError(node, CndI18n.expectedValidOnParentVersion, text,
VALID_ON_PARENT_VERSION);
+ return null;
+ }
+ return upperText;
+ }
+
+ protected Path createNodeType( CommonTree nodeType,
+ Path parentPath ) {
+ Name name = nameFrom(nodeType, CndLexer.NAME);
+ Name[] supertypes = namesFrom(nodeType, CndLexer.SUPERTYPES);
+ boolean isAbstract = booleanFrom(nodeType, CndLexer.IS_ABSTRACT, false);
+ boolean hasOrderableChildNodes = booleanFrom(nodeType,
CndLexer.HAS_ORDERABLE_CHILD_NODES, false);
+ boolean isMixin = booleanFrom(nodeType, CndLexer.IS_MIXIN, false);
+ boolean isQueryable = booleanFrom(nodeType, CndLexer.IS_QUERYABLE, true);
+ Name primaryItemName = nameFrom(nodeType, CndLexer.PRIMARY_ITEM_NAME);
+
+ if (primaryItemName == null) {
+ // See if one of the property definitions is marked as the primary ...
+ CommonTree propertyDefinitions =
(CommonTree)nodeType.getFirstChildWithType(CndLexer.PROPERTY_DEFINITION);
+ if (propertyDefinitions != null) {
+ // Walk each of the nodes under PROPERTY_DEFINITION ...
+ for (int j = 0; j != propertyDefinitions.getChildCount(); ++j) {
+ CommonTree propDefn =
(CommonTree)propertyDefinitions.getChild(j);
+ if (booleanFrom(propDefn, CndLexer.IS_PRIMARY_PROPERTY, false))
{
+ primaryItemName = nameFrom(propDefn, CndLexer.NAME);
+ break;
+ }
+ }
+ }
+ }
+ if (primaryItemName == null) {
+ // See if one of the child definitions is marked as the primary ...
+ CommonTree childNodeDefinitions =
(CommonTree)nodeType.getFirstChildWithType(CndLexer.CHILD_NODE_DEFINITION);
+ if (childNodeDefinitions != null) {
+ // Walk each of the nodes under CHILD_NODE_DEFINITION ...
+ for (int j = 0; j != childNodeDefinitions.getChildCount(); ++j) {
+ CommonTree childDefn =
(CommonTree)childNodeDefinitions.getChild(j);
+ if (booleanFrom(childDefn, CndLexer.IS_PRIMARY_PROPERTY, false))
{
+ primaryItemName = nameFrom(childDefn, CndLexer.NAME);
+ break;
+ }
+ }
+ }
+ }
+
+ // Create the node for the node type ...
+ if (name == null) return null;
+ Path path = pathFactory().create(parentPath, name);
+
+ PropertyFactory factory = context.getPropertyFactory();
+ destination.create(path,
+ factory.create(JcrLexicon.PRIMARY_TYPE,
JcrNtLexicon.NODE_TYPE),
+ factory.create(JcrLexicon.SUPERTYPES,
(Object[])supertypes),
+ factory.create(JcrLexicon.IS_ABSTRACT, isAbstract),
+ factory.create(JcrLexicon.HAS_ORDERABLE_CHILD_NODES,
hasOrderableChildNodes),
+ factory.create(JcrLexicon.IS_MIXIN, isMixin),
+ factory.create(JcrLexicon.IS_QUERYABLE, isQueryable),
+ factory.create(JcrLexicon.PRIMARY_ITEM_NAME,
primaryItemName));
+
+ return path;
+ }
+
+ protected Path createPropertyDefinition( CommonTree propDefn,
+ Path parentPath ) {
+ Name name = nameFrom(propDefn, CndLexer.NAME);
+ String requiredType = propertyTypeNameFrom(propDefn,
CndLexer.REQUIRED_TYPE);
+ String[] defaultValues = stringsFrom(propDefn, CndLexer.DEFAULT_VALUES);
+ boolean multiple = booleanFrom(propDefn, CndLexer.MULTIPLE, false);
+ boolean mandatory = booleanFrom(propDefn, CndLexer.MANDATORY, false);
+ boolean autoCreated = booleanFrom(propDefn, CndLexer.AUTO_CREATED, false);
+ boolean isProtected = booleanFrom(propDefn, CndLexer.PROTECTED, false);
+ String onParentVersion = onParentVersionFrom(propDefn,
CndLexer.ON_PARENT_VERSION);
+ /*QueryOperator[] queryOperators =*/queryOperatorsFrom(propDefn,
CndLexer.QUERY_OPERATORS);
+ boolean isFullTextSearchable = booleanFrom(propDefn,
CndLexer.IS_FULL_TEXT_SEARCHABLE, true);
+ boolean isQueryOrderable = booleanFrom(propDefn,
CndLexer.IS_QUERY_ORDERERABLE, true);
+ String[] valueConstraints = stringsFrom(propDefn,
CndLexer.VALUE_CONSTRAINTS);
+
+ // Create the node for the node type ...
+ if (name == null) return null;
+ Path path = pathFactory().create(parentPath, name);
+
+ PropertyFactory factory = context.getPropertyFactory();
+ destination.create(path,
+ factory.create(JcrLexicon.PRIMARY_TYPE,
JcrNtLexicon.PROPERTY_DEFINITION),
+ factory.create(JcrLexicon.REQUIRED_TYPE, requiredType),
+ factory.create(JcrLexicon.DEFAULT_VALUES,
(Object[])defaultValues),
+ factory.create(JcrLexicon.MULTIPLE, multiple),
+ factory.create(JcrLexicon.MANDATORY, mandatory),
+ factory.create(JcrLexicon.AUTO_CREATED, autoCreated),
+ factory.create(JcrLexicon.PROTECTED, isProtected),
+ factory.create(JcrLexicon.ON_PARENT_VERSION,
onParentVersion),
+ // factory.create(DnaLexicon.QUERY_OPERATORS,
queryOperators),
+ factory.create(JcrLexicon.IS_FULL_TEXT_SEARCHABLE,
isFullTextSearchable),
+ factory.create(JcrLexicon.IS_QUERY_ORDERABLE,
isQueryOrderable),
+ factory.create(JcrLexicon.VALUE_CONSTRAINTS,
(Object[])valueConstraints));
+
+ return path;
+ }
+
+ protected Path createChildDefinition( CommonTree childDefn,
+ Path parentPath ) {
+ Name name = nameFrom(childDefn, CndLexer.NAME);
+ Name[] requiredPrimaryTypes = namesFrom(childDefn,
CndLexer.REQUIRED_PRIMARY_TYPES);
+ Name defaultPrimaryType = nameFrom(childDefn,
CndLexer.DEFAULT_PRIMARY_TYPE);
+ boolean mandatory = booleanFrom(childDefn, CndLexer.MANDATORY, false);
+ boolean autoCreated = booleanFrom(childDefn, CndLexer.AUTO_CREATED, false);
+ boolean isProtected = booleanFrom(childDefn, CndLexer.PROTECTED, false);
+ String onParentVersion = onParentVersionFrom(childDefn,
CndLexer.ON_PARENT_VERSION);
+ boolean sameNameSiblings = booleanFrom(childDefn,
CndLexer.SAME_NAME_SIBLINGS, false);
+
+ // Create the node for the node type ...
+ if (name == null) return null;
+ Path path = pathFactory().create(parentPath, name);
+
+ PropertyFactory factory = context.getPropertyFactory();
+ destination.create(path,
+ factory.create(JcrLexicon.PRIMARY_TYPE,
JcrNtLexicon.CHILD_NODE_DEFINITION),
+ factory.create(JcrLexicon.REQUIRED_PRIMARY_TYPES,
(Object[])requiredPrimaryTypes),
+ factory.create(JcrLexicon.DEFAULT_PRIMARY_TYPE,
defaultPrimaryType),
+ factory.create(JcrLexicon.MANDATORY, mandatory),
+ factory.create(JcrLexicon.AUTO_CREATED, autoCreated),
+ factory.create(JcrLexicon.PROTECTED, isProtected),
+ factory.create(JcrLexicon.ON_PARENT_VERSION,
onParentVersion),
+ factory.create(JcrLexicon.SAME_NAME_SIBLINGS,
sameNameSiblings));
+
+ return path;
+ }
+ }
+
+ protected class Parser extends CndParser {
+ private final Problems problems;
+ private final String nameOfResource;
+
+ public Parser( TokenStream input,
+ Problems problems,
+ String nameOfResource ) {
+ super(input);
+ this.problems = problems;
+ this.nameOfResource = nameOfResource;
+ }
+
+ @Override
+ public void displayRecognitionError( String[] tokenNames,
+ RecognitionException e ) {
+ if (problems != null) {
+ String hdr = getErrorHeader(e);
+ String msg = getErrorMessage(e, tokenNames);
+ problems.addError(CndI18n.passthrough, nameOfResource, hdr, msg);
+ } else {
+ super.displayRecognitionError(tokenNames, e);
+ }
+ }
+ }
+
+ /**
+ * Specialization of an {@link ANTLRInputStream} that converts all tokens to
lowercase, allowing the grammar to be
+ * case-insensitive. See the <a
href="http://www.antlr.org/wiki/pages/viewpage.action?pageId=1782&qu...
documentation</a>.
+ */
+ protected class CaseInsensitiveInputStream extends ANTLRInputStream {
+ protected CaseInsensitiveInputStream( InputStream stream ) throws IOException {
+ super(stream);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.antlr.runtime.ANTLRStringStream#LA(int)
+ */
+ @Override
+ public int LA( int i ) {
+ if (i == 0) {
+ return 0; // undefined
+ }
+ if (i < 0) {
+ i++; // e.g., translate LA(-1) to use offset 0
+ }
+
+ if ((p + i - 1) >= n) {
+ return CharStream.EOF;
+ }
+ return Character.toLowerCase(data[p + i - 1]);
+ }
+ }
+
+ /**
+ * Specialization of an {@link ANTLRInputStream} that converts all tokens to
lowercase, allowing the grammar to be
+ * case-insensitive. See the <a
href="http://www.antlr.org/wiki/pages/viewpage.action?pageId=1782&qu...
documentation</a>.
+ */
+ protected class CaseInsensitiveFileStream extends ANTLRFileStream {
+ protected CaseInsensitiveFileStream( String fileName ) throws IOException {
+ super(fileName, null);
+ }
+
+ protected CaseInsensitiveFileStream( String fileName,
+ String encoding ) throws IOException {
+ super(fileName, encoding);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.antlr.runtime.ANTLRStringStream#LA(int)
+ */
+ @Override
+ public int LA( int i ) {
+ if (i == 0) {
+ return 0; // undefined
+ }
+ if (i < 0) {
+ i++; // e.g., translate LA(-1) to use offset 0
+ }
+
+ if ((p + i - 1) >= n) {
+
+ return CharStream.EOF;
+ }
+ return Character.toLowerCase(data[p + i - 1]);
+ }
+ }
+
+}
Added: trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/QueryOperator.java
===================================================================
--- trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/QueryOperator.java
(rev 0)
+++ trunk/dna-cnd/src/main/java/org/jboss/dna/cnd/QueryOperator.java 2009-04-20 19:07:48
UTC (rev 840)
@@ -0,0 +1,80 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * Unless otherwise indicated, all code in JBoss DNA is licensed
+ * to you 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.
+ *
+ * JBoss DNA 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.cnd;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.jboss.dna.common.util.CheckArg;
+
+/**
+ * Enumeration of the query operators allowed in a CND file.
+ */
+public enum QueryOperator {
+
+ EQUAL("="),
+ NOT_EQUAL("<>"),
+ LESS_THAN("<"),
+ LESS_THAN_OR_EQUALS("<="),
+ GREATER_THAN("<"),
+ GREATER_THAN_OR_EQUALS("<="),
+ LIKE("LIKE");
+
+ private static final Map<String, QueryOperator> ALL_OPERATORS;
+ static {
+ Map<String, QueryOperator> operators = new HashMap<String,
QueryOperator>();
+ for (QueryOperator operator : QueryOperator.values()) {
+ operators.put(operator.getText(), operator);
+ }
+ ALL_OPERATORS = Collections.unmodifiableMap(operators);
+ }
+
+ private final String text;
+
+ private QueryOperator( String text ) {
+ this.text = text;
+ }
+
+ /**
+ * @return text
+ */
+ public String getText() {
+ return text;
+ }
+
+ public static QueryOperator forText( String text ) {
+ CheckArg.isNotNull(text, "text");
+ return ALL_OPERATORS.get(text.trim().toUpperCase());
+ }
+
+ /**
+ * Return an iterator over all the operator enumeration literals.
+ *
+ * @return an immutable iterator
+ */
+ public static Iterator<QueryOperator> iterator() {
+ return ALL_OPERATORS.values().iterator();
+ }
+}
Added: trunk/dna-cnd/src/main/resources/org/jboss/dna/cnd/CndI18n.properties
===================================================================
--- trunk/dna-cnd/src/main/resources/org/jboss/dna/cnd/CndI18n.properties
(rev 0)
+++ trunk/dna-cnd/src/main/resources/org/jboss/dna/cnd/CndI18n.properties 2009-04-20
19:07:48 UTC (rev 840)
@@ -0,0 +1,33 @@
+#
+# JBoss DNA (
http://www.jboss.org/dna)
+# See the COPYRIGHT.txt file distributed with this work for information
+# regarding copyright ownership. Some portions may be licensed
+# to Red Hat, Inc. under one or more contributor license agreements.
+# See the AUTHORS.txt file in the distribution for a full listing of
+# individual contributors.
+#
+# JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+# is licensed to you 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.
+#
+# JBoss DNA 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.
+#
+
+passthrough = {0}
+errorImportingCndContent = Error importing {0}: {1}
+expectedBooleanLiteral = Expected 'true' or 'false', but was
"{0}"
+expectedStringLiteral = Expected a valid string, but was "{0}"
+expectedValidNameLiteral = Expected a valid name, but was "{0}"
+expectedValidPropertyTypeName = Property type name was "{0}" but should be one
of "{1}"
+expectedValidOnParentVersion = On parent version value was "{0}" but should be
one of "{1}"
+expectedValidQueryOperator = Expected a valid query operator ('=',
'<>', '<', '<=', '>', '>=', or
'LIKE'), but was {0}
+locationFromLineNumberAndCharacter = Line {0} column {1}
\ No newline at end of file
Added: trunk/dna-cnd/src/test/java/org/jboss/dna/cnd/CndImporterTest.java
===================================================================
--- trunk/dna-cnd/src/test/java/org/jboss/dna/cnd/CndImporterTest.java
(rev 0)
+++ trunk/dna-cnd/src/test/java/org/jboss/dna/cnd/CndImporterTest.java 2009-04-20 19:07:48
UTC (rev 840)
@@ -0,0 +1,611 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * Unless otherwise indicated, all code in JBoss DNA is licensed
+ * to you 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.
+ *
+ * JBoss DNA 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.cnd;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.jboss.dna.graph.IsNodeWithProperty.hasProperty;
+import static org.junit.Assert.assertThat;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.util.HashSet;
+import java.util.Set;
+import org.jboss.dna.common.collection.Problem;
+import org.jboss.dna.common.collection.SimpleProblems;
+import org.jboss.dna.graph.DnaLexicon;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.JcrLexicon;
+import org.jboss.dna.graph.JcrNtLexicon;
+import org.jboss.dna.graph.Node;
+import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource;
+import org.jboss.dna.graph.io.Destination;
+import org.jboss.dna.graph.io.GraphBatchDestination;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class CndImporterTest {
+
+ public static final String CND_FILE_PATH = "src/test/resources/cnd/";
+
+ private ExecutionContext context;
+ private InMemoryRepositorySource repository;
+ private Graph graph;
+ private Destination destination;
+ private Path rootPath;
+ private CndImporter importer;
+ private SimpleProblems problems;
+
+ @Before
+ public void beforeEach() {
+ problems = new SimpleProblems();
+ context = new ExecutionContext();
+ context.getNamespaceRegistry().register(DnaLexicon.Namespace.PREFIX,
DnaLexicon.Namespace.URI);
+ context.getNamespaceRegistry().register(JcrLexicon.Namespace.PREFIX,
JcrLexicon.Namespace.URI);
+ context.getNamespaceRegistry().register(JcrNtLexicon.Namespace.PREFIX,
JcrNtLexicon.Namespace.URI);
+
+ // Set up the repository and graph ...
+ repository = new InMemoryRepositorySource();
+ repository.setName("NodeTypes");
+ graph = Graph.create(repository, context);
+
+ // Set up the path where the content will go, and make sure that path exists in
the repository ...
+ rootPath = context.getValueFactories().getPathFactory().create("/a");
+ graph.create(rootPath);
+
+ // Now set up the destination ...
+ destination = new GraphBatchDestination(graph.batch());
+
+ // Set up the importer ...
+ importer = new CndImporter(destination, rootPath);
+ }
+
+ protected Name name( String name ) {
+ return context.getValueFactories().getNameFactory().create(name);
+ }
+
+ protected void printProblems() {
+ for (Problem problem : problems) {
+ System.out.println(problem);
+ }
+ }
+
+ protected Node node( String pathToNode ) {
+ return graph.getNodeAt("/a/" + pathToNode);
+ }
+
+ protected InputStream openCndStream( String cndFileName ) throws IOException {
+ return this.getClass().getClassLoader().getResourceAsStream("cnd/" +
cndFileName);
+ }
+
+ protected File openCndFile( String cndFileName ) throws IOException,
URISyntaxException {
+ File result = new File(CND_FILE_PATH + cndFileName);
+ assertThat(result.exists(), is(true));
+ return result;
+ }
+
+ @Test
+ public void shouldReportErrorIfTheNodeTypeNameIsEmpty() throws IOException {
+ String cnd = "<ns = 'http://namespace.com/ns'> []
abstract";
+ importer.importFrom(cnd, problems, "string");
+ // printProblems();
+ assertThat(problems.size(), is(1));
+ assertThat(problems.iterator().next().getMessageString(), is("missing STRING
at ']'"));
+ }
+
+ @Test
+ public void shouldReportErrorIfTheNodeTypeNameIsBlank() throws IOException {
+ String cnd = "<ns = 'http://namespace.com/ns'> [ ]
abstract";
+ importer.importFrom(cnd, problems, "string");
+ // printProblems();
+ assertThat(problems.size(), is(1));
+ assertThat(problems.iterator().next().getMessageString(), is("missing STRING
at ']'"));
+ }
+
+ @Test
+ public void shouldReportErrorIfTheNodeTypeNameIsNotFollowedByClosingBracket() throws
IOException {
+ String cnd = "<ns = 'http://namespace.com/ns'> [
abstract";
+ importer.importFrom(cnd, problems, "string");
+ // printProblems();
+ assertThat(problems.size(), is(1));
+ assertThat(problems.iterator().next().getMessageString(), is("mismatched
input 'abstract' expecting STRING"));
+ }
+
+ @Test
+ public void shouldReportErrorIfTheNodeTypeNameUsesInvalidNamespace() throws
IOException {
+ String cnd = "<ns = 'http://namespace.com/ns'> [xyz:acme]
abstract";
+ importer.importFrom(cnd, problems, "string");
+ // printProblems();
+ assertThat(problems.size(), is(1));
+ assertThat(problems.iterator().next().getMessage(),
is(CndI18n.expectedValidNameLiteral));
+ }
+
+ @Test
+ public void shouldImportCndThatUsesAllFeatures() throws IOException {
+ // importer.setDebug(true);
+ String cnd = "<ex = 'http://namespace.com/ns'>\n"
+ + "[ex:NodeType] > ex:ParentType1, ex:ParentType2 abstract
orderable mixin noquery primaryitem ex:property\n"
+ + "- ex:property (STRING) = 'default1',
'default2' mandatory autocreated protected multiple VERSION <
'constraint1', 'constraint2'\n"
+ + " queryops '=, <>, <, <=, >, >=,
LIKE' nofulltext noqueryorder\n"
+ + "+ ex:node (ex:reqType1, ex:reqType2) = ex:defaultType
mandatory autocreated protected sns version";
+ importer.importFrom(cnd, problems, "string");
+ // assertThat(problems.size(), is(1));
+ // printProblems();
+ context.getNamespaceRegistry().register("ex",
"http://namespace.com/ns");
+ Node nodeType = node("ex:NodeType");
+ assertThat(nodeType, hasProperty(JcrLexicon.IS_ABSTRACT, true));
+ Node prop = node("ex:NodeType/ex:property");
+ assertThat(prop, hasProperty(JcrLexicon.REQUIRED_TYPE, "STRING"));
+ assertThat(prop, hasProperty(JcrLexicon.DEFAULT_VALUES, new Object[]
{"default1", "default2"}));
+ assertThat(prop, hasProperty(JcrLexicon.AUTO_CREATED, true));
+ assertThat(prop, hasProperty(JcrLexicon.MANDATORY, true));
+ assertThat(prop, hasProperty(JcrLexicon.PROTECTED, true));
+ assertThat(prop, hasProperty(JcrLexicon.MULTIPLE, true));
+ assertThat(prop, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"VERSION"));
+ assertThat(prop, hasProperty(JcrLexicon.VALUE_CONSTRAINTS, new Object[]
{"constraint1", "constraint2"}));
+ assertThat(prop, hasProperty(JcrLexicon.IS_FULL_TEXT_SEARCHABLE, false));
+ assertThat(prop, hasProperty(JcrLexicon.IS_QUERY_ORDERABLE, false));
+ Node node = node("ex:NodeType/ex:node");
+ assertThat(node, hasProperty(JcrLexicon.REQUIRED_PRIMARY_TYPES, new Object[]
{name("ex:reqType1"), name("ex:reqType2")}));
+ assertThat(node, hasProperty(JcrLexicon.DEFAULT_PRIMARY_TYPE,
name("ex:defaultType")));
+ assertThat(node, hasProperty(JcrLexicon.AUTO_CREATED, true));
+ assertThat(node, hasProperty(JcrLexicon.MANDATORY, true));
+ assertThat(node, hasProperty(JcrLexicon.PROTECTED, true));
+ assertThat(node, hasProperty(JcrLexicon.SAME_NAME_SIBLINGS, true));
+ assertThat(node, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"VERSION"));
+ }
+
+ @Test
+ public void shouldImportCndThatIsOnOneLine() throws IOException {
+ String cnd = "<ns = 'http://namespace.com/ns'> "
+ + "[ns:NodeType] > ns:ParentType1, ns:ParentType2 abstract
orderable mixin noquery primaryitem ex:property "
+ + "- ex:property (STRING) = 'default1',
'default2' mandatory autocreated protected multiple VERSION <
'constraint1', 'constraint2' "
+ + " queryops '=, <>, <, <=, >, >=,
LIKE' nofulltext noqueryorder "
+ + "+ ns:node (ns:reqType1, ns:reqType2) = ns:defaultType
mandatory autocreated protected sns version";
+ // importer.importFrom(cnd, problems, "string");
+ }
+
+ @Test
+ public void shouldImportCndThatHasNoChildren() throws IOException {
+ String cnd = "<ns = 'http://namespace.com/ns'>\n"
+ + "[ns:NodeType] > ns:ParentType1, ns:ParentType2 abstract
orderable mixin noquery primaryitem ex:property\n"
+ + "- ex:property (STRING) = 'default1',
'default2' mandatory autocreated protected multiple VERSION <
'constraint1', 'constraint2'\n"
+ + " queryops '=, <>, <, <=, >, >=,
LIKE' nofulltext noqueryorder";
+ // importer.importFrom(cnd, problems, "string");
+ }
+
+ @Test
+ public void shouldImportJcrBuiltinNodeTypesForJSR170() throws Exception {
+ importer.importFrom(openCndFile("jcr-builtins-170.cnd"), problems);
+ if (problems.size() != 0) printProblems();
+ assertThat(problems.size(), is(0));
+
+ // [nt:base]
+ // - jcr:primaryType (name) mandatory autocreated protected compute
+ // - jcr:mixinTypes (name) protected multiple compute
+ assertNodeType("nt:base", NO_SUPERTYPES, NO_PRIMARY_NAME);
+ assertProperty("nt:base", "jcr:primaryType",
"Name", NO_DEFAULTS, new PropertyOptions[] {PropertyOptions.Mandatory,
+ PropertyOptions.Autocreated, PropertyOptions.Protected},
OnParentVersion.Compute);
+ assertProperty("nt:base", "jcr:mixinTypes", "Name",
NO_DEFAULTS, new PropertyOptions[] {PropertyOptions.Multiple,
+ PropertyOptions.Protected}, OnParentVersion.Compute);
+
+ // [nt:unstructured]
+ // orderable
+ // - * (undefined) multiple
+ // - * (undefined)
+ // + * (nt:base) = nt:unstructured multiple version
+ assertNodeType("nt:unstructured", NO_SUPERTYPES, NO_PRIMARY_NAME,
NodeOptions.Ordered);
+ assertProperty("nt:unstructured", "*[1]",
"Undefined", NO_DEFAULTS, PropertyOptions.Multiple);
+ assertProperty("nt:unstructured", "*[2]",
"Undefined", NO_DEFAULTS);
+ assertChild("nt:unstructured", "*[3]", "nt:base",
"nt:unstructured", OnParentVersion.Version, ChildOptions.Multiple);
+
+ // [mix:referenceable]
+ // mixin
+ // - jcr:uuid (string) mandatory autocreated protected initialize
+ assertNodeType("mix:referenceable", NO_SUPERTYPES, NO_PRIMARY_NAME,
NodeOptions.Mixin);
+ assertProperty("mix:referenceable",
+ "jcr:uuid",
+ "String",
+ NO_DEFAULTS,
+ OnParentVersion.Initialize,
+ PropertyOptions.Mandatory,
+ PropertyOptions.Autocreated,
+ PropertyOptions.Protected);
+
+ // [mix:lockable]
+ // mixin
+ // - jcr:lockOwner (string) protected ignore
+ // - jcr:lockIsDeep (boolean) protected ignore
+ assertNodeType("mix:lockable", NO_SUPERTYPES, NO_PRIMARY_NAME,
NodeOptions.Mixin);
+ assertProperty("mix:lockable", "jcr:lockOwner",
"String", NO_DEFAULTS, OnParentVersion.Ignore, PropertyOptions.Protected);
+ assertProperty("mix:lockable",
+ "jcr:lockIsDeep",
+ "Boolean",
+ NO_DEFAULTS,
+ OnParentVersion.Ignore,
+ PropertyOptions.Protected);
+
+ // [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
+ assertNodeType("nt:propertyDefinition", NO_SUPERTYPES,
NO_PRIMARY_NAME);
+ assertProperty("nt:propertyDefinition", "jcr:name",
"Name", NO_DEFAULTS);
+ assertProperty("nt:propertyDefinition", "jcr:autoCreated",
"Boolean", NO_DEFAULTS, PropertyOptions.Mandatory);
+ assertProperty("nt:propertyDefinition", "jcr:mandatory",
"Boolean", NO_DEFAULTS, PropertyOptions.Mandatory);
+ assertProperty("nt:propertyDefinition",
+ "jcr:onParentVersion",
+ "String",
+ NO_DEFAULTS,
+ new PropertyOptions[] {PropertyOptions.Mandatory},
+ null,
+ new String[] {"COPY", "VERSION",
"INITIALIZE", "COMPUTE", "IGNORE", "ABORT"});
+ assertProperty("nt:propertyDefinition", "jcr:protected",
"Boolean", NO_DEFAULTS, PropertyOptions.Mandatory);
+ assertProperty("nt:propertyDefinition",
+ "jcr:requiredType",
+ "String",
+ NO_DEFAULTS,
+ new PropertyOptions[] {PropertyOptions.Mandatory},
+ null,
+ new String[] {"STRING", "BINARY",
"LONG", "DOUBLE", "BOOLEAN", "DATE",
"NAME", "PATH", "REFERENCE",
+ "UNDEFINED"});
+ assertProperty("nt:propertyDefinition",
"jcr:valueConstraints", "String", NO_DEFAULTS,
PropertyOptions.Multiple);
+ assertProperty("nt:propertyDefinition", "jcr:defaultValues",
"Undefined", NO_DEFAULTS, PropertyOptions.Multiple);
+ assertProperty("nt:propertyDefinition", "jcr:multiple",
"Boolean", NO_DEFAULTS, PropertyOptions.Mandatory);
+ }
+
+ @Test
+ public void shouldImportJcrBuiltinNodeTypesForJSR283() throws Exception {
+ importer.importFrom(openCndFile("jcr-builtins-283-early-draft.cnd"),
problems);
+ if (problems.size() != 0) printProblems();
+ assertThat(problems.size(), is(0));
+
+ // [nt:base]
+ // - jcr:primaryType (name) mandatory autocreated protected compute
+ // - jcr:mixinTypes (name) protected multiple compute
+ assertNodeType("nt:base", NO_SUPERTYPES, NO_PRIMARY_NAME,
NodeOptions.Abstract);
+ assertProperty("nt:base", "jcr:primaryType",
"Name", NO_DEFAULTS, new PropertyOptions[] {PropertyOptions.Mandatory,
+ PropertyOptions.Autocreated, PropertyOptions.Protected},
OnParentVersion.Compute);
+ assertProperty("nt:base", "jcr:mixinTypes", "Name",
NO_DEFAULTS, new PropertyOptions[] {PropertyOptions.Multiple,
+ PropertyOptions.Protected}, OnParentVersion.Compute);
+
+ // [nt:unstructured]
+ // orderable
+ // - * (undefined) multiple
+ // - * (undefined)
+ // + * (nt:base) = nt:unstructured multiple version
+ assertNodeType("nt:unstructured", NO_SUPERTYPES, NO_PRIMARY_NAME,
NodeOptions.Ordered);
+ assertProperty("nt:unstructured", "*[1]",
"Undefined", NO_DEFAULTS, PropertyOptions.Multiple);
+ assertProperty("nt:unstructured", "*[2]",
"Undefined", NO_DEFAULTS);
+ assertChild("nt:unstructured", "*[3]", "nt:base",
"nt:unstructured", OnParentVersion.Version, ChildOptions.Multiple);
+
+ // [mix:referenceable]
+ // mixin
+ // - jcr:uuid (string) mandatory autocreated protected initialize
+ assertNodeType("mix:referenceable", NO_SUPERTYPES, NO_PRIMARY_NAME,
NodeOptions.Mixin);
+ assertProperty("mix:referenceable",
+ "jcr:uuid",
+ "String",
+ NO_DEFAULTS,
+ OnParentVersion.Initialize,
+ PropertyOptions.Mandatory,
+ PropertyOptions.Autocreated,
+ PropertyOptions.Protected);
+
+ // [mix:lockable]
+ // mixin
+ // - jcr:lockOwner (string) protected ignore
+ // - jcr:lockIsDeep (boolean) protected ignore
+ assertNodeType("mix:lockable", NO_SUPERTYPES, NO_PRIMARY_NAME,
NodeOptions.Mixin);
+ assertProperty("mix:lockable", "jcr:lockOwner",
"String", NO_DEFAULTS, OnParentVersion.Ignore, PropertyOptions.Protected);
+ assertProperty("mix:lockable",
+ "jcr:lockIsDeep",
+ "Boolean",
+ NO_DEFAULTS,
+ OnParentVersion.Ignore,
+ PropertyOptions.Protected);
+
+ // [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
+ assertNodeType("nt:propertyDefinition", NO_SUPERTYPES,
NO_PRIMARY_NAME);
+ assertProperty("nt:propertyDefinition", "jcr:name",
"Name", NO_DEFAULTS);
+ assertProperty("nt:propertyDefinition", "jcr:autoCreated",
"Boolean", NO_DEFAULTS, PropertyOptions.Mandatory);
+ assertProperty("nt:propertyDefinition", "jcr:mandatory",
"Boolean", NO_DEFAULTS, PropertyOptions.Mandatory);
+ assertProperty("nt:propertyDefinition",
+ "jcr:onParentVersion",
+ "String",
+ NO_DEFAULTS,
+ new PropertyOptions[] {PropertyOptions.Mandatory},
+ null,
+ new String[] {"COPY", "VERSION",
"INITIALIZE", "COMPUTE", "IGNORE", "ABORT"});
+ assertProperty("nt:propertyDefinition", "jcr:protected",
"Boolean", NO_DEFAULTS, PropertyOptions.Mandatory);
+ assertProperty("nt:propertyDefinition",
+ "jcr:requiredType",
+ "String",
+ NO_DEFAULTS,
+ new PropertyOptions[] {PropertyOptions.Mandatory},
+ null,
+ new String[] {"STRING", "BINARY",
"LONG", "DOUBLE", "BOOLEAN", "DATE",
"NAME", "PATH", "REFERENCE",
+ "UNDEFINED"});
+ assertProperty("nt:propertyDefinition",
"jcr:valueConstraints", "String", NO_DEFAULTS,
PropertyOptions.Multiple);
+ assertProperty("nt:propertyDefinition", "jcr:defaultValues",
"Undefined", NO_DEFAULTS, PropertyOptions.Multiple);
+ assertProperty("nt:propertyDefinition", "jcr:multiple",
"Boolean", NO_DEFAULTS, PropertyOptions.Mandatory);
+ }
+
+ @Test
+ public void shouldImportCndThatIsEmpty() throws Exception {
+ importer.importFrom(openCndFile("empty.cnd"), problems);
+ if (problems.size() != 0) printProblems();
+ assertThat(problems.size(), is(0));
+ }
+
+ @Test
+ public void shouldImportCndForImageSequencer() throws Exception {
+ importer.importFrom(openCndFile("images.cnd"), problems);
+ if (problems.size() != 0) printProblems();
+ assertThat(problems.size(), is(0));
+ }
+
+ @Test
+ public void shouldImportCndForMp3Sequencer() throws Exception {
+ importer.importFrom(openCndFile("mp3.cnd"), problems);
+ if (problems.size() != 0) printProblems();
+ assertThat(problems.size(), is(0));
+ }
+
+ @Test
+ public void shouldNotImportFileThatIsNotAValidCnd() throws Exception {
+ importer.importFrom(openCndFile("invalid.cnd"), problems);
+ assertThat(problems.size(), is(1));
+ }
+
+ public static final String[] NO_DEFAULTS = {};
+ public static final String[] NO_SUPERTYPES = {};
+ public static final String[] NO_VALUE_CONSTRAINTS = {};
+ public static final String NO_PRIMARY_NAME = null;
+
+ public static enum PropertyOptions {
+ Mandatory,
+ Autocreated,
+ Protected,
+ Multiple,
+ FullTextSearchable,
+ QueryOrderable
+ }
+
+ public static enum ChildOptions {
+ Mandatory,
+ Autocreated,
+ Protected,
+ Multiple
+ }
+
+ public static enum NodeOptions {
+ Abstract,
+ Mixin,
+ Ordered,
+ Queryable
+ }
+
+ public static enum OnParentVersion {
+ Copy,
+ Version,
+ Initialize,
+ Compute,
+ Ignore,
+ Abort
+ }
+
+ protected void assertNodeType( String name,
+ String[] superTypes,
+ String primaryItemName,
+ NodeOptions... nodeOptions ) {
+ Set<NodeOptions> options = new HashSet<NodeOptions>();
+ for (NodeOptions option : nodeOptions)
+ options.add(option);
+
+ Node nodeType = node(name);
+ assertThat(nodeType, hasProperty(JcrLexicon.IS_MIXIN,
options.contains(NodeOptions.Mixin)));
+ assertThat(nodeType, hasProperty(JcrLexicon.IS_ABSTRACT,
options.contains(NodeOptions.Abstract)));
+ assertThat(nodeType, hasProperty(JcrLexicon.HAS_ORDERABLE_CHILD_NODES,
options.contains(NodeOptions.Ordered)));
+ assertThat(nodeType, hasProperty(JcrLexicon.IS_QUERYABLE,
!options.contains(NodeOptions.Queryable)));
+ assertThat(nodeType, hasProperty(JcrLexicon.PRIMARY_ITEM_NAME,
name(primaryItemName)));
+ if (superTypes.length != 0) {
+ Name[] superTypeNames = new Name[superTypes.length];
+ for (int i = 0; i != superTypes.length; ++i) {
+ String requiredType = superTypes[i];
+ superTypeNames[i] = name(requiredType);
+ }
+ assertThat(nodeType, hasProperty(JcrLexicon.SUPERTYPES,
(Object[])superTypeNames));
+ } else {
+ assertThat(nodeType.getProperty(JcrLexicon.SUPERTYPES), is(nullValue()));
+ }
+ }
+
+ protected void assertProperty( String nodeTypeName,
+ String propertyName,
+ String requiredType,
+ String[] defaultValues,
+ PropertyOptions... propertyOptions ) {
+ assertProperty(nodeTypeName, propertyName, requiredType, defaultValues,
propertyOptions, null);
+ }
+
+ protected void assertProperty( String nodeTypeName,
+ String propertyName,
+ String requiredType,
+ String[] defaultValues,
+ OnParentVersion onParentVersion,
+ PropertyOptions... propertyOptions ) {
+ assertProperty(nodeTypeName, propertyName, requiredType, defaultValues,
propertyOptions, onParentVersion);
+ }
+
+ protected void assertProperty( String nodeTypeName,
+ String propertyName,
+ String requiredType,
+ String[] defaultValues,
+ PropertyOptions[] propertyOptions,
+ OnParentVersion onParentVersioning,
+ String... valueConstraints ) {
+ Set<PropertyOptions> options = new HashSet<PropertyOptions>();
+ for (PropertyOptions option : propertyOptions)
+ options.add(option);
+
+ Node nodeType = node(nodeTypeName + "/" + propertyName);
+ assertThat(nodeType, hasProperty(JcrLexicon.REQUIRED_TYPE,
requiredType.toUpperCase()));
+ assertThat(nodeType, hasProperty(JcrLexicon.MULTIPLE,
options.contains(PropertyOptions.Multiple)));
+ assertThat(nodeType, hasProperty(JcrLexicon.MANDATORY,
options.contains(PropertyOptions.Mandatory)));
+ assertThat(nodeType, hasProperty(JcrLexicon.AUTO_CREATED,
options.contains(PropertyOptions.Autocreated)));
+ assertThat(nodeType, hasProperty(JcrLexicon.PROTECTED,
options.contains(PropertyOptions.Protected)));
+ if (onParentVersioning != null) {
+ switch (onParentVersioning) {
+ case Abort:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"ABORT"));
+ break;
+ case Compute:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"COMPUTE"));
+ break;
+ case Copy:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"COPY"));
+ break;
+ case Ignore:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"IGNORE"));
+ break;
+ case Initialize:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"INITIALIZE"));
+ break;
+ case Version:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"VERSION"));
+ break;
+ }
+ } else {
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"COPY")); // it's copy by default
+ }
+ assertThat(nodeType, hasProperty(JcrLexicon.IS_FULL_TEXT_SEARCHABLE,
+
!options.contains(PropertyOptions.FullTextSearchable)));
+ assertThat(nodeType, hasProperty(JcrLexicon.IS_QUERY_ORDERABLE,
!options.contains(PropertyOptions.QueryOrderable)));
+ if (valueConstraints.length != 0) {
+ assertThat(nodeType, hasProperty(JcrLexicon.VALUE_CONSTRAINTS,
(Object[])valueConstraints));
+ } else {
+ assertThat(nodeType.getProperty(JcrLexicon.VALUE_CONSTRAINTS),
is(nullValue()));
+ }
+ if (defaultValues.length != 0) {
+ assertThat(nodeType, hasProperty(JcrLexicon.DEFAULT_VALUES,
(Object[])defaultValues));
+ } else {
+ assertThat(nodeType.getProperty(JcrLexicon.DEFAULT_VALUES),
is(nullValue()));
+ }
+ }
+
+ protected void assertChild( String nodeTypeName,
+ String childName,
+ String requiredType,
+ String defaultPrimaryType,
+ ChildOptions[] childOptions,
+ OnParentVersion onParentVersioning ) {
+ assertChild(nodeTypeName, childName, new String[] {requiredType},
defaultPrimaryType, childOptions, onParentVersioning);
+ }
+
+ protected void assertChild( String nodeTypeName,
+ String childName,
+ String requiredType,
+ String defaultPrimaryType,
+ OnParentVersion onParentVersioning,
+ ChildOptions... childOptions ) {
+ assertChild(nodeTypeName, childName, new String[] {requiredType},
defaultPrimaryType, childOptions, onParentVersioning);
+ }
+
+ protected void assertChild( String nodeTypeName,
+ String childName,
+ String[] requiredTypes,
+ String defaultPrimaryType,
+ ChildOptions[] childOptions,
+ OnParentVersion onParentVersioning ) {
+ Set<ChildOptions> options = new HashSet<ChildOptions>();
+ for (ChildOptions option : childOptions)
+ options.add(option);
+
+ Node nodeType = node(nodeTypeName + "/" + childName);
+ assertThat(nodeType, hasProperty(JcrLexicon.DEFAULT_PRIMARY_TYPE,
name(defaultPrimaryType)));
+ assertThat(nodeType, hasProperty(JcrLexicon.SAME_NAME_SIBLINGS,
options.contains(ChildOptions.Multiple)));
+ assertThat(nodeType, hasProperty(JcrLexicon.MANDATORY,
options.contains(ChildOptions.Mandatory)));
+ assertThat(nodeType, hasProperty(JcrLexicon.AUTO_CREATED,
options.contains(ChildOptions.Autocreated)));
+ assertThat(nodeType, hasProperty(JcrLexicon.PROTECTED,
options.contains(ChildOptions.Protected)));
+ switch (onParentVersioning) {
+ case Abort:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"ABORT"));
+ break;
+ case Compute:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"COMPUTE"));
+ break;
+ case Copy:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"COPY"));
+ break;
+ case Ignore:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"IGNORE"));
+ break;
+ case Initialize:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"INITIALIZE"));
+ break;
+ case Version:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
"VERSION"));
+ break;
+ default:
+ assertThat(nodeType, hasProperty(JcrLexicon.ON_PARENT_VERSION,
is(nullValue())));
+ }
+ if (requiredTypes.length != 0) {
+ Name[] requiredTypeNames = new Name[requiredTypes.length];
+ for (int i = 0; i != requiredTypes.length; ++i) {
+ String requiredType = requiredTypes[i];
+ requiredTypeNames[i] = name(requiredType);
+ }
+ assertThat(nodeType, hasProperty(JcrLexicon.REQUIRED_PRIMARY_TYPES,
(Object[])requiredTypeNames));
+ } else {
+ assertThat(nodeType.getProperty(JcrLexicon.REQUIRED_PRIMARY_TYPES),
is(nullValue()));
+ }
+ }
+}
Added: trunk/dna-cnd/src/test/resources/cnd/empty.cnd
===================================================================
Added: trunk/dna-cnd/src/test/resources/cnd/images.cnd
===================================================================
--- trunk/dna-cnd/src/test/resources/cnd/images.cnd (rev 0)
+++ trunk/dna-cnd/src/test/resources/cnd/images.cnd 2009-04-20 19:07:48 UTC (rev 840)
@@ -0,0 +1,63 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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/dna-cnd/src/test/resources/cnd/invalid.cnd
===================================================================
--- trunk/dna-cnd/src/test/resources/cnd/invalid.cnd (rev 0)
+++ trunk/dna-cnd/src/test/resources/cnd/invalid.cnd 2009-04-20 19:07:48 UTC (rev 840)
@@ -0,0 +1 @@
+This is not a valid cnd file.
\ No newline at end of file
Added: trunk/dna-cnd/src/test/resources/cnd/jcr-builtins-170.cnd
===================================================================
--- trunk/dna-cnd/src/test/resources/cnd/jcr-builtins-170.cnd (rev
0)
+++ trunk/dna-cnd/src/test/resources/cnd/jcr-builtins-170.cnd 2009-04-20 19:07:48 UTC (rev
840)
@@ -0,0 +1,173 @@
+/*
+ * 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'>
+
+//------------------------------------------------------------------------------
+// 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/dna-cnd/src/test/resources/cnd/jcr-builtins-283-early-draft.cnd
===================================================================
--- trunk/dna-cnd/src/test/resources/cnd/jcr-builtins-283-early-draft.cnd
(rev 0)
+++ trunk/dna-cnd/src/test/resources/cnd/jcr-builtins-283-early-draft.cnd 2009-04-20
19:07:48 UTC (rev 840)
@@ -0,0 +1,218 @@
+<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>
+<sv=http://www.jcp.org/jcr/sv/1.0>
+
+// ------------------------------------------------------------------------
+// Pre-defined Node Types
+// ------------------------------------------------------------------------
+
+[nt:base] abstract
+ - 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
+
+[nt:hierarchyNode] > mix:created abstract
+
+[nt:file] > nt:hierarchyNode
+ + jcr:content (nt:base) primary mandatory
+
+[nt:linkedFile] > nt:hierarchyNode
+ - jcr:content (reference) primary mandatory
+
+[nt:folder] > nt:hierarchyNode
+ + * (nt:hierarchyNode) version
+
+[nt:resource] > mix:referenceable,
+ mix:mimeTyped,
+ mix:lastModified
+ - jcr:data (binary) primary mandatory
+
+[nt:nodeType]
+ - jcr:nodeTypeName (name) mandatory
+ - jcr:supertypes (name) multiple
+ - jcr:isAbstract (boolean) mandatory
+ - 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
+
+[nt:versionHistory] > mix:referenceable
+ - jcr:versionableUuid (string) mandatory autocreated
+ protected abort
+ - jcr:copiedFrom (reference) protected abort
+ < 'nt:version'
+ + 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:activity (reference) protected abort
+ < 'nt:activity'
+ + 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'
+
+[nt:query]
+ - jcr:statement (string)
+ - jcr:language (string)
+
+[nt:activity] > mix:referenceable
+ - jcr:title (string)
+ mandatory autocreated protected
+
+[nt:configuration] > mix:versionable
+ - jcr:root (reference)
+ mandatory autocreated protected
+
+[nt:address]
+ - jcr:protocol (string)
+ - jcr:host (string)
+ - jcr:port (string)
+ - jcr:repository (string)
+ - jcr:workspace (string)
+ - jcr:path (path)
+ - jcr:id (weakreference)
+
+[nt:naturalText]
+ - jcr:text (string)
+ - jcr:messageId (string)
+
+
+// ------------------------------------------------------------------------
+// Pre-defined Mixins
+// ------------------------------------------------------------------------
+
+[mix:lockable]
+ mixin
+ - jcr:lockOwner (string) protected ignore
+ - jcr:lockIsDeep (boolean) protected ignore
+
+[mix:referenceable]
+ mixin
+ - jcr:uuid (string) mandatory autocreated protected
+ initialize
+
+[mix:simpleVersionable] > mix:referenceable
+ mixin
+ - jcr:isCheckedOut (boolean) = 'true' mandatory
+ autocreated protected ignore
+ - jcr:versionLabels (name) mandatory protected multiple
+
+[mix:versionable] > mix:simpleVersionable
+ mixin
+ - jcr:versionHistory (reference) mandatory protected
+ < 'nt:versionHistory'
+ - jcr:baseVersion (reference) mandatory protected
+ ignore
+ < 'nt:version'
+ - jcr:predecessors (reference) mandatory protected
+ multiple
+ < 'nt:version'
+ - jcr:mergeFailed (reference) protected multiple abort
+ - jcr:activity (reference)
+ < 'nt:version'
+ - jcr:configuration (reference)
+ < 'nt:configuration'
+
+[mix:lifecycle]
+ mixin
+ - jcr:lifecyclePolicy (reference) protected initialize
+ - jcr:currentLifecycleState (string) protected
+initialize
+
+[mix:managedRetention] > mix:referenceable
+ mixin
+ - jcr:hold (string) protected multiple
+ - jcr:isDeep (boolean) protected multiple
+ - jcr:retentionPolicy (reference) protected
+
+[mix:shareable] > mix:referenceable mixin
+
+[mix:title] mixin
+ - jcr:title (string)
+ - jcr:description (string)
+
+[mix:created] mixin
+ - jcr:created (date)
+ - jcr:createdBy (string)
+
+[mix:lastModified] mixin
+ - jcr:lastModified (date)
+ - jcr:lastModifiedBy (string)
+
+[mix:language] mixin
+ - jcr:language (string)
+
+[mix:mimeType] mixin
+ - jcr:mimeType (string)
+ - jcr:encoding (string)
+
+
+
+
+
\ No newline at end of file
Added: trunk/dna-cnd/src/test/resources/cnd/mp3.cnd
===================================================================
--- trunk/dna-cnd/src/test/resources/cnd/mp3.cnd (rev 0)
+++ trunk/dna-cnd/src/test/resources/cnd/mp3.cnd 2009-04-20 19:07:48 UTC (rev 840)
@@ -0,0 +1,53 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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
Added: trunk/dna-cnd/src/test/resources/log4j.properties
===================================================================
--- trunk/dna-cnd/src/test/resources/log4j.properties (rev 0)
+++ trunk/dna-cnd/src/test/resources/log4j.properties 2009-04-20 19:07:48 UTC (rev 840)
@@ -0,0 +1,13 @@
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %m%n
+
+# Root logger option
+log4j.rootLogger=INFO, stdout
+
+# Set up the default logging to be INFO level, then override specific units
+log4j.logger.org.jboss.dna=INFO
+log4j.logger.org.jboss.dna.cnd=INFO
+
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2009-04-17 14:23:57 UTC (rev 839)
+++ trunk/pom.xml 2009-04-20 19:07:48 UTC (rev 840)
@@ -114,7 +114,8 @@
<module>dna-common</module>
<module>dna-graph</module>
<module>dna-repository</module>
- <module>dna-jcr</module>
+ <module>dna-cnd</module>
+ <!--module>dna-jcr</module-->
<module>extensions/dna-classloader-maven</module>
<module>extensions/dna-sequencer-images</module>
<module>extensions/dna-sequencer-mp3</module>