You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2008/04/04 17:55:39 UTC
svn commit: r644745 [2/3] - in /jackrabbit/trunk:
jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/
jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/
jackrabbit-spi-commons/ jackrabbit-spi-commons/src/main/jav...
Added: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefReader.java?rev=644745&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefReader.java (added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefReader.java Fri Apr 4 08:55:26 2008
@@ -0,0 +1,709 @@
+/*
+ * 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.
+ */
+package org.apache.jackrabbit.spi.commons.nodetype.compact;
+
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.jcr.NamespaceException;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.ValueFormatException;
+import javax.jcr.version.OnParentVersionAction;
+
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QNodeDefinition;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
+import org.apache.jackrabbit.spi.QValue;
+import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
+import org.apache.jackrabbit.spi.commons.conversion.NameException;
+import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
+import org.apache.jackrabbit.spi.commons.namespace.NamespaceMapping;
+import org.apache.jackrabbit.spi.commons.nodetype.InvalidConstraintException;
+import org.apache.jackrabbit.spi.commons.nodetype.compact.QNodeTypeDefinitionsBuilder.QNodeDefinitionBuilder;
+import org.apache.jackrabbit.spi.commons.nodetype.compact.QNodeTypeDefinitionsBuilder.QNodeTypeDefinitionBuilder;
+import org.apache.jackrabbit.spi.commons.nodetype.compact.QNodeTypeDefinitionsBuilder.QPropertyDefinitionBuilder;
+import org.apache.jackrabbit.util.ISO9075;
+
+/**
+ * CompactNodeTypeDefReader. Parses node type definitions written in the compact
+ * node type definition format and returns a list of QNodeTypeDefinition objects that
+ * can then be used to register node types.
+ * <p/>
+ * The EBNF grammar of the compact node type definition:<br>
+ * <pre>
+ * cnd ::= ns_mapping* node_type_def+
+ *
+ * ns_mapping ::= "<" prefix "=" namespace ">"
+ *
+ * prefix ::= string
+ *
+ * namespace ::= string
+ *
+ * node_type_def ::= node_type_name [super_types] [options] {property_def | node_def}
+ *
+ * node_type_name ::= "[" string "]"
+ *
+ * super_types ::= ">" string_list
+ *
+ * options ::= orderable_opt | mixin_opt | orderable_opt mixin_opt | mixin_opt orderable_opt
+ *
+ * orderable_opt ::= "orderable" | "ord" | "o"
+ *
+ * mixin_opt ::= "mixin" | "mix" | "m"
+ *
+ * property_def ::= "-" property_name [property_type_decl] [default_values] [attributes] [value_constraints]
+ *
+ * property_name ::= string
+ *
+ * property_type_decl ::= "(" property_type ")"
+ *
+ * property_type ::= "STRING" | "String |"string" |
+ * "BINARY" | "Binary" | "binary" |
+ * "LONG" | "Long" | "long" |
+ * "DOUBLE" | "Double" | "double" |
+ * "BOOLEAN" | "Boolean" | "boolean" |
+ * "DATE" | "Date" | "date" |
+ * "NAME | "Name | "name |
+ * "PATH" | "Path" | "path" |
+ * "REFERENCE" | "Reference" | "reference" |
+ * "UNDEFINED" | "Undefined" | "undefined" | "*"
+ *
+ *
+ * default_values ::= "=" string_list
+ *
+ * value_constraints ::= "<" string_list
+ *
+ * node_def ::= "+" node_name [required_types] [default_type] [attributes]
+ *
+ * node_name ::= string
+ *
+ * required_types ::= "(" string_list ")"
+ *
+ * default_type ::= "=" string
+ *
+ * attributes ::= "primary" | "pri" | "!" |
+ * "autocreated" | "aut" | "a" |
+ * "mandatory" | "man" | "m" |
+ * "protected" | "pro" | "p" |
+ * "multiple" | "mul" | "*" |
+ * "COPY" | "Copy" | "copy" |
+ * "VERSION" | "Version" | "version" |
+ * "INITIALIZE" | "Initialize" | "initialize" |
+ * "COMPUTE" | "Compute" | "compute" |
+ * "IGNORE" | "Ignore" | "ignore" |
+ * "ABORT" | "Abort" | "abort"
+ *
+ * string_list ::= string {"," string}
+ *
+ * string ::= quoted_string | unquoted_string
+ *
+ * quoted_string :: = "'" unquoted_string "'"
+ *
+ * unquoted_string ::= [A-Za-z0-9:_]+
+ * </pre>
+ */
+public class CompactNodeTypeDefReader {
+
+ /**
+ * Empty array of value constraints
+ */
+ private final static String[] EMPTY_VALUE_CONSTRAINTS = new String[0];
+
+ /**
+ * the list of parsed QNodeTypeDefinition
+ */
+ private final List nodeTypeDefs = new LinkedList();
+
+ /**
+ * the current namespace mapping
+ */
+ private final NamespaceMapping nsMapping;
+
+ /**
+ * Name and Path resolver
+ */
+ private final NamePathResolver resolver;
+
+ /**
+ * the underlying lexer
+ */
+ private final Lexer lexer;
+
+ /**
+ * the current token
+ */
+ private String currentToken;
+
+ /**
+ * The builder for QNodeTypeDefinitions
+ */
+ private final QNodeTypeDefinitionsBuilder builder;
+
+ /**
+ * Creates a new CND reader.
+ * @param r
+ * @param systemId
+ * @param builder
+ * @throws ParseException
+ */
+ public CompactNodeTypeDefReader(Reader r, String systemId, QNodeTypeDefinitionsBuilder builder) throws ParseException {
+ this(r, systemId, new NamespaceMapping(), builder);
+ }
+
+
+ /**
+ * Creates a new CND reader.
+ * @param r
+ * @param builder
+ * @throws ParseException
+ */
+ public CompactNodeTypeDefReader(Reader r, String systemId, NamespaceMapping mapping,
+ QNodeTypeDefinitionsBuilder builder) throws ParseException {
+
+ this.builder = builder;
+ lexer = new Lexer(r, systemId);
+ this.nsMapping = mapping;
+ this.resolver = new DefaultNamePathResolver(nsMapping);
+ nextToken();
+ parse();
+ }
+
+ /**
+ * Returns the list of parsed QNodeTypeDefinition definitions.
+ *
+ * @return a List of QNodeTypeDefinition objects
+ */
+ public List getNodeTypeDefs() {
+ return nodeTypeDefs;
+ }
+
+ /**
+ * Returns the namespace mapping.
+ *
+ * @return a NamespaceMapping object.
+ */
+ public NamespaceMapping getNamespaceMapping() {
+ return nsMapping;
+ }
+
+ /**
+ * Parses the definition
+ *
+ * @throws ParseException
+ */
+ private void parse() throws ParseException {
+ while (!currentTokenEquals(Lexer.EOF)) {
+ if (!doNameSpace()) {
+ break;
+ }
+ }
+ while (!currentTokenEquals(Lexer.EOF)) {
+ QNodeTypeDefinitionBuilder ntd = builder.newQNodeTypeDefinition();
+ ntd.setOrderableChildNodes(false);
+ ntd.setMixin(false);
+ ntd.setPrimaryItemName(null);
+ doNodeTypeName(ntd);
+ doSuperTypes(ntd);
+ doOptions(ntd);
+ doItemDefs(ntd);
+ nodeTypeDefs.add(ntd.build());
+ }
+ }
+
+
+
+ /**
+ * processes the namespace declaration
+ *
+ * @return
+ * @throws ParseException
+ */
+ private boolean doNameSpace() throws ParseException {
+ if (!currentTokenEquals('<')) {
+ return false;
+ }
+ nextToken();
+ String prefix = currentToken;
+ nextToken();
+ if (!currentTokenEquals('=')) {
+ lexer.fail("Missing = in namespace decl.");
+ }
+ nextToken();
+ String uri = currentToken;
+ nextToken();
+ if (!currentTokenEquals('>')) {
+ lexer.fail("Missing > in namespace decl.");
+ }
+ try {
+ nsMapping.setMapping(prefix, uri);
+ } catch (NamespaceException e) {
+ // ignore
+ }
+ nextToken();
+ return true;
+ }
+
+ /**
+ * processes the nodetype name
+ *
+ * @param ntd
+ * @throws ParseException
+ */
+ private void doNodeTypeName(QNodeTypeDefinitionBuilder ntd) throws ParseException {
+ if (!currentTokenEquals(Lexer.BEGIN_NODE_TYPE_NAME)) {
+ lexer.fail("Missing '" + Lexer.BEGIN_NODE_TYPE_NAME + "' delimiter for beginning of node type name");
+ }
+ nextToken();
+ ntd.setName(toName(currentToken));
+
+ nextToken();
+ if (!currentTokenEquals(Lexer.END_NODE_TYPE_NAME)) {
+ lexer.fail("Missing '" + Lexer.END_NODE_TYPE_NAME + "' delimiter for end of node type name, found " + currentToken);
+ }
+ nextToken();
+ }
+
+ /**
+ * processes the superclasses
+ *
+ * @param ntd
+ * @throws ParseException
+ */
+ private void doSuperTypes(QNodeTypeDefinitionBuilder ntd) throws ParseException {
+ // a set would be nicer here, in case someone defines a supertype twice.
+ // but due to issue [JCR-333], the resulting node type definition is
+ // not symmetric anymore and the tests will fail.
+ ArrayList supertypes = new ArrayList();
+ if (currentTokenEquals(Lexer.EXTENDS))
+ do {
+ nextToken();
+ supertypes.add(toName(currentToken));
+ nextToken();
+ } while (currentTokenEquals(Lexer.LIST_DELIMITER));
+
+ ntd.setSupertypes((Name[]) supertypes.toArray(new Name[0]));
+ }
+
+ /**
+ * processes the options
+ *
+ * @param ntd
+ * @throws ParseException
+ */
+ private void doOptions(QNodeTypeDefinitionBuilder ntd) throws ParseException {
+ if (currentTokenEquals(Lexer.ORDERABLE)) {
+ ntd.setOrderableChildNodes(true);
+ nextToken();
+ if (currentTokenEquals(Lexer.MIXIN)) {
+ ntd.setMixin(true);
+ nextToken();
+ }
+ } else if (currentTokenEquals(Lexer.MIXIN)) {
+ ntd.setMixin(true);
+ nextToken();
+ if (currentTokenEquals(Lexer.ORDERABLE)) {
+ ntd.setOrderableChildNodes(true);
+ nextToken();
+ }
+ }
+ }
+
+ /**
+ * processes the item definitions
+ *
+ * @param ntd
+ * @throws ParseException
+ */
+ private void doItemDefs(QNodeTypeDefinitionBuilder ntd) throws ParseException {
+ List propertyDefinitions = new ArrayList();
+ List nodeDefinitions = new ArrayList();
+ while (currentTokenEquals(Lexer.PROPERTY_DEFINITION) || currentTokenEquals(Lexer.CHILD_NODE_DEFINITION)) {
+ if (currentTokenEquals(Lexer.PROPERTY_DEFINITION)) {
+ QPropertyDefinitionBuilder pd = ntd.newQPropertyDefinition();
+
+ pd.setAutoCreated(false);
+ pd.setDeclaringNodeType(ntd.getName());
+ pd.setDefaultValues(null);
+ pd.setMandatory(false);
+ pd.setMultiple(false);
+ pd.setOnParentVersion(OnParentVersionAction.COPY);
+ pd.setProtected(false);
+ pd.setRequiredType(PropertyType.STRING);
+ pd.setValueConstraints(EMPTY_VALUE_CONSTRAINTS);
+
+ nextToken();
+ doPropertyDefinition(pd, ntd);
+ propertyDefinitions.add(pd.build());
+
+ } else if (currentTokenEquals(Lexer.CHILD_NODE_DEFINITION)) {
+ QNodeDefinitionBuilder nd = ntd.newQNodeDefinitionBuilder();
+
+ nd.setAllowsSameNameSiblings(false);
+ nd.setAutoCreated(false);
+ nd.setDeclaringNodeType(ntd.getName());
+ nd.setMandatory(false);
+ nd.setOnParentVersion(OnParentVersionAction.COPY);
+ nd.setProtected(false);
+ nd.setDefaultPrimaryType(null);
+ nd.setRequiredPrimaryTypes(new Name[]{NameConstants.NT_BASE});
+
+ nextToken();
+ doChildNodeDefinition(nd, ntd);
+ nodeDefinitions.add(nd.build());
+ }
+ }
+
+ ntd.setPropertyDefs((QPropertyDefinition[]) propertyDefinitions
+ .toArray(new QPropertyDefinition[0]));
+
+ ntd.setChildNodeDefs((QNodeDefinition[]) nodeDefinitions.toArray(new QNodeDefinition[0]));
+ }
+
+ /**
+ * processes the property definition
+ *
+ * @param pd
+ * @param ntd
+ * @throws ParseException
+ */
+ private void doPropertyDefinition(QPropertyDefinitionBuilder pd, QNodeTypeDefinitionBuilder ntd)
+ throws ParseException {
+ if (currentToken.equals("*")) {
+ pd.setName(NameConstants.ANY_NAME);
+ } else {
+ pd.setName(toName(currentToken));
+ }
+ nextToken();
+ doPropertyType(pd);
+ doPropertyDefaultValue(pd);
+ doPropertyAttributes(pd, ntd);
+ doPropertyValueConstraints(pd);
+ }
+
+ /**
+ * processes the property type
+ *
+ * @param pd
+ * @throws ParseException
+ */
+ private void doPropertyType(QPropertyDefinitionBuilder pd) throws ParseException {
+ if (!currentTokenEquals(Lexer.BEGIN_TYPE)) {
+ return;
+ }
+ nextToken();
+ if (currentTokenEquals(Lexer.STRING)) {
+ pd.setRequiredType(PropertyType.STRING);
+ } else if (currentTokenEquals(Lexer.BINARY)) {
+ pd.setRequiredType(PropertyType.BINARY);
+ } else if (currentTokenEquals(Lexer.LONG)) {
+ pd.setRequiredType(PropertyType.LONG);
+ } else if (currentTokenEquals(Lexer.DOUBLE)) {
+ pd.setRequiredType(PropertyType.DOUBLE);
+ } else if (currentTokenEquals(Lexer.BOOLEAN)) {
+ pd.setRequiredType(PropertyType.BOOLEAN);
+ } else if (currentTokenEquals(Lexer.DATE)) {
+ pd.setRequiredType(PropertyType.DATE);
+ } else if (currentTokenEquals(Lexer.NAME)) {
+ pd.setRequiredType(PropertyType.NAME);
+ } else if (currentTokenEquals(Lexer.PATH)) {
+ pd.setRequiredType(PropertyType.PATH);
+ } else if (currentTokenEquals(Lexer.REFERENCE)) {
+ pd.setRequiredType(PropertyType.REFERENCE);
+ } else if (currentTokenEquals(Lexer.UNDEFINED)) {
+ pd.setRequiredType(PropertyType.UNDEFINED);
+ } else {
+ lexer.fail("Unkown property type '" + currentToken + "' specified");
+ }
+ nextToken();
+ if (!currentTokenEquals(Lexer.END_TYPE)) {
+ lexer.fail("Missing '" + Lexer.END_TYPE + "' delimiter for end of property type");
+ }
+ nextToken();
+ }
+
+ /**
+ * processes the property attributes
+ *
+ * @param pd
+ * @param ntd
+ * @throws ParseException
+ */
+ private void doPropertyAttributes(QPropertyDefinitionBuilder pd, QNodeTypeDefinitionBuilder ntd) throws ParseException {
+ while (currentTokenEquals(Lexer.ATTRIBUTE)) {
+ if (currentTokenEquals(Lexer.PRIMARY)) {
+ if (ntd.getPrimaryItemName() != null) {
+ String name = null;
+ try {
+ name = resolver.getJCRName(ntd.getName());
+ } catch (NamespaceException e) {
+ // Should never happen, checked earlier
+ }
+ lexer.fail("More than one primary item specified in node type '" + name + "'");
+ }
+ ntd.setPrimaryItemName(pd.getName());
+ } else if (currentTokenEquals(Lexer.AUTOCREATED)) {
+ pd.setAutoCreated(true);
+ } else if (currentTokenEquals(Lexer.MANDATORY)) {
+ pd.setMandatory(true);
+ } else if (currentTokenEquals(Lexer.PROTECTED)) {
+ pd.setProtected(true);
+ } else if (currentTokenEquals(Lexer.MULTIPLE)) {
+ pd.setMultiple(true);
+ } else if (currentTokenEquals(Lexer.COPY)) {
+ pd.setOnParentVersion(OnParentVersionAction.COPY);
+ } else if (currentTokenEquals(Lexer.VERSION)) {
+ pd.setOnParentVersion(OnParentVersionAction.VERSION);
+ } else if (currentTokenEquals(Lexer.INITIALIZE)) {
+ pd.setOnParentVersion(OnParentVersionAction.INITIALIZE);
+ } else if (currentTokenEquals(Lexer.COMPUTE)) {
+ pd.setOnParentVersion(OnParentVersionAction.COMPUTE);
+ } else if (currentTokenEquals(Lexer.IGNORE)) {
+ pd.setOnParentVersion(OnParentVersionAction.IGNORE);
+ } else if (currentTokenEquals(Lexer.ABORT)) {
+ pd.setOnParentVersion(OnParentVersionAction.ABORT);
+ }
+ nextToken();
+ }
+ }
+
+ /**
+ * processes the property default values
+ *
+ * @param pd
+ * @throws ParseException
+ */
+ private void doPropertyDefaultValue(QPropertyDefinitionBuilder pd) throws ParseException {
+ if (!currentTokenEquals(Lexer.DEFAULT)) {
+ return;
+ }
+ List defaultValues = new ArrayList();
+ do {
+ nextToken();
+ QValue value = null;
+ try {
+ value = pd.createValue(currentToken, resolver);
+ } catch (ValueFormatException e) {
+ lexer.fail("'" + currentToken + "' is not a valid string representation of a value of type " + pd.getRequiredType());
+ } catch (RepositoryException e) {
+ lexer.fail("An error occured during value conversion of '" + currentToken + "'");
+ }
+ defaultValues.add(value);
+ nextToken();
+ } while (currentTokenEquals(Lexer.LIST_DELIMITER));
+ pd.setDefaultValues((QValue[]) defaultValues.toArray(new QValue[0]));
+ }
+
+ /**
+ * processes the property value constraints
+ *
+ * @param pd
+ * @throws ParseException
+ */
+ private void doPropertyValueConstraints(QPropertyDefinitionBuilder pd) throws ParseException {
+ if (!currentTokenEquals(Lexer.CONSTRAINT)) {
+ return;
+ }
+ List constraints = new ArrayList();
+ do {
+ nextToken();
+ String constraint = null;
+ try {
+ constraint = pd.createValueConstraint(currentToken, resolver);
+ } catch (InvalidConstraintException e) {
+ lexer.fail("'" + currentToken + "' is not a valid constraint expression for a value of type " + pd.getRequiredType());
+ }
+ constraints.add(constraint);
+ nextToken();
+ } while (currentTokenEquals(Lexer.LIST_DELIMITER));
+ pd.setValueConstraints((String[]) constraints.toArray(new String[0]));
+ }
+
+ /**
+ * processes the childnode definition
+ *
+ * @param nd
+ * @param ntd
+ * @throws ParseException
+ */
+ private void doChildNodeDefinition(QNodeDefinitionBuilder nd, QNodeTypeDefinitionBuilder ntd)
+ throws ParseException {
+ if (currentTokenEquals('*')) {
+ nd.setName(NameConstants.ANY_NAME);
+ } else {
+ nd.setName(toName(currentToken));
+ }
+ nextToken();
+ doChildNodeRequiredTypes(nd);
+ doChildNodeDefaultType(nd);
+ doChildNodeAttributes(nd, ntd);
+ }
+
+ /**
+ * processes the childnode required types
+ *
+ * @param nd
+ * @throws ParseException
+ */
+ private void doChildNodeRequiredTypes(QNodeDefinitionBuilder nd) throws ParseException {
+ if (!currentTokenEquals(Lexer.BEGIN_TYPE)) {
+ return;
+ }
+ List types = new ArrayList();
+ do {
+ nextToken();
+ types.add(toName(currentToken));
+ nextToken();
+ } while (currentTokenEquals(Lexer.LIST_DELIMITER));
+ nd.setRequiredPrimaryTypes((Name[]) types.toArray(new Name[0]));
+ nextToken();
+ }
+
+ /**
+ * processes the childnode default types
+ *
+ * @param nd
+ * @throws ParseException
+ */
+ private void doChildNodeDefaultType(QNodeDefinitionBuilder nd) throws ParseException {
+ if (!currentTokenEquals(Lexer.DEFAULT)) {
+ return;
+ }
+ nextToken();
+ nd.setDefaultPrimaryType(toName(currentToken));
+ nextToken();
+ }
+
+ /**
+ * processes the childnode attributes
+ *
+ * @param nd
+ * @param ntd
+ * @throws ParseException
+ */
+ private void doChildNodeAttributes(QNodeDefinitionBuilder nd, QNodeTypeDefinitionBuilder ntd) throws ParseException {
+ while (currentTokenEquals(Lexer.ATTRIBUTE)) {
+ if (currentTokenEquals(Lexer.PRIMARY)) {
+ if (ntd.getPrimaryItemName() != null) {
+ String name = null;
+ try {
+ name = resolver.getJCRName(ntd.getName());
+ } catch (NamespaceException e) {
+ // Should never happen, checked earlier
+ }
+ lexer.fail("More than one primary item specified in node type '" + name + "'");
+ }
+ ntd.setPrimaryItemName(nd.getName());
+ } else if (currentTokenEquals(Lexer.AUTOCREATED)) {
+ nd.setAutoCreated(true);
+ } else if (currentTokenEquals(Lexer.MANDATORY)) {
+ nd.setMandatory(true);
+ } else if (currentTokenEquals(Lexer.PROTECTED)) {
+ nd.setProtected(true);
+ } else if (currentTokenEquals(Lexer.MULTIPLE)) {
+ nd.setAllowsSameNameSiblings(true);
+ } else if (currentTokenEquals(Lexer.COPY)) {
+ nd.setOnParentVersion(OnParentVersionAction.COPY);
+ } else if (currentTokenEquals(Lexer.VERSION)) {
+ nd.setOnParentVersion(OnParentVersionAction.VERSION);
+ } else if (currentTokenEquals(Lexer.INITIALIZE)) {
+ nd.setOnParentVersion(OnParentVersionAction.INITIALIZE);
+ } else if (currentTokenEquals(Lexer.COMPUTE)) {
+ nd.setOnParentVersion(OnParentVersionAction.COMPUTE);
+ } else if (currentTokenEquals(Lexer.IGNORE)) {
+ nd.setOnParentVersion(OnParentVersionAction.IGNORE);
+ } else if (currentTokenEquals(Lexer.ABORT)) {
+ nd.setOnParentVersion(OnParentVersionAction.ABORT);
+ }
+ nextToken();
+ }
+ }
+
+ /**
+ * Converts the given string into a qualified name using the current
+ * namespace mapping.
+ *
+ * @param stringName
+ * @return the qualified name
+ * @throws ParseException if the conversion fails
+ */
+ private Name toName(String stringName) throws ParseException {
+ try {
+ Name n = resolver.getQName(stringName);
+ String decodedLocalName = ISO9075.decode(n.getLocalName());
+ return builder.createName(n.getNamespaceURI(), decodedLocalName);
+ } catch (NameException e) {
+ lexer.fail("Error while parsing '" + stringName + "'", e);
+ return null;
+ } catch (NamespaceException e) {
+ lexer.fail("Error while parsing '" + stringName + "'", e);
+ return null;
+ }
+ }
+
+ /**
+ * Gets the next token from the underlying lexer.
+ *
+ * @see Lexer#getNextToken()
+ * @throws ParseException if the lexer fails to get the next token.
+ */
+ private void nextToken() throws ParseException {
+ currentToken = lexer.getNextToken();
+ }
+
+ /**
+ * Checks if the {@link #currentToken} is semantically equal to the given
+ * argument.
+ *
+ * @param s the tokens to compare with
+ * @return <code>true</code> if equals; <code>false</code> otherwise.
+ */
+ private boolean currentTokenEquals(String[] s) {
+ for (int i = 0; i < s.length; i++) {
+ if (currentToken.equals(s[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if the {@link #currentToken} is semantically equal to the given
+ * argument.
+ *
+ * @param c the tokens to compare with
+ * @return <code>true</code> if equals; <code>false</code> otherwise.
+ */
+ private boolean currentTokenEquals(char c) {
+ return currentToken.length() == 1 && currentToken.charAt(0) == c;
+ }
+
+ /**
+ * Checks if the {@link #currentToken} is semantically equal to the given
+ * argument.
+ *
+ * @param s the tokens to compare with
+ * @return <code>true</code> if equals; <code>false</code> otherwise.
+ */
+ private boolean currentTokenEquals(String s) {
+ return currentToken.equals(s);
+ }
+
+}
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefReader.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java?rev=644745&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java (added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java Fri Apr 4 08:55:26 2008
@@ -0,0 +1,470 @@
+/*
+ * 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.
+ */
+package org.apache.jackrabbit.spi.commons.nodetype.compact;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.NamespaceException;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.version.OnParentVersionAction;
+
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QNodeDefinition;
+import org.apache.jackrabbit.spi.QNodeTypeDefinition;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
+import org.apache.jackrabbit.spi.QValue;
+import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
+import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver;
+import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl;
+import org.apache.jackrabbit.spi.commons.value.ValueFormat;
+import org.apache.jackrabbit.util.ISO9075;
+
+/**
+ * Prints node type defs in a compact notation
+ * Print Format:
+ * <ex = "http://apache.org/jackrabbit/example">
+ * [ex:NodeType] > ex:ParentType1, ex:ParentType2
+ * orderable mixin
+ * - ex:property (STRING) = 'default1', 'default2'
+ * primary mandatory autocreated protected multiple VERSION
+ * < 'constraint1', 'constraint2'
+ * + ex:node (ex:reqType1, ex:reqType2) = ex:defaultType
+ * mandatory autocreated protected multiple VERSION
+ */
+public class CompactNodeTypeDefWriter {
+
+ /**
+ * the indention string
+ */
+ private static final String INDENT = " ";
+
+ /**
+ * the current namespace resolver
+ */
+ private final NamespaceResolver resolver;
+
+ /**
+ * the current name/path resolver
+ */
+ private final NamePathResolver npResolver;
+
+ /**
+ * the current value factory
+ */
+ private final ValueFactory valueFactory;
+
+ /**
+ * the underlying writer
+ */
+ private Writer out;
+
+ /**
+ * special writer used for namespaces
+ */
+ private Writer nsWriter;
+
+ /**
+ * namespaces(prefixes) that are used
+ */
+ private final HashSet usedNamespaces = new HashSet();
+
+ /**
+ * Creates a new nodetype writer
+ *
+ * @param out the underlying writer
+ * @param r the namespace resolver
+ * @param npResolver
+ * @param valueFactory
+ */
+ public CompactNodeTypeDefWriter(Writer out, NamespaceResolver r, NamePathResolver npResolver,
+ ValueFactory valueFactory) {
+ this(out, r, npResolver, valueFactory, false);
+ }
+
+ /**
+ * Creates a new nodetype writer
+ *
+ * @param out the underlaying writer
+ * @param r the naespace resolver
+ * @param npResolver
+ * @param valueFactory
+ * @param includeNS if <code>true</code> all used namespace decl. are also
+ */
+ public CompactNodeTypeDefWriter(Writer out, NamespaceResolver r, NamePathResolver npResolver,
+ ValueFactory valueFactory, boolean includeNS) {
+ this.resolver = r;
+ this.npResolver = npResolver;
+ this.valueFactory = valueFactory;
+ if (includeNS) {
+ this.out = new StringWriter();
+ this.nsWriter = out;
+ } else {
+ this.out = out;
+ this.nsWriter = null;
+ }
+ }
+
+ /**
+ * Writes the given list of QNodeTypeDefinition to the output writer including the
+ * used namespaces.
+ *
+ * @param l
+ * @param r
+ * @param npResolver
+ * @param valueFactory
+ * @param out
+ * @throws IOException
+ */
+ public static void write(List l, NamespaceResolver r, NamePathResolver npResolver,
+ ValueFactory valueFactory, Writer out)
+ throws IOException {
+ CompactNodeTypeDefWriter w = new CompactNodeTypeDefWriter(out, r, npResolver, valueFactory, true);
+ Iterator iter = l.iterator();
+ while (iter.hasNext()) {
+ QNodeTypeDefinition def = (QNodeTypeDefinition) iter.next();
+ w.write(def);
+ }
+ w.close();
+ }
+
+ /**
+ * Write one QNodeTypeDefinition to this writer
+ *
+ * @param ntd
+ * @throws IOException
+ */
+ public void write(QNodeTypeDefinition ntd) throws IOException {
+ writeName(ntd);
+ writeSupertypes(ntd);
+ writeOptions(ntd);
+ writePropDefs(ntd);
+ writeNodeDefs(ntd);
+ out.write("\n\n");
+ }
+
+ /**
+ * Flushes all pending write operations and Closes this writer. please note,
+ * that the underlying writer remains open.
+ *
+ * @throws IOException
+ */
+ public void close() throws IOException {
+ if (nsWriter != null) {
+ nsWriter.write("\n");
+ out.close();
+ nsWriter.write(((StringWriter) out).getBuffer().toString());
+ out = nsWriter;
+ nsWriter = null;
+ }
+ out.flush();
+ out = null;
+ }
+
+ /**
+ * write name
+ */
+ private void writeName(QNodeTypeDefinition ntd) throws IOException {
+ out.write("[");
+ out.write(resolve(ntd.getName()));
+ out.write("]");
+ }
+
+ /**
+ * write supertypes
+ */
+ private void writeSupertypes(QNodeTypeDefinition ntd) throws IOException {
+ Name[] sta = ntd.getSupertypes();
+ String delim = " > ";
+ for (int i = 0; i < sta.length; i++) {
+ out.write(delim);
+ out.write(resolve(sta[i]));
+ delim = ", ";
+ }
+ }
+
+ /**
+ * write options
+ */
+ private void writeOptions(QNodeTypeDefinition ntd) throws IOException {
+ if (ntd.hasOrderableChildNodes()) {
+ out.write("\n" + INDENT);
+ out.write("orderable");
+ if (ntd.isMixin()) {
+ out.write(" mixin");
+ }
+ } else if (ntd.isMixin()) {
+ out.write("\n" + INDENT);
+ out.write("mixin");
+ }
+ }
+
+ /**
+ * write prop defs
+ */
+ private void writePropDefs(QNodeTypeDefinition ntd) throws IOException {
+ QPropertyDefinition[] pda = ntd.getPropertyDefs();
+ for (int i = 0; i < pda.length; i++) {
+ QPropertyDefinition pd = pda[i];
+ writePropDef(ntd, pd);
+ }
+ }
+
+ /**
+ * write node defs
+ */
+ private void writeNodeDefs(QNodeTypeDefinition ntd) throws IOException {
+ QNodeDefinition[] nda = ntd.getChildNodeDefs();
+ for (int i = 0; i < nda.length; i++) {
+ QNodeDefinition nd = nda[i];
+ writeNodeDef(ntd, nd);
+ }
+ }
+
+ /**
+ * write prop def
+ * @param pd
+ */
+ private void writePropDef(QNodeTypeDefinition ntd, QPropertyDefinition pd) throws IOException {
+ out.write("\n" + INDENT + "- ");
+
+ Name name = pd.getName();
+ if (name.equals(NameConstants.ANY_NAME)) {
+ out.write('*');
+ } else {
+ writeItemDefName(name);
+ }
+
+ out.write(" (");
+ out.write(PropertyType.nameFromValue(pd.getRequiredType()).toLowerCase());
+ out.write(")");
+ writeDefaultValues(pd.getDefaultValues());
+ out.write(ntd.getPrimaryItemName() != null && ntd.getPrimaryItemName().equals(pd.getName()) ? " primary" : "");
+ if (pd.isMandatory()) {
+ out.write(" mandatory");
+ }
+ if (pd.isAutoCreated()) {
+ out.write(" autocreated");
+ }
+ if (pd.isProtected()) {
+ out.write(" protected");
+ }
+ if (pd.isMultiple()) {
+ out.write(" multiple");
+ }
+ if (pd.getOnParentVersion() != OnParentVersionAction.COPY) {
+ out.write(" ");
+ out.write(OnParentVersionAction.nameFromValue(pd.getOnParentVersion()).toLowerCase());
+ }
+ writeValueConstraints(pd.getValueConstraints(), pd.getRequiredType());
+ }
+
+ /**
+ * write default values
+ * @param dva
+ */
+ private void writeDefaultValues(QValue[] dva) throws IOException {
+ if (dva != null && dva.length > 0) {
+ String delim = " = '";
+ for (int i = 0; i < dva.length; i++) {
+ out.write(delim);
+ try {
+ Value v = ValueFormat.getJCRValue(dva[i], npResolver, valueFactory);
+ out.write(escape(v.getString()));
+ } catch (RepositoryException e) {
+ out.write(escape(dva[i].toString()));
+ }
+ out.write("'");
+ delim = ", '";
+ }
+ }
+ }
+
+ /**
+ * write value constraints
+ * @param vca
+ */
+ private void writeValueConstraints(String[] vca, int type) throws IOException {
+ if (vca != null && vca.length > 0) {
+ String vc = convertConstraint(vca[0], type);
+ out.write(" < '");
+ out.write(escape(vc));
+ out.write("'");
+ for (int i = 1; i < vca.length; i++) {
+ vc = convertConstraint(vca[i], type);
+ out.write(", '");
+ out.write(escape(vc));
+ out.write("'");
+ }
+ }
+ }
+
+ private String convertConstraint(String vc, int type) {
+ if (type == PropertyType.REFERENCE || type == PropertyType.NAME || type == PropertyType.PATH) {
+ if (type == PropertyType.REFERENCE)
+ type = PropertyType.NAME;
+
+ try {
+ QValue qv = QValueFactoryImpl.getInstance().create(vc, type);
+ vc = ValueFormat.getJCRValue(qv, npResolver, valueFactory).getString();
+ }
+ catch (RepositoryException e) {
+ // ignore -> return unconverted constraint
+ }
+ }
+
+ return vc;
+ }
+
+ /**
+ * write node def
+ *
+ * @param nd
+ */
+ private void writeNodeDef(QNodeTypeDefinition ntd, QNodeDefinition nd) throws IOException {
+ out.write("\n" + INDENT + "+ ");
+
+ Name name = nd.getName();
+ if (name.equals(NameConstants.ANY_NAME)) {
+ out.write('*');
+ } else {
+ writeItemDefName(name);
+ }
+ writeRequiredTypes(nd.getRequiredPrimaryTypes());
+ writeDefaultType(nd.getDefaultPrimaryType());
+ out.write(ntd.getPrimaryItemName() != null && ntd.getPrimaryItemName().equals(nd.getName()) ? " primary" : "");
+ if (nd.isMandatory()) {
+ out.write(" mandatory");
+ }
+ if (nd.isAutoCreated()) {
+ out.write(" autocreated");
+ }
+ if (nd.isProtected()) {
+ out.write(" protected");
+ }
+ if (nd.allowsSameNameSiblings()) {
+ out.write(" multiple");
+ }
+ if (nd.getOnParentVersion() != OnParentVersionAction.COPY) {
+ out.write(" ");
+ out.write(OnParentVersionAction.nameFromValue(nd.getOnParentVersion()).toLowerCase());
+ }
+ }
+
+ /**
+ * Write item def name
+ * @param name
+ * @throws IOException
+ */
+ private void writeItemDefName(Name name) throws IOException {
+ out.write(resolve(name));
+ }
+ /**
+ * write required types
+ * @param reqTypes
+ */
+ private void writeRequiredTypes(Name[] reqTypes) throws IOException {
+ if (reqTypes != null && reqTypes.length > 0) {
+ String delim = " (";
+ for (int i = 0; i < reqTypes.length; i++) {
+ out.write(delim);
+ out.write(resolve(reqTypes[i]));
+ delim = ", ";
+ }
+ out.write(")");
+ }
+ }
+
+ /**
+ * write default types
+ * @param defType
+ */
+ private void writeDefaultType(Name defType) throws IOException {
+ if (defType != null && !defType.getLocalName().equals("*")) {
+ out.write(" = ");
+ out.write(resolve(defType));
+ }
+ }
+
+ /**
+ * resolve
+ * @param name
+ * @return the resolved name
+ */
+ private String resolve(Name name) throws IOException {
+ if (name == null) {
+ return "";
+ }
+ try {
+ String prefix = resolver.getPrefix(name.getNamespaceURI());
+ if (prefix != null && !prefix.equals(Name.NS_EMPTY_PREFIX)) {
+ // check for writing namespaces
+ if (nsWriter != null) {
+ if (!usedNamespaces.contains(prefix)) {
+ usedNamespaces.add(prefix);
+ nsWriter.write("<'");
+ nsWriter.write(prefix);
+ nsWriter.write("'='");
+ nsWriter.write(escape(name.getNamespaceURI()));
+ nsWriter.write("'>\n");
+ }
+ }
+ prefix += ":";
+ }
+
+ String encLocalName = ISO9075.encode(name.getLocalName());
+ String resolvedName = prefix + encLocalName;
+
+ // check for '-' and '+'
+ if (resolvedName.indexOf('-') >= 0 || resolvedName.indexOf('+') >= 0) {
+ return "'" + resolvedName + "'";
+ } else {
+ return resolvedName;
+ }
+
+ } catch (NamespaceException e) {
+ return name.toString();
+ }
+ }
+
+ /**
+ * escape
+ * @param s
+ * @return the escaped string
+ */
+ private String escape(String s) {
+ StringBuffer sb = new StringBuffer(s);
+ for (int i = 0; i < sb.length(); i++) {
+ if (sb.charAt(i) == '\\') {
+ sb.insert(i, '\\');
+ i++;
+ } else if (sb.charAt(i) == '\'') {
+ sb.insert(i, '\'');
+ i++;
+ }
+ }
+ return sb.toString();
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/Lexer.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/Lexer.java?rev=644745&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/Lexer.java (added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/Lexer.java Fri Apr 4 08:55:26 2008
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ */
+package org.apache.jackrabbit.spi.commons.nodetype.compact;
+
+import java.io.StreamTokenizer;
+import java.io.Reader;
+import java.io.IOException;
+
+/**
+ * Lexer
+ */
+public class Lexer {
+ public static final char SINGLE_QUOTE = '\'';
+ public static final char DOUBLE_QUOTE = '\"';
+ public static final char BEGIN_NODE_TYPE_NAME = '[';
+ public static final char END_NODE_TYPE_NAME = ']';
+ public static final char EXTENDS = '>';
+ public static final char LIST_DELIMITER = ',';
+ public static final char PROPERTY_DEFINITION = '-';
+ public static final char CHILD_NODE_DEFINITION = '+';
+ public static final char BEGIN_TYPE = '(';
+ public static final char END_TYPE = ')';
+ public static final char DEFAULT = '=';
+ public static final char CONSTRAINT = '<';
+
+ public static final String[] ORDERABLE = new String[] {"orderable", "ord", "o"};
+ public static final String[] MIXIN = new String[]{"mixin", "mix", "m"};
+
+ public static final String[] PRIMARY = new String[]{"primary", "pri", "!"};
+ public static final String[] AUTOCREATED = new String[]{"autocreated", "aut", "a"};
+ public static final String[] MANDATORY = new String[]{"mandatory", "man", "m"};
+ public static final String[] PROTECTED = new String[]{"protected", "pro", "p"};
+ public static final String[] MULTIPLE = new String[]{"multiple", "mul", "*"};
+
+ public static final String[] COPY = new String[]{"copy", "Copy", "COPY"};
+ public static final String[] VERSION = new String[]{"version", "Version", "VERSION"};
+ public static final String[] INITIALIZE = new String[]{"initialize", "Initialize", "INITIALIZE"};
+ public static final String[] COMPUTE = new String[]{"compute", "Compute", "COMPUTE"};
+ public static final String[] IGNORE = new String[]{"ignore", "Ignore", "IGNORE"};
+ public static final String[] ABORT = new String[]{"abort", "Abort", "ABORT"};
+
+ public static final String[] ATTRIBUTE = new String[]{"primary", "pri", "!",
+ "autocreated", "aut", "a",
+ "mandatory", "man", "m",
+ "protected", "pro", "p",
+ "multiple", "mul", "*",
+ "copy", "Copy", "COPY",
+ "version", "Version", "VERSION",
+ "initialize", "Initialize", "INITIALIZE",
+ "compute", "Compute", "COMPUTE",
+ "ignore", "Ignore", "IGNORE",
+ "abort", "Abort", "ABORT"};
+
+ public static final String[] STRING = {"string", "String", "STRING"};
+ public static final String[] BINARY = {"binary", "Binary", "BINARY"};
+ public static final String[] LONG = {"long", "Long", "LONG"};
+ public static final String[] DOUBLE = {"double", "Double", "DOUBLE"};
+ public static final String[] BOOLEAN = {"boolean", "Boolean", "BOOLEAN"};
+ public static final String[] DATE = {"date", "Date", "DATE"};
+ public static final String[] NAME = {"name", "Name", "NAME"};
+ public static final String[] PATH = {"path", "Path", "PATH"};
+ public static final String[] REFERENCE = {"reference", "Reference", "REFERENCE"};
+
+ public static final String[] UNDEFINED = new String[]{"undefined", "Undefined", "UNDEFINED", "*"};
+
+ public static final String EOF = "eof";
+
+ private final StreamTokenizer st;
+
+ private final String systemId;
+
+ /**
+ * Constructor
+ * @param r
+ */
+ public Lexer(Reader r, String systemId) {
+ this.systemId = systemId;
+ st = new StreamTokenizer(r);
+
+ st.eolIsSignificant(false);
+
+ st.lowerCaseMode(false);
+
+ st.slashSlashComments(true);
+ st.slashStarComments(true);
+
+ st.wordChars('a', 'z');
+ st.wordChars('A', 'Z');
+ st.wordChars(':', ':');
+ st.wordChars('_', '_');
+
+ st.quoteChar(SINGLE_QUOTE);
+ st.quoteChar(DOUBLE_QUOTE);
+
+ st.ordinaryChar(BEGIN_NODE_TYPE_NAME);
+ st.ordinaryChar(END_NODE_TYPE_NAME);
+ st.ordinaryChar(EXTENDS);
+ st.ordinaryChar(LIST_DELIMITER);
+ st.ordinaryChar(PROPERTY_DEFINITION);
+ st.ordinaryChar(CHILD_NODE_DEFINITION);
+ st.ordinaryChar(BEGIN_TYPE);
+ st.ordinaryChar(END_TYPE);
+ st.ordinaryChar(DEFAULT);
+ st.ordinaryChar(CONSTRAINT);
+ }
+
+ /**
+ * getNextToken
+ *
+ * @return
+ * @throws ParseException
+ */
+ public String getNextToken() throws ParseException {
+ try {
+ int tokenType = st.nextToken();
+ if (tokenType == StreamTokenizer.TT_EOF) {
+ return EOF;
+ } else if (tokenType == StreamTokenizer.TT_WORD
+ || tokenType == SINGLE_QUOTE
+ || tokenType == DOUBLE_QUOTE) {
+ return st.sval;
+ } else if (tokenType == StreamTokenizer.TT_NUMBER) {
+ return String.valueOf(st.nval);
+ } else {
+ return new String(new char[] {(char) tokenType});
+ }
+ } catch (IOException e) {
+ fail("IOException while attempting to read input stream", e);
+ return null;
+ }
+ }
+
+ public void fail(String message) throws ParseException {
+ throw new ParseException(message, st.lineno(), -1, systemId);
+ }
+
+ public void fail(String message, Throwable e) throws ParseException {
+ throw new ParseException(message, e, st.lineno(), -1, systemId);
+ }
+
+ public void fail(Throwable e) throws ParseException {
+ throw new ParseException(e, st.lineno(), -1, systemId);
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/Lexer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/Lexer.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/ParseException.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/ParseException.java?rev=644745&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/ParseException.java (added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/ParseException.java Fri Apr 4 08:55:26 2008
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+package org.apache.jackrabbit.spi.commons.nodetype.compact;
+
+/**
+ * ParseException
+ */
+public class ParseException extends Exception {
+
+ /**
+ * the line number where the error occurred
+ */
+ private final int lineNumber;
+
+ /**
+ * the column number where the error occurred
+ */
+ private final int colNumber;
+
+ /**
+ * the systemid of the source that produced the error
+ */
+ private final String systemId;
+
+
+ /**
+ * Constructs a new instance of this class with <code>null</code> as its
+ * detail message.
+ */
+ public ParseException(int lineNumber, int colNumber, String systemId) {
+ super();
+ this.lineNumber = lineNumber;
+ this.colNumber = colNumber;
+ this.systemId = systemId;
+ }
+
+ /**
+ * Constructs a new instance of this class with the specified detail
+ * message.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public ParseException(String message, int lineNumber, int colNumber, String systemId) {
+ super(message);
+ this.lineNumber = lineNumber;
+ this.colNumber = colNumber;
+ this.systemId = systemId;
+ }
+
+ /**
+ * Constructs a new instance of this class with the specified detail
+ * message and root cause.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ * @param rootCause root failure cause
+ */
+ public ParseException(String message, Throwable rootCause, int lineNumber, int colNumber, String systemId) {
+ super(message, rootCause);
+ this.lineNumber = lineNumber;
+ this.colNumber = colNumber;
+ this.systemId = systemId;
+ }
+
+ /**
+ * Constructs a new instance of this class with the specified root cause.
+ *
+ * @param rootCause root failure cause
+ */
+ public ParseException(Throwable rootCause, int lineNumber, int colNumber, String systemId) {
+ super(rootCause);
+ this.lineNumber = lineNumber;
+ this.colNumber = colNumber;
+ this.systemId = systemId;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getMessage() {
+ StringBuffer b = new StringBuffer(super.getMessage());
+ String delim = " (";
+ if (systemId != null && !systemId.equals("")) {
+ b.append(delim);
+ b.append(systemId);
+ delim = ", ";
+ }
+ if (lineNumber >= 0) {
+ b.append(delim);
+ b.append("line ");
+ b.append(lineNumber);
+ delim = ", ";
+ }
+ if (colNumber >= 0) {
+ b.append(delim);
+ b.append("col ");
+ b.append(colNumber);
+ delim = ", ";
+ }
+ if (delim.equals(", ")) {
+ b.append(")");
+ }
+ return b.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return super.toString(); // + " (" + systemId + ", line " + lineNumber +", col " + colNumber +")";
+ }
+
+}
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/ParseException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/ParseException.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilder.java?rev=644745&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilder.java (added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilder.java Fri Apr 4 08:55:26 2008
@@ -0,0 +1,453 @@
+/*
+ * 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.
+ */
+package org.apache.jackrabbit.spi.commons.nodetype.compact;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.ValueFormatException;
+
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QItemDefinition;
+import org.apache.jackrabbit.spi.QNodeDefinition;
+import org.apache.jackrabbit.spi.QNodeTypeDefinition;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
+import org.apache.jackrabbit.spi.QValue;
+import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
+import org.apache.jackrabbit.spi.commons.nodetype.InvalidConstraintException;
+
+/**
+ * A builder for {@link QNodeTypeDefinition}s
+ */
+public abstract class QNodeTypeDefinitionsBuilder {
+
+ /**
+ * @return a new instance of a builder for a {@link QNodeTypeDefinition}
+ */
+ public abstract QNodeTypeDefinitionBuilder newQNodeTypeDefinition();
+
+ /**
+ * Returns a <code>Name</code> with the given namespace URI and
+ * local part and validates the given parameters.
+ *
+ * @param namespaceURI namespace uri
+ * @param localName local part
+ * @throws IllegalArgumentException if <code>namespaceURI</code> or
+ * <code>localName</code> is invalid.
+ */
+ public abstract Name createName(String namespaceURI, String localName) throws IllegalArgumentException;
+
+ /**
+ * A builder for a {@link QNodeTypeDefinition}
+ */
+ public abstract class QNodeTypeDefinitionBuilder {
+ private Name name;
+ private Name[] supertypes;
+ private boolean isMixin;
+ private boolean isOrderable;
+ private Name primaryItemName;
+ private QPropertyDefinition[] propertyDefinitions;
+ private QNodeDefinition[] childNodeDefinitions;
+
+ /**
+ * Set the name of the node type definition being built
+ * @param name
+ */
+ public void setName(Name name) {
+ this.name = name;
+ }
+
+ /**
+ * @return the name of the node type definition being built or <code>null</code> if not set.
+ */
+ public Name getName() {
+ return name;
+ }
+
+ /**
+ * Specifies the supertypes of the node type definition being built
+ * @param supertypes
+ */
+ public void setSupertypes(Name[] supertypes) {
+ this.supertypes = supertypes;
+ }
+
+ /**
+ * Returns an array containing the names of the supertypes of the node type definition being
+ * built.
+ *
+ * @return an array of supertype names
+ */
+ public Name[] getSuperTypes() {
+ return supertypes;
+ }
+
+ /**
+ * @param isMixin true if building a mixin node type definition; false otherwise.
+ */
+ public void setMixin(boolean isMixin) {
+ this.isMixin = isMixin;
+ }
+
+ /**
+ * @return true if building a mixin node type definition; false otherwise.
+ */
+ public boolean getMixin() {
+ return isMixin;
+ }
+
+ /**
+ * @param isOrderable true if building a node type having orderable child nodes; false
+ * otherwise.
+ */
+ public void setOrderableChildNodes(boolean isOrderable) {
+ this.isOrderable = isOrderable;
+ }
+
+ /**
+ * @return true if building a node type having orderable child nodes; false otherwise.
+ */
+ public boolean getOrderableChildNodes() {
+ return isOrderable;
+ }
+
+ /**
+ * @param primaryItemName the name of the primary item or <code>null</code> if not set.
+ */
+ public void setPrimaryItemName(Name primaryItemName) {
+ this.primaryItemName = primaryItemName;
+ }
+
+ /**
+ * @return the name of the primary item or <code>null</code> if not set.
+ */
+ public Name getPrimaryItemName() {
+ return primaryItemName;
+ }
+
+ /**
+ * @param propDefs an array containing the property definitions of the node type definition
+ * being built.
+ */
+ public void setPropertyDefs(QPropertyDefinition[] propDefs) {
+ propertyDefinitions = propDefs;
+ }
+
+ /**
+ * @return an array containing the property definitions of the node type definition being
+ * built or <code>null</code> if not set.
+ */
+ public QPropertyDefinition[] getPropertyDefs() {
+ return propertyDefinitions;
+ }
+
+ /**
+ * @param childDefs an array containing the child node definitions of the node type
+ * definition being.
+ */
+ public void setChildNodeDefs(QNodeDefinition[] childDefs) {
+ childNodeDefinitions = childDefs;
+ }
+
+ /**
+ * @return an array containing the child node definitions of the node type definition being
+ * built or <code>null</code> if not set.
+ */
+ public QNodeDefinition[] getChildNodeDefs() {
+ return childNodeDefinitions;
+ }
+
+ /**
+ * @return a new instance of a builder for a {@link QNodeDefinition}.
+ */
+ public abstract QPropertyDefinitionBuilder newQPropertyDefinition();
+
+ /**
+ * @return a new instance of a builder for a {@link QNodeDefinition}.
+ */
+ public abstract QNodeDefinitionBuilder newQNodeDefinitionBuilder();
+
+ /**
+ * Creates a new {@link QNodeTypeDefinition} instance based on the state of this builder.
+ *
+ * @return a new {@link QNodeTypeDefinition} instance.
+ * @throws IllegalStateException if the instance has not the necessary information to build
+ * the QNodeTypeDefinition instance.
+ */
+ public abstract QNodeTypeDefinition build() throws IllegalStateException;
+ }
+
+ /**
+ * A builder for a {@link QItemDefinition}
+ */
+ abstract class QItemDefinitionBuilder {
+ private Name name;
+ private Name declaringType;
+ private boolean isAutocreated;
+ private int onParentVersion;
+ private boolean isProtected;
+ private boolean isMandatory;
+
+ /**
+ * @param name the name of the child item definition being build
+ */
+ public void setName(Name name) {
+ this.name = name;
+ }
+
+ /**
+ * @return the name of the child item definition being build.
+ */
+ public Name getName() {
+ return name;
+ }
+
+ /**
+ * @param type the name of the declaring node type.
+ */
+ public void setDeclaringNodeType(Name type) {
+ declaringType = type;
+ }
+
+ /**
+ * @return the name of the declaring node type.
+ */
+ public Name getDeclaringNodeType() {
+ return declaringType;
+ }
+
+ /**
+ * @param autocreate true if building a 'autocreate' child item definition, false otherwise.
+ */
+ public void setAutoCreated(boolean autocreate) {
+ isAutocreated = autocreate;
+ }
+
+ /**
+ * @return true if building a 'autocreate' child item definition, false otherwise.
+ */
+ public boolean getAutoCreated() {
+ return isAutocreated;
+ }
+
+ /**
+ * @param onParent the 'onParentVersion' attribute of the child item definition being built
+ */
+ public void setOnParentVersion(int onParent) {
+ onParentVersion = onParent;
+ }
+
+ /**
+ * @return the 'onParentVersion' attribute of the child item definition being built
+ */
+ public int getOnParentVersion() {
+ return onParentVersion;
+ }
+
+ /**
+ * @param isProtected true if building a 'protected' child item definition, false otherwise.
+ */
+ public void setProtected(boolean isProtected) {
+ this.isProtected = isProtected;
+ }
+
+ /**
+ * @return true if building a 'protected' child item definition, false otherwise.
+ */
+ public boolean getProtected() {
+ return isProtected;
+ }
+
+ /**
+ * @param isMandatory true if building a 'mandatory' child item definition, false otherwise.
+ */
+ public void setMandatory(boolean isMandatory) {
+ this.isMandatory = isMandatory;
+ }
+
+ /**
+ * @return true if building a 'mandatory' child item definition, false otherwise.
+ */
+ public boolean getMandatory() {
+ return isMandatory;
+ }
+ }
+
+ /**
+ * A builder for a {@link QNodeDefinition}
+ */
+ public abstract class QPropertyDefinitionBuilder extends QItemDefinitionBuilder {
+ private int requiredType;
+ private String[] valueConstraints;
+ private QValue[] defaultValues;
+ private boolean isMultiple;
+
+ /**
+ * @param type the required type of the property definition being built.
+ */
+ public void setRequiredType(int type) {
+ requiredType = type;
+ }
+
+ /**
+ * @return the required type of the property definition being built.
+ */
+ public int getRequiredType() {
+ return requiredType;
+ }
+
+ /**
+ * @param constraints array of value constraints of the property definition being built.
+ */
+ public void setValueConstraints(String[] constraints) {
+ valueConstraints = constraints;
+ }
+
+ /**
+ * @return array of value constraints of the property definition being built.
+ */
+ public String[] getValueConstraints() {
+ return valueConstraints;
+ }
+
+ /**
+ * @param values array of default values of the property definition being built.
+ */
+ public void setDefaultValues(QValue[] values) {
+ defaultValues = values;
+ }
+
+ /**
+ * @return array of default values of the property definition being built or
+ * <code>null</code> if no default values are defined.
+ */
+ public QValue[] getDefaultValues() {
+ return defaultValues;
+ }
+
+ /**
+ * @param isMultiple true if building a 'multiple' property definition.
+ */
+ public void setMultiple(boolean isMultiple) {
+ this.isMultiple = isMultiple;
+ }
+
+ /**
+ * @return true if building a 'multiple' property definition.
+ */
+ public boolean getMultiple() {
+ return isMultiple;
+ }
+
+ /**
+ * Validate the given <code>constraint</code> and resolve any prefixes.
+ *
+ * @param constraint
+ * @param resolver
+ * @return A syntactically valid value constrained which refers to fully qualified names and
+ * paths only.
+ * @throws InvalidConstraintException if <code>constraint</code> cannot be converted to a
+ * valid value constrained.
+ */
+ public abstract String createValueConstraint(String constraint, NamePathResolver resolver)
+ throws InvalidConstraintException;
+
+ /**
+ * Create a new <code>QValue</code> for <code>value</code> of the type this instance
+ * represents using the given <code>resolver</code>.
+ *
+ * @param value
+ * @param resolver
+ * @return a new <code>QValue</code>.
+ * @throws ValueFormatException If the given <code>value</code> cannot be converted to the
+ * specified <code>type</code>.
+ * @throws RepositoryException If another error occurs.
+ */
+ public abstract QValue createValue(String value, NamePathResolver resolver)
+ throws ValueFormatException, RepositoryException;
+
+ /**
+ * Creates a new {@link QPropertyDefinition} instance based on the state of this builder.
+ *
+ * @return a new {@link QPropertyDefinition} instance.
+ * @throws IllegalStateException if the instance has not the necessary information to build
+ * the QPropertyDefinition instance.
+ */
+ public abstract QPropertyDefinition build() throws IllegalStateException;
+ }
+
+ /**
+ * A builder for a {@link QNodeDefinition}
+ */
+ public abstract class QNodeDefinitionBuilder extends QItemDefinitionBuilder {
+ private Name defaultPrimaryType;
+ private Name[] requiredPrimaryTypes;
+ private boolean allowsSameNameSiblings;
+
+ /**
+ * @param name the name of the default primary type of the node definition being built.
+ */
+ public void setDefaultPrimaryType(Name name) {
+ defaultPrimaryType = name;
+ }
+
+ /**
+ * @return the name of the default primary type of the node definition being built.
+ */
+ public Name getDefaultPrimaryType() {
+ return defaultPrimaryType;
+ }
+
+ /**
+ * @param names array of names of the required primary types of the node definition being
+ * built.
+ */
+ public void setRequiredPrimaryTypes(Name[] names) {
+ requiredPrimaryTypes = names;
+ }
+
+ /**
+ * @return array of names of the required primary types of the node definition being built.
+ */
+ public Name[] getRequiredPrimaryTypes() {
+ return requiredPrimaryTypes;
+ }
+
+ /**
+ * @param allowSns true if building a node definition with same name siblings, false
+ * otherwise.
+ */
+ public void setAllowsSameNameSiblings(boolean allowSns) {
+ allowsSameNameSiblings = allowSns;
+ }
+
+ /**
+ * @return true if building a node definition with same name siblings, false otherwise.
+ */
+ public boolean getAllowsSameNameSiblings() {
+ return allowsSameNameSiblings;
+ }
+
+ /**
+ * Creates a new {@link QNodeDefinition} instance based on the state of this builder.
+ *
+ * @return a new {@link QNodeDefinition} instance.
+ * @throws IllegalStateException if the instance has not the necessary information to build
+ * the QNodeDefinition instance.
+ */
+ public abstract QNodeDefinition build() throws IllegalStateException;
+ }
+
+}
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilder.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilderImpl.java?rev=644745&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilderImpl.java (added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilderImpl.java Fri Apr 4 08:55:26 2008
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+package org.apache.jackrabbit.spi.commons.nodetype.compact;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.ValueFormatException;
+
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.NameFactory;
+import org.apache.jackrabbit.spi.QNodeDefinition;
+import org.apache.jackrabbit.spi.QNodeTypeDefinition;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
+import org.apache.jackrabbit.spi.QValue;
+import org.apache.jackrabbit.spi.commons.QNodeDefinitionImpl;
+import org.apache.jackrabbit.spi.commons.QNodeTypeDefinitionImpl;
+import org.apache.jackrabbit.spi.commons.QPropertyDefinitionImpl;
+import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
+import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
+import org.apache.jackrabbit.spi.commons.nodetype.InvalidConstraintException;
+import org.apache.jackrabbit.spi.commons.nodetype.ValueConstraint;
+import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl;
+import org.apache.jackrabbit.spi.commons.value.ValueFormat;
+
+/**
+ * Default implementations of a {@link QNodeTypeDefinitionsBuilder}. This implementations uses
+ * {@link QNodeTypeDefinitionBuilderImpl} for building node type definitions,
+ * {@link QPropertyDefinitionBuilderImpl} for building property definitions, and
+ * {@link QNodeDefinitionBuilderImpl} for building node definitions. It further uses
+ * {@link NameFactoryImpl} for creating <code>Name</code>s and {@link QValueFactoryImpl} for
+ * creating <code>QValue</code>s.
+ */
+public class QNodeTypeDefinitionsBuilderImpl extends QNodeTypeDefinitionsBuilder {
+
+ private static final NameFactory NAME_FACTORY = NameFactoryImpl.getInstance();
+
+ public QNodeTypeDefinitionBuilder newQNodeTypeDefinition() {
+ return new QNodeTypeDefinitionBuilderImpl();
+ }
+
+ public Name createName(String namespaceURI, String localName) {
+ return NAME_FACTORY.create(namespaceURI, localName);
+ }
+
+ /**
+ * Default implementation of a {@link QNodeTypeDefinitionBuilder}.
+ */
+ public class QNodeTypeDefinitionBuilderImpl extends QNodeTypeDefinitionBuilder {
+
+ public QNodeDefinitionBuilder newQNodeDefinitionBuilder() {
+ return new QNodeDefinitionBuilderImpl();
+ }
+
+ public QPropertyDefinitionBuilder newQPropertyDefinition() {
+ return new QPropertyDefinitionBuilderImpl();
+ }
+
+ public QNodeTypeDefinition build() {
+ return new QNodeTypeDefinitionImpl(
+ this.getName(),
+ this.getSuperTypes(),
+ this.getMixin(),
+ this.getOrderableChildNodes(),
+ this.getPrimaryItemName(),
+ this.getPropertyDefs(),
+ this.getChildNodeDefs());
+ }
+
+ }
+
+ /**
+ * Default implementation of a {@link QPropertyDefinitionBuilder}.
+ */
+ public class QPropertyDefinitionBuilderImpl extends QPropertyDefinitionBuilder {
+
+ public QValue createValue(String value, NamePathResolver resolver)
+ throws ValueFormatException, RepositoryException {
+
+ return ValueFormat.getQValue(value, getRequiredType(), resolver, QValueFactoryImpl
+ .getInstance());
+ }
+
+ public String createValueConstraint(String constraint, NamePathResolver resolver)
+ throws InvalidConstraintException {
+
+ return ValueConstraint.create(getRequiredType(), constraint, resolver).getQualifiedDefinition();
+ }
+
+ public QPropertyDefinition build() {
+ return new QPropertyDefinitionImpl(
+ this.getName(),
+ this.getDeclaringNodeType(),
+ this.getAutoCreated(),
+ this.getMandatory(),
+ this.getOnParentVersion(),
+ this.getProtected(),
+ this.getDefaultValues(),
+ this.getMultiple(),
+ this.getRequiredType(),
+ this.getValueConstraints());
+ }
+
+ }
+
+ /**
+ * Default implementation of a {@link QNodeDefinitionBuilder}.
+ */
+ public class QNodeDefinitionBuilderImpl extends QNodeDefinitionBuilder {
+
+ public QNodeDefinition build() {
+ return new QNodeDefinitionImpl(
+ this.getName(),
+ this.getDeclaringNodeType(),
+ this.getAutoCreated(),
+ this.getMandatory(),
+ this.getOnParentVersion(),
+ this.getProtected(),
+ this.getDefaultPrimaryType(),
+ this.getRequiredPrimaryTypes(),
+ this.getAllowsSameNameSiblings());
+ }
+
+ }
+
+}
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilderImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilderImpl.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/BooleanConstraintTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/BooleanConstraintTest.java?rev=644745&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/BooleanConstraintTest.java (added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/BooleanConstraintTest.java Fri Apr 4 08:55:26 2008
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+package org.apache.jackrabbit.spi.commons.nodetype;
+
+import org.apache.jackrabbit.spi.QValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.ConstraintViolationException;
+
+/**
+ * <code>BooleanConstraintTest</code>...
+ */
+public class BooleanConstraintTest extends ValueConstraintTest {
+
+ private static Logger log = LoggerFactory.getLogger(BooleanConstraintTest.class);
+
+ protected ValueConstraint createInvalidConstraint() throws RepositoryException {
+ return new BooleanConstraint("test");
+ }
+
+ protected ValueConstraint createValueConstraint(String definition) throws RepositoryException {
+ return new BooleanConstraint(definition);
+ }
+
+ protected int getType() {
+ return PropertyType.BOOLEAN;
+ }
+
+ protected String[] getInvalidQualifiedDefinitions() {
+ return new String[] {"test", "/abc/d", "12345"};
+ }
+
+ protected String[] getDefinitions() {
+ return new String[] { Boolean.TRUE.toString()};
+ }
+
+ protected String[] getQualifiedDefinitions() {
+ return getDefinitions();
+ }
+
+ protected QValue[] createNonMatchingValues() throws RepositoryException {
+ return new QValue[] {
+ valueFactory.create(Boolean.FALSE.toString(), PropertyType.BOOLEAN),
+ valueFactory.create(Boolean.TRUE.toString(), PropertyType.BOOLEAN)
+ };
+ }
+
+ protected QValue createOtherValueType() throws RepositoryException {
+ return valueFactory.create(1345);
+ }
+
+ public void testTrueConstraint() throws RepositoryException, ConstraintViolationException {
+ ValueConstraint vc = new BooleanConstraint(Boolean.TRUE.toString());
+ vc.check(valueFactory.create(Boolean.TRUE.toString(), PropertyType.BOOLEAN));
+ try {
+ vc.check(valueFactory.create(Boolean.FALSE.toString(), PropertyType.BOOLEAN));
+ fail();
+ } catch (ConstraintViolationException e) {
+ // ok
+ }
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/BooleanConstraintTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/BooleanConstraintTest.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/DateConstraintTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/DateConstraintTest.java?rev=644745&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/DateConstraintTest.java (added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/DateConstraintTest.java Fri Apr 4 08:55:26 2008
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+package org.apache.jackrabbit.spi.commons.nodetype;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.spi.QValue;
+import org.apache.jackrabbit.value.DateValue;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.PropertyType;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * <code>DateConstraintTest</code>...
+ */
+public class DateConstraintTest extends ValueConstraintTest {
+
+ private static Logger log = LoggerFactory.getLogger(DateConstraintTest.class);
+
+ protected int getType() {
+ return PropertyType.DATE;
+ }
+
+ protected String[] getInvalidQualifiedDefinitions() {
+ return new String[] {"abc", "-18", "1234567"};
+ }
+
+ protected String[] getDefinitions() throws RepositoryException {
+ Calendar c1 = Calendar.getInstance();
+ c1.setTimeInMillis(234567);
+
+ Calendar c2 = Calendar.getInstance();
+ c2.setTime(new Date());
+
+ StringBuffer b = new StringBuffer("(");
+ b.append(new DateValue(c1).getString());
+ b.append(",");
+ b.append(new DateValue(c2).getString());
+ b.append(")");
+
+ return new String[] {b.toString()};
+ }
+
+ protected String[] getQualifiedDefinitions() throws RepositoryException {
+ return getDefinitions();
+ }
+
+ protected QValue[] createNonMatchingValues() throws RepositoryException {
+ Calendar cd = Calendar.getInstance();
+ cd.setTimeInMillis(997);
+ return new QValue[] {valueFactory.create(cd)};
+ }
+
+ protected QValue createOtherValueType() throws RepositoryException {
+ return valueFactory.create(resolver.getQName("abc"));
+ }
+
+ // TODO: add more
+}
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/DateConstraintTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/DateConstraintTest.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url