diff --git a/tests/PhpcrUtils/CndParserTest.php b/tests/PhpcrUtils/CndParserTest.php new file mode 100644 index 00000000..a8d87f3c --- /dev/null +++ b/tests/PhpcrUtils/CndParserTest.php @@ -0,0 +1,209 @@ +cndParser = new CndParser($this->sharedFixture['session']->getWorkspace()->getNodeTypeManager()); + } + + public function testParseNormal() + { + $res = $this->cndParser->parseFile(__DIR__ . '/resources/cnd/example.cnd'); + $this->assertExampleCnd($res); + } + + public function testParseCompact() + { + $res = $this->cndParser->parseFile(__DIR__ . '/resources/cnd/example.compact.cnd'); + $this->assertExampleCnd($res); + + } + + public function testParseVerbose() + { + $res = $this->cndParser->parseFile(__DIR__ . '/resources/cnd/example.verbose.cnd'); + $this->assertExampleCnd($res); + } + + + public function testParseString() + { + // the "worst case" example from http://jackrabbit.apache.org/node-type-notation.html + $cnd = << +[ns:NodeType] > ns:ParentType1, ns:ParentType2 + orderable mixin + - ex:property (STRING) + = 'default1' , 'default2' + mandatory autocreated protected multiple + VERSION + < 'constraint1', 'constraint2' + + ns:node (ns:reqType1, ns:reqType2) + = ns:defaultType + mandatory autocreated protected VERSION +EOT; + + + $res = $this->cndParser->parseString($cnd); + $this->assertExampleCnd($res); + } + + /** + * @expectedException \PHPCR\Util\CND\Exception\ParserException + */ + public function testParseError() + { + $cnd = << +[ns:NodeType] > ns:ParentType1, ns:ParentType2 + orderable mixin + - ex:property (STRING) + = 'default1' , 'default2' + mandatory invalid-string protected multiple + VERSION + < 'constraint1', 'constraint2' + + ns:node (ns:reqType1, ns:reqType2) + = ns:defaultType + mandatory autocreated protected VERSION +EOT; + + $this->cndParser->parseString($cnd); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testErrorNoFile() + { + $this->cndParser->parseFile('/not/found'); + } + + /** + * @expectedException \PHPCR\Util\CND\Exception\ScannerException + */ + public function testScannerErrorComment() + { + $cnd = <<cndParser->parseString($cnd); + } + + /** + * @expectedException \PHPCR\Util\CND\Exception\ScannerException + */ + public function testScannerErrorNewline() + { + $cnd = << +[ns:NodeType] > ns:ParentType1, ns:ParentType2 + orderable mixin + - ex:property (STRING) +EOT; + + $this->cndParser->parseString($cnd); + } + + /** + * Test the case where the parser did not parse correctly + * the default values at the end of the parsed file. + * + * Assert no exception is thrown + */ + public function testNoStopAtEofError() + { + $res = $this->cndParser->parseFile(__DIR__ . '/resources/cnd/no-stop-at-eof.cnd'); + + $this->assertTrue(isset($res['namespaces'])); + $this->assertEquals(array('phpcr' => 'http://www.doctrine-project.org/projects/phpcr_odm'), $res['namespaces']); + + $this->assertTrue(isset($res['nodeTypes'])); + } + + public function testBigFile() + { + //var_dump($this->sharedFixture['session']->getWorkspace()->getNodeTypeManager()->getNodeType('nt:file')->hasOrderableChildNodes());die; + $res = $this->cndParser->parseFile(__DIR__ . '/resources/cnd/jackrabbit_nodetypes.cnd'); + + // some random sanity checks + $this->assertTrue(isset($res['nodeTypes'])); + + $def = $res['nodeTypes']; + $this->assertTrue(isset($def['nt:file'])); + /** @var $parsed NodeTypeDefinitionInterface */ + $parsed = $def['nt:file']; + $this->assertEquals('nt:file', $parsed->getName()); + $this->assertFalse($parsed->isAbstract()); + $this->assertFalse($parsed->hasOrderableChildNodes()); + $this->assertFalse($parsed->isMixin()); + // queryable default is implementation specific + } + + /** + * Check if $res matches the expected node type definition from the + * "worst case" example. + * + * @param array $res namespaces and node types + */ + protected function assertExampleCnd($res) + { + $this->assertTrue(isset($res['namespaces'])); + $this->assertEquals(array('ns' => 'http://namespace.com/ns'), $res['namespaces']); + + $this->assertTrue(isset($res['nodeTypes'])); + // get first node type + reset($res['nodeTypes']); + /** @var $def NodeTypeDefinitionInterface */ + list($name, $def) = each($res['nodeTypes']); + + $this->assertEquals('ns:NodeType', $name); + $this->assertInstanceOf('\PHPCR\NodeType\NodeTypeTemplateInterface', $def); + $this->assertEquals('ns:NodeType', $def->getName()); + $this->assertEquals(array('ns:ParentType1', 'ns:ParentType2'), $def->getDeclaredSuperTypeNames()); + $this->assertTrue($def->hasOrderableChildNodes()); + $this->assertTrue($def->isMixin()); + // queryable default is implementation specific + $this->assertFalse($def->isAbstract()); + $this->assertEquals(1, count($def->getPropertyDefinitionTemplates())); + + /** @var $prop PropertyDefinitionTemplateInterface */ + $prop = $def->getPropertyDefinitionTemplates()->getIterator()->current(); + + $this->assertEquals('ex:property', $prop->getName()); + $this->assertEquals(PropertyType::STRING, $prop->getRequiredType()); + $this->assertEquals(array('default1', 'default2'), $prop->getDefaultValues()); + $this->assertEquals(array('constraint1', 'constraint2'), $prop->getValueConstraints()); + $this->assertTrue($prop->isAutoCreated()); + $this->assertTrue($prop->isMandatory()); + $this->assertTrue($prop->isProtected()); + $this->assertTrue($prop->isMultiple()); + $this->assertEquals(OnParentVersionAction::VERSION, $prop->getOnParentVersion()); + $this->assertEquals(array(), $prop->getAvailableQueryOperators()); + $this->assertTrue($prop->isFullTextSearchable()); // True because there was no "nofulltext" attribute + $this->assertTrue($prop->isQueryOrderable()); // True because there was no "noqueryorder" attribute + } + +} diff --git a/tests/PhpcrUtils/resources/cnd/example.cnd b/tests/PhpcrUtils/resources/cnd/example.cnd new file mode 100644 index 00000000..7ac57aed --- /dev/null +++ b/tests/PhpcrUtils/resources/cnd/example.cnd @@ -0,0 +1,12 @@ +/* An example node type definition */ + +[ns:NodeType] > ns:ParentType1, ns:ParentType2 + orderable mixin + - ex:property (STRING) + = 'default1' , 'default2' + mandatory autocreated protected multiple + VERSION + < 'constraint1', 'constraint2' + + ns:node (ns:reqType1, ns:reqType2) + = ns:defaultType + mandatory autocreated protected VERSION \ No newline at end of file diff --git a/tests/PhpcrUtils/resources/cnd/example.compact.cnd b/tests/PhpcrUtils/resources/cnd/example.compact.cnd new file mode 100644 index 00000000..d3af8391 --- /dev/null +++ b/tests/PhpcrUtils/resources/cnd/example.compact.cnd @@ -0,0 +1,6 @@ + +[ns:NodeType]>ns:ParentType1, ns:ParentType2 o m +-ex:property(STRING)='default1','default2' m a p * VERSION + <'constraint1', 'constraint2' ++ns:node(ns:reqType1,ns:reqType2)=ns:defaultType + m a p VERSION \ No newline at end of file diff --git a/tests/PhpcrUtils/resources/cnd/example.verbose.cnd b/tests/PhpcrUtils/resources/cnd/example.verbose.cnd new file mode 100644 index 00000000..834a5a93 --- /dev/null +++ b/tests/PhpcrUtils/resources/cnd/example.verbose.cnd @@ -0,0 +1,48 @@ +/* An example node type definition */ + +// The namespace declaration + + +// Node type name +[ns:NodeType] + +// Supertypes +> ns:ParentType1, ns:ParentType2 + +// This node type supports orderable child nodes +orderable + +// This is a mixin node type +mixin + +// Nodes of this node type have a property called 'ex:property' of type STRING +- ex:property (STRING) + +// The default values for this +// (multi-value) property are... += 'default1', 'default2' + +// and it is... +mandatory autocreated protected + +// and multi-valued +multiple + +// and has an on-parent-version setting of ... +VERSION + +// The constraint settings are... +< 'constraint1', 'constraint2' + +// Nodes of this node type have a child node called ns:node which must be of +// at least the node types ns:reqType1 and ns:reqType2 ++ ns:node (ns:reqType1, ns:reqType2) + +// and the default primary node type of the child node is... += ns:defaultType + +// This child node is... +mandatory autocreated protected + +// and has an on-parent-version setting of ... +VERSION diff --git a/tests/PhpcrUtils/resources/cnd/jackrabbit_nodetypes.cnd b/tests/PhpcrUtils/resources/cnd/jackrabbit_nodetypes.cnd new file mode 100644 index 00000000..64fad9de --- /dev/null +++ b/tests/PhpcrUtils/resources/cnd/jackrabbit_nodetypes.cnd @@ -0,0 +1,631 @@ +/* + * 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. + */ + + + + + + +//------------------------------------------------------------------------------ +// B A S E T Y P E +//------------------------------------------------------------------------------ + +/** + * nt:base is an abstract primary node type that is the base type for all other + * primary node types. It is the only primary node type without supertypes. + * + * @since 1.0 + */ +[nt:base] + abstract + - jcr:primaryType (NAME) mandatory autocreated protected COMPUTE + - jcr:mixinTypes (NAME) protected multiple COMPUTE + +//------------------------------------------------------------------------------ +// S T A N D A R D A P P L I C A T I O N N O D E T Y P E S +//------------------------------------------------------------------------------ + +/** + * This abstract node type serves as the supertype of nt:file and nt:folder. + * @since 1.0 + */ +[nt:hierarchyNode] > mix:created + abstract + +/** + * Nodes of this node type may be used to represent files. This node type inherits + * the item definitions of nt:hierarchyNode and requires a single child node called + * jcr:content. The jcr:content node is used to hold the actual content of the + * file. This child node is mandatory, but not auto-created. Its node type will be + * application-dependent and therefore it must be added by the user. A common + * approach is to make the jcr:content a node of type nt:resource. The + * jcr:content child node is also designated as the primary child item of its parent. + * + * @since 1.0 + */ +[nt:file] > nt:hierarchyNode + primaryitem jcr:content + + jcr:content (nt:base) mandatory + +/** + * The nt:linkedFile node type is similar to nt:file, except that the content + * node is not stored directly as a child node, but rather is specified by a + * REFERENCE property. This allows the content node to reside anywhere in the + * workspace and to be referenced by multiple nt:linkedFile nodes. The content + * node must be referenceable. + * + * @since 1.0 + */ +[nt:linkedFile] > nt:hierarchyNode + primaryitem jcr:content + - jcr:content (REFERENCE) mandatory + +/** + * Nodes of this type may be used to represent folders or directories. This node + * type inherits the item definitions of nt:hierarchyNode and adds the ability + * to have any number of other nt:hierarchyNode child nodes with any names. + * This means, in particular, that it can have child nodes of types nt:folder, + * nt:file or nt:linkedFile. + * + * @since 1.0 + */ +[nt:folder] > nt:hierarchyNode + + * (nt:hierarchyNode) VERSION + +/** + * This node type may be used to represent the content of a file. In particular, + * the jcr:content subnode of an nt:file node will often be an nt:resource. + * + * @since 1.0 + */ +[nt:resource] > mix:mimeType, mix:lastModified, mix:referenceable + primaryitem jcr:data + - jcr:data (BINARY) mandatory + +/** + * This mixin node type can be used to add standardized title and description + * properties to a node. + * + * Note that the protected attributes suggested by JSR283 are omitted in this variant. + * @since 2.0 + */ +[mix:title] + mixin + - jcr:title (STRING) + - jcr:description (STRING) + +/** + * This mixin node type can be used to add standardized creation information + * properties to a node. Since the properties are protected, their values are + * controlled by the repository, which should set them appropriately upon the + * initial persist of a node with this mixin type. In cases where this mixin is + * added to an already existing node the semantics of these properties are + * implementation specific. Note that jackrabbit initializes the properties to + * the current date and user in this case. + * + * + * @since 2.0 + */ +[mix:created] + mixin + - jcr:created (DATE) autocreated protected + - jcr:createdBy (STRING) autocreated protected + +/** + * This mixin node type can be used to provide standardized modification + * information properties to a node. + * + * The following is not yet implemented in Jackrabbit: + * "Since the properties are protected, their values + * are controlled by the repository, which should set them appropriately upon a + * significant modification of the subgraph of a node with this mixin. What + * constitutes a significant modification will depend on the semantics of the various + * parts of a node's subgraph and is implementation-dependent" + * + * Jackrabbit initializes the properties to the current date and user in the + * case they are newly created. + * + * Note that the protected attributes suggested by JSR283 are omitted in this variant. + * @since 2.0 + */ +[mix:lastModified] + mixin + - jcr:lastModified (DATE) autocreated + - jcr:lastModifiedBy (STRING) autocreated + +/** + * This mixin node type can be used to provide a standardized property that + * specifies the natural language in which the content of a node is expressed. + * The value of the jcr:language property should be a language code as defined + * in RFC 46465. Examples include "en" (English), "en-US" (United States English), + * "de" (German) and "de-CH" (Swiss German). + * + * Note that the protected attributes suggested by JSR283 are omitted in this variant. + * @since 2.0 + */ +[mix:language] + mixin + - jcr:language (STRING) + +/** + * This mixin node type can be used to provide standardized mimetype and + * encoding properties to a node. If a node of this type has a primary item + * that is a single-value BINARY property then jcr:mimeType property indicates + * the media type applicable to the contents of that property and, if that + * media type is one to which a text encoding applies, the jcr:encoding property + * indicates the character set used. If a node of this type does not meet the + * above precondition then the interpretation of the jcr:mimeType and + * jcr:encoding properties is implementation-dependent. + * + * Note that the protected attributes suggested by JSR283 are omitted in this variant. + * @since 2.0 + */ +[mix:mimeType] + mixin + - jcr:mimeType (STRING) + - jcr:encoding (STRING) + +/** + * This node type may be used to represent the location of a JCR item not just + * within a particular workspace but within the space of all workspaces in all JCR + * repositories. + * + * @prop jcr:protocol Stores a string holding the protocol through which the + * target repository is to be accessed. + * @prop jcr:host Stores a string holding the host name of the system + * through which the repository is to be accessed. + * @prop jcr:port Stores a string holding the port number through which the + * target repository is to be accessed. + * + * The semantics of these properties above are left undefined but are assumed to be + * known by the application. The names and descriptions of the properties are not + * normative and the repository does not enforce any particular semantic + * interpretation on them. + * + * @prop jcr:repository Stores a string holding the name of the target repository. + * @prop jcr:workspace Stores the name of a workspace. + * @prop jcr:path Stores a path to an item. + * @prop jcr:id Stores a weak reference to a node. + * + * In most cases either the jcr:path or the jcr:id property would be used, but + * not both, since they may point to different nodes. If any of the properties + * other than jcr:path and jcr:id are missing, the address can be interpreted as + * relative to the current container at the same level as the missing specifier. + * For example, if no repository is specified, then the address can be + * interpreted as referring to a workspace and path or id within the current + * repository. + * + * @since 2.0 + */ +[nt:address] + - jcr:protocol (STRING) + - jcr:host (STRING) + - jcr:port (STRING) + - jcr:repository (STRING) + - jcr:workspace (STRING) + - jcr:path (PATH) + - jcr:id (WEAKREFERENCE) + +/** + * The mix:etag mixin type defines a standardized identity validator for BINARY + * properties similar to the entity tags used in HTTP/1.1 + * + * A jcr:etag property is an opaque string whose syntax is identical to that + * defined for entity tags in HTTP/1.1. Semantically, the jcr:etag is comparable + * to the HTTP/1.1 strong entity tag. + * + * On creation of a mix:etag node N, or assignment of mix:etag to N, the + * repository must create a jcr:etag property with an implementation determined + * value. + * + * The value of the jcr:etag property must change immediately on persist of any + * of the following changes to N: + * - A BINARY property is added t o N. + * - A BINARY property is removed from N. + * - The value of an existing BINARY property of N changes. + * + * @since 2.0 + */ +[mix:etag] + mixin + - jcr:etag (STRING) protected autocreated + +//------------------------------------------------------------------------------ +// U N S T R U C T U R E D C O N T E N T +//------------------------------------------------------------------------------ + +/** + * This node type is used to store unstructured content. It allows any number of + * child nodes or properties with any names. It also allows multiple nodes having + * the same name as well as both multi-value and single-value properties with any + * names. This node type also supports client-orderable child nodes. + * + * @since 1.0 + */ +[nt:unstructured] + orderable + - * (UNDEFINED) multiple + - * (UNDEFINED) + + * (nt:base) = nt:unstructured sns VERSION + +//------------------------------------------------------------------------------ +// R E F E R E N C E A B L E +//------------------------------------------------------------------------------ + +/** + * This node type adds an auto-created, mandatory, protected STRING property to + * the node, called jcr:uuid, which exposes the identifier of the node. + * Note that the term "UUID" is used for backward compatibility with JCR 1.0 + * and does not necessarily imply the use of the UUID syntax, or global uniqueness. + * The identifier of a referenceable node must be a referenceable identifier. + * Referenceable identifiers must fulfill a number of constraints beyond the + * minimum required of standard identifiers (see 3.8.3 Referenceable Identifiers). + * A reference property is a property that holds the referenceable identifier of a + * referenceable node and therefore serves as a pointer to that node. The two types + * of reference properties, REFERENCE and WEAKREFERENCE differ in that the former + * enforces referential integrity while the latter does not. + * + * @since 1.0 + */ +[mix:referenceable] + mixin + - jcr:uuid (STRING) mandatory autocreated protected INITIALIZE + +//------------------------------------------------------------------------------ +// L O C K I N G +//------------------------------------------------------------------------------ + +/** + * @since 1.0 + */ +[mix:lockable] + mixin + - jcr:lockOwner (STRING) protected IGNORE + - jcr:lockIsDeep (BOOLEAN) protected IGNORE + +//------------------------------------------------------------------------------ +// S H A R E A B L E N O D E S +//------------------------------------------------------------------------------ + +/** + * @since 2.0 + */ +[mix:shareable] > mix:referenceable + mixin + +//------------------------------------------------------------------------------ +// V E R S I O N I N G +//------------------------------------------------------------------------------ + +/** + * @since 2.0 + */ +[mix:simpleVersionable] + mixin + - jcr:isCheckedOut (BOOLEAN) = 'true' mandatory autocreated protected IGNORE + +/** + * @since 1.0 + */ +[mix:versionable] > mix:simpleVersionable, mix:referenceable + mixin + - jcr:versionHistory (REFERENCE) mandatory protected IGNORE < 'nt:versionHistory' + - jcr:baseVersion (REFERENCE) mandatory protected IGNORE < 'nt:version' + - jcr:predecessors (REFERENCE) mandatory protected multiple IGNORE < 'nt:version' + - jcr:mergeFailed (REFERENCE) protected multiple ABORT < 'nt:version' + /** @since 2.0 */ + - jcr:activity (REFERENCE) protected < 'nt:activity' + /** @since 2.0 */ + - jcr:configuration (REFERENCE) protected IGNORE < 'nt:configuration' + +/** + * @since 1.0 + */ +[nt:versionHistory] > mix:referenceable + - jcr:versionableUuid (STRING) mandatory autocreated protected ABORT + /** @since 2.0 */ + - jcr:copiedFrom (WEAKREFERENCE) 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 + +/** + * @since 1.0 + */ +[nt:versionLabels] + - * (REFERENCE) protected ABORT < 'nt:version' + +/** + * @since 1.0 + */ +[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' + /** @since 2.0 */ + - jcr:activity (REFERENCE) protected ABORT < 'nt:activity' + + jcr:frozenNode (nt:frozenNode) protected ABORT + +/** + * @since 1.0 + */ +[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 sns ABORT + +/** + * @since 1.0 + */ +[nt:versionedChild] + - jcr:childVersionHistory (REFERENCE) mandatory autocreated protected ABORT < 'nt:versionHistory' + +/** + * @since 2.0 + */ +[nt:activity] > mix:referenceable + - jcr:activityTitle (STRING) mandatory autocreated protected + +/** + * @since 2.0 + */ +[nt:configuration] > mix:versionable + - jcr:root (REFERENCE) mandatory autocreated protected + +//------------------------------------------------------------------------------ +// N O D E T Y P E S +//------------------------------------------------------------------------------ + +/** + * This node type is used to store a node type definition. Property and child node + * definitions within the node type definition are stored as same-name sibling nodes + * of type nt:propertyDefinition and nt:childNodeDefinition. + * + * @since 1.0 + */ +[nt:nodeType] + - jcr:nodeTypeName (NAME) protected mandatory + - jcr:supertypes (NAME) protected multiple + - jcr:isAbstract (BOOLEAN) protected mandatory + - jcr:isQueryable (BOOLEAN) protected mandatory + - jcr:isMixin (BOOLEAN) protected mandatory + - jcr:hasOrderableChildNodes (BOOLEAN) protected mandatory + - jcr:primaryItemName (NAME) protected + + jcr:propertyDefinition (nt:propertyDefinition) = nt:propertyDefinition protected sns + + jcr:childNodeDefinition (nt:childNodeDefinition) = nt:childNodeDefinition protected sns + +/** + * This node type used to store a property definition within a node type definition, + * which itself is stored as an nt:nodeType node. + * + * @since 1.0 + */ +[nt:propertyDefinition] + - jcr:name (NAME) protected + - jcr:autoCreated (BOOLEAN) protected mandatory + - jcr:mandatory (BOOLEAN) protected mandatory + - jcr:onParentVersion (STRING) protected mandatory + < 'COPY', 'VERSION', 'INITIALIZE', 'COMPUTE', 'IGNORE', 'ABORT' + - jcr:protected (BOOLEAN) protected mandatory + - jcr:requiredType (STRING) protected mandatory + < 'STRING', 'URI', 'BINARY', 'LONG', 'DOUBLE', + 'DECIMAL', 'BOOLEAN', 'DATE', 'NAME', 'PATH', + 'REFERENCE', 'WEAKREFERENCE', 'UNDEFINED' + - jcr:valueConstraints (STRING) protected multiple + - jcr:defaultValues (UNDEFINED) protected multiple + - jcr:multiple (BOOLEAN) protected mandatory + - jcr:availableQueryOperators (NAME) protected mandatory multiple + - jcr:isFullTextSearchable (BOOLEAN) protected mandatory + - jcr:isQueryOrderable (BOOLEAN) protected mandatory + +/** + * This node type used to store a child node definition within a node type definition, + * which itself is stored as an nt:nodeType node. + * + * @since 1.0 + */ +[nt:childNodeDefinition] + - jcr:name (NAME) protected + - jcr:autoCreated (BOOLEAN) protected mandatory + - jcr:mandatory (BOOLEAN) protected mandatory + - jcr:onParentVersion (STRING) protected mandatory + < 'COPY', 'VERSION', 'INITIALIZE', 'COMPUTE', 'IGNORE', 'ABORT' + - jcr:protected (BOOLEAN) protected mandatory + - jcr:requiredPrimaryTypes (NAME) = 'nt:base' protected mandatory multiple + - jcr:defaultPrimaryType (NAME) protected + - jcr:sameNameSiblings (BOOLEAN) protected mandatory + +//------------------------------------------------------------------------------ +// Q U E R Y +//------------------------------------------------------------------------------ + +/** + * @since 1.0 + */ +[nt:query] + - jcr:statement (STRING) + - jcr:language (STRING) + +//------------------------------------------------------------------------------ +// L I F E C Y C L E M A N A G E M E N T +//------------------------------------------------------------------------------ + +/** + * Only nodes with mixin node type mix:lifecycle may participate in a lifecycle. + * + * @peop jcr:lifecyclePolicy + * This property is a reference to another node that contains + * lifecycle policy information. The definition of the referenced + * node is not specified. + * @prop jcr:currentLifecycleState + * This property is a string identifying the current lifecycle + * state of this node. The format of this string is not specified. + * + * @since 2.0 + */ +[mix:lifecycle] + mixin + - jcr:lifecyclePolicy (REFERENCE) protected INITIALIZE + - jcr:currentLifecycleState (STRING) protected INITIALIZE + +//------------------------------------------------------------------------------ +// J A C K R A B B I T I N T E R N A L S +//------------------------------------------------------------------------------ + +[rep:root] > nt:unstructured + + 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 + // @since 2.0 + + jcr:activities (rep:Activities) = rep:Activities mandatory protected ABORT + // @since 2.0 + + jcr:configurations (rep:Configurations) = rep:Configurations protected ABORT + + * (nt:base) = nt:base IGNORE + + +/** + * Node Types (virtual) storage + */ +[rep:nodeTypes] + + * (nt:nodeType) = nt:nodeType protected ABORT + +/** + * Version storage + */ +[rep:versionStorage] + + * (nt:versionHistory) = nt:versionHistory protected ABORT + + * (rep:versionStorage) = rep:versionStorage protected ABORT + +/** + * Activities storage + * @since 2.0 + */ +[rep:Activities] + + * (nt:activity) = nt:activity protected ABORT + + * (rep:Activities) = rep:Activities protected ABORT + +/** + * the intermediate nodes for the configurations storage. + * Note: since the versionable node points to the configuration and vice versa, + * a configuration could never be removed because no such API exists. therefore + * the child node definitions are not protected. + * @since 2.0 + */ +[rep:Configurations] + + * (nt:configuration) = nt:configuration ABORT + + * (rep:Configurations) = rep:Configurations ABORT + +/** + * mixin that provides a multi value property for referencing versions. + * This is used for recording the baseline versions in the nt:configuration + * node, and to setup a bidirectional relationship between activities and + * the respective versions + * @since 2.0 + */ +[rep:VersionReference] mix + - rep:versions (REFERENCE) protected multiple + +// ----------------------------------------------------------------------------- +// J A C K R A B B I T S E C U R I T Y +// ----------------------------------------------------------------------------- + +[rep:AccessControllable] + mixin + + rep:policy (rep:Policy) protected IGNORE + +[rep:RepoAccessControllable] + mixin + + rep:repoPolicy (rep:Policy) protected IGNORE + +[rep:Policy] + abstract + +[rep:ACL] > rep:Policy + orderable + + * (rep:ACE) = rep:GrantACE protected IGNORE + +[rep:ACE] + - rep:principalName (STRING) protected mandatory + - rep:privileges (NAME) protected mandatory multiple + - rep:nodePath (PATH) protected + - rep:glob (STRING) protected + - * (UNDEFINED) protected + +[rep:GrantACE] > rep:ACE + +[rep:DenyACE] > rep:ACE + +// ----------------------------------------------------------------------------- +// Principal based AC +// ----------------------------------------------------------------------------- + +[rep:AccessControl] + + * (rep:AccessControl) protected IGNORE + + * (rep:PrincipalAccessControl) protected IGNORE + +[rep:PrincipalAccessControl] > rep:AccessControl + + rep:policy (rep:Policy) protected IGNORE + +// ----------------------------------------------------------------------------- +// User Management +// ----------------------------------------------------------------------------- + +[rep:Authorizable] > mix:referenceable, nt:hierarchyNode + abstract + + * (nt:base) = nt:unstructured VERSION + - rep:principalName (STRING) protected mandatory + - * (UNDEFINED) + - * (UNDEFINED) multiple + +[rep:Impersonatable] + mixin + - rep:impersonators (STRING) protected multiple + +[rep:User] > rep:Authorizable, rep:Impersonatable + - rep:password (STRING) protected mandatory + - rep:disabled (STRING) protected + +[rep:Group] > rep:Authorizable +// TODO: this seems a bug to me, multiple is not allowed on child node definitions +// + rep:members (rep:Members) = rep:Members multiple protected VERSION + - rep:members (WEAKREFERENCE) protected multiple < 'rep:Authorizable' + +[rep:AuthorizableFolder] > nt:hierarchyNode + + * (rep:Authorizable) = rep:User VERSION + + * (rep:AuthorizableFolder) = rep:AuthorizableFolder VERSION + +[rep:Members] + orderable +// TODO: this seems a bug to me, multiple is not allowed on child node definitions +// + * (rep:Members) = rep:Members protected multiple + - * (WEAKREFERENCE) protected < 'rep:Authorizable' + +// ----------------------------------------------------------------------------- +// J A C K R A B B I T R E T E N T I O N M A N A G E M E N T +// ----------------------------------------------------------------------------- + +[rep:RetentionManageable] + mixin + - rep:hold (UNDEFINED) protected multiple IGNORE + - rep:retentionPolicy (UNDEFINED) protected IGNORE diff --git a/tests/PhpcrUtils/resources/cnd/no-stop-at-eof.cnd b/tests/PhpcrUtils/resources/cnd/no-stop-at-eof.cnd new file mode 100644 index 00000000..a5534b7e --- /dev/null +++ b/tests/PhpcrUtils/resources/cnd/no-stop-at-eof.cnd @@ -0,0 +1,5 @@ +<'phpcr'='http://www.doctrine-project.org/projects/phpcr_odm'> +[phpcr:primary_item_test] > ? +- phpcr:content (STRING) += ? +< ? \ No newline at end of file