Return-Path: Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: (qmail 15098 invoked from network); 4 Apr 2008 15:56:22 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 4 Apr 2008 15:56:22 -0000 Received: (qmail 49526 invoked by uid 500); 4 Apr 2008 15:56:22 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 49448 invoked by uid 500); 4 Apr 2008 15:56:22 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 49430 invoked by uid 99); 4 Apr 2008 15:56:22 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 04 Apr 2008 08:56:22 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 04 Apr 2008 15:55:40 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 7DA891A983E; Fri, 4 Apr 2008 08:55:48 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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... Date: Fri, 04 Apr 2008 15:55:39 -0000 To: commits@jackrabbit.apache.org From: angela@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080404155552.7DA891A983E@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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. + *

+ * The EBNF grammar of the compact node type definition:
+ *

+ * 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:_]+
+ * 
+ */ +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 true if equals; false 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 true if equals; false 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 true if equals; false 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: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 true 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 null 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 Name with the given namespace URI and + * local part and validates the given parameters. + * + * @param namespaceURI namespace uri + * @param localName local part + * @throws IllegalArgumentException if namespaceURI or + * localName 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 null 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 null if not set. + */ + public void setPrimaryItemName(Name primaryItemName) { + this.primaryItemName = primaryItemName; + } + + /** + * @return the name of the primary item or null 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 null 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 null 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 + * null 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 constraint 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 constraint cannot be converted to a + * valid value constrained. + */ + public abstract String createValueConstraint(String constraint, NamePathResolver resolver) + throws InvalidConstraintException; + + /** + * Create a new QValue for value of the type this instance + * represents using the given resolver. + * + * @param value + * @param resolver + * @return a new QValue. + * @throws ValueFormatException If the given value cannot be converted to the + * specified type. + * @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 Names and {@link QValueFactoryImpl} for + * creating QValues. + */ +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; + +/** + * BooleanConstraintTest... + */ +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; + +/** + * DateConstraintTest... + */ +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