stefan      2004/07/09 09:48:45

  Modified:    proposals/jcrri/src/org/apache/slide/jcr/core NodeImpl.java
                        Test.java PropertyImpl.java
  Log:
  jcrri
  
  Revision  Changes    Path
  1.19      +228 -17   
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NodeImpl.java
  
  Index: NodeImpl.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NodeImpl.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- NodeImpl.java     8 Jul 2004 17:34:34 -0000       1.18
  +++ NodeImpl.java     9 Jul 2004 16:48:44 -0000       1.19
  @@ -53,7 +53,7 @@
   
       private static Logger log = Logger.getLogger(NodeImpl.class);
   
  -    protected NodeTypeImpl nodeType;
  +    protected final NodeTypeImpl nodeType;
   
       protected NodeDef definition;
   
  @@ -105,6 +105,8 @@
   
        // @todo need a more flexible generic way (callback?) of applying system 
generated values
   
  +     NodeState thisState = (NodeState) state;
  +
        // compute/apply system generated values
        NodeTypeImpl nt = (NodeTypeImpl) def.getDeclaringNodeType();
        if (nt.getQName().equals(NodeTypeRegistry.MIX_REFERENCEABLE)) {
  @@ -126,7 +128,13 @@
                genValues = new 
InternalValue[]{InternalValue.create(nodeType.getQName())};
            } else if (name.equals(PROPNAME_MIXINTYPES)) {
                // jcr:mixinTypes property
  -             // @todo determine value of mixin:nodeTypes property
  +             Set mixins = thisState.getMixinTypeNames();
  +             ArrayList values = new ArrayList(mixins.size());
  +             Iterator iter = mixins.iterator();
  +             while (iter.hasNext()) {
  +                 values.add(InternalValue.create((QName) iter.next()));
  +             }
  +             genValues = (InternalValue[]) values.toArray(new 
InternalValue[values.size()]);
            }
        }
   
  @@ -135,12 +143,12 @@
   
       protected PropertyImpl getOrCreateProperty(String name, int type)
            throws RepositoryException {
  -     QName qName = QName.fromJCRName(name, ticket.getNamespaceResolver());
        try {
            return (PropertyImpl) getProperty(name);
        } catch (PathNotFoundException pnfe) {
            // does not exist yet:
  -         // find definition for the specified property and  create property
  +         // find definition for the specified property and create property
  +         QName qName = QName.fromJCRName(name, ticket.getNamespaceResolver());
            PropertyDefImpl def = nodeType.getApplicablePropertyDef(qName, type);
            return createChildProperty(qName, type, def);
        }
  @@ -219,14 +227,14 @@
        // add new child node entry
        thisState.addChildNodeEntry(name, nodeState.getUUID());
   
  -     // add 'auto-create' properties defined in nodetype
  +     // add 'auto-create' properties defined in node type
        PropertyDef[] pda = nodeType.getAutoCreatePropertyDefs();
        for (int i = 0; i < pda.length; i++) {
            PropertyDefImpl pd = (PropertyDefImpl) pda[i];
            node.createChildProperty(pd.getQName(), pd.getRequiredType(), pd);
        }
   
  -     // recursively add 'auto-create' child nodes defined in nodetype
  +     // recursively add 'auto-create' child nodes defined in node type
        NodeDef[] nda = nodeType.getAutoCreateNodeDefs();
        for (int i = 0; i < nda.length; i++) {
            NodeDefImpl nd = (NodeDefImpl) nda[i];
  @@ -405,6 +413,28 @@
        return parentNode.createChildNode(nodeName, def, nodeType);
       }
   
  +    private void setMixinTypesProperty(Set mixinNames) throws RepositoryException {
  +     NodeState thisState = (NodeState) state;
  +     // get or create jcr:mixinTypes property
  +     PropertyImpl prop = null;
  +     if (thisState.hasPropertyEntry(PROPNAME_MIXINTYPES)) {
  +         prop = (PropertyImpl) itemMgr.getItem(new PropertyId(thisState.getUUID(), 
PROPNAME_MIXINTYPES));
  +     } else {
  +         // find definition for the jcr:mixinTypes property and create property
  +         PropertyDefImpl def = 
nodeType.getApplicablePropertyDef(PROPNAME_MIXINTYPES, PropertyType.STRING);
  +         prop = createChildProperty(PROPNAME_MIXINTYPES, PropertyType.STRING, def);
  +     }
  +     // call internalSetValue for setting the jcr:mixinTypes property
  +     // to avoid checking of the 'protected' flag
  +     InternalValue[] vals = new InternalValue[mixinNames.size()];
  +     Iterator iter = mixinNames.iterator();
  +     int cnt = 0;
  +     while (iter.hasNext()) {
  +         vals[cnt++] = InternalValue.create((QName) iter.next());
  +     }
  +     prop.internalSetValue(vals, PropertyType.STRING);
  +    }
  +
       protected void makePersistent() throws RepositoryException {
        if (!isTransient()) {
            log.debug(safeGetJCRPath() + " (" + id + "): there's no transient state to 
persist");
  @@ -423,6 +453,8 @@
            // parent uuid's
            persistentState.setParentUUID(transientState.getParentUUID());
            persistentState.setParentUUIDs(transientState.getParentUUIDs());
  +         // mixin types
  +         persistentState.setMixinTypeNames(transientState.getMixinTypeNames());
            // child node entries
            persistentState.setChildNodeEntries(transientState.getChildNodeEntries());
            // property entries
  @@ -548,6 +580,7 @@
        * Same as <code>[EMAIL PROTECTED] Node#setProperty(String, String)}</code> 
except that
        * this method takes a <code>QName</code> instead of a <code>String</code>
        * value.
  +     *
        * @param name
        * @param value
        * @return
  @@ -567,6 +600,7 @@
        * Same as <code>[EMAIL PROTECTED] Node#setProperty(String, String[])}</code> 
except that
        * this method takes an array of  <code>QName</code> instead of a
        * <code>String</code> values.
  +     *
        * @param name
        * @param values
        * @return
  @@ -1186,11 +1220,30 @@
        // check state of this instance
        checkItemState();
   
  +     // check primary type
        if (nodeTypeName.equals(nodeType.getName())) {
            return true;
        }
        QName ntName = QName.fromJCRName(nodeTypeName, ticket.getNamespaceResolver());
  -     return nodeType.isDerivedFrom(ntName);
  +     if (nodeType.isDerivedFrom(ntName)) {
  +         return true;
  +     }
  +
  +     // check mixin types
  +     Set mixinNames = ((NodeState) state).getMixinTypeNames();
  +     if (mixinNames.isEmpty()) {
  +         return false;
  +     }
  +     NodeTypeManagerImpl ntMgr = (NodeTypeManagerImpl) 
ticket.getWorkspace().getNodeTypeManager();
  +     NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
  +     try {
  +         EffectiveNodeType ent = ntReg.buildEffectiveNodeType((QName[]) 
mixinNames.toArray(new QName[mixinNames.size()]));
  +         return ent.includesNodeType(ntName);
  +     } catch (NodeTypeConflictException ntce) {
  +         String msg = "internal error: invalid mixin node type(s)";
  +         log.error(msg, ntce);
  +         throw new RepositoryException(msg, ntce);
  +     }
       }
   
       /**
  @@ -1204,8 +1257,18 @@
        * @see Node#getMixinNodeTypes()
        */
       public NodeType[] getMixinNodeTypes() throws RepositoryException {
  -     // @todo implement mixin node types support
  -     throw new RepositoryException("not yet implemented");
  +     Set mixinNames = ((NodeState) state).getMixinTypeNames();
  +     if (mixinNames.isEmpty()) {
  +         return new NodeType[0];
  +     }
  +     NodeTypeManagerImpl ntMgr = (NodeTypeManagerImpl) 
ticket.getWorkspace().getNodeTypeManager();
  +     NodeType[] nta = new NodeType[mixinNames.size()];
  +     Iterator iter = mixinNames.iterator();
  +     int i = 0;
  +     while (iter.hasNext()) {
  +         nta[i++] = ntMgr.getNodeType((QName) iter.next());
  +     }
  +     return nta;
       }
   
       /**
  @@ -1214,8 +1277,58 @@
       public void addMixin(String mixinName)
            throws NoSuchNodeTypeException, ConstraintViolationException,
            RepositoryException {
  -     // @todo implement mixin node types support
  -     throw new RepositoryException("not yet implemented");
  +     // check state of this instance
  +     checkItemState();
  +
  +     QName ntName = QName.fromJCRName(mixinName, ticket.getNamespaceResolver());
  +
  +     NodeTypeManagerImpl ntMgr = (NodeTypeManagerImpl) 
ticket.getWorkspace().getNodeTypeManager();
  +     NodeTypeImpl mixin = ntMgr.getNodeType(ntName);
  +     if (!mixin.isMixin()) {
  +         throw new RepositoryException(mixinName + ": not a mixin node type");
  +     }
  +     if (nodeType.isDerivedFrom(ntName)) {
  +         throw new RepositoryException(mixinName + ": already contained in primary 
node type");
  +     }
  +
  +     // build effective node type of mixins & primary type in order to detect 
conflicts
  +     NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
  +     // existing mixin's
  +     HashSet set = new HashSet(((NodeState) state).getMixinTypeNames());
  +     // new mixin
  +     set.add(ntName);
  +     // primary type
  +     set.add(nodeType.getQName());
  +     try {
  +         // try to build effective node type (will throw in case of conflicts)
  +         ntReg.buildEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
  +     } catch (NodeTypeConflictException ntce) {
  +         throw new ConstraintViolationException(ntce.getMessage());
  +     }
  +
  +     // modify the state of this node
  +     NodeState thisState = (NodeState) getOrCreateTransientItemState();
  +     // add mixin name
  +     Set mixins = new HashSet(thisState.getMixinTypeNames());
  +     mixins.add(ntName);
  +     thisState.setMixinTypeNames(mixins);
  +
  +     // set jcr:mixinTypes property
  +     setMixinTypesProperty(mixins);
  +
  +     // add 'auto-create' properties defined in mixin type
  +     PropertyDef[] pda = mixin.getAutoCreatePropertyDefs();
  +     for (int i = 0; i < pda.length; i++) {
  +         PropertyDefImpl pd = (PropertyDefImpl) pda[i];
  +         createChildProperty(pd.getQName(), pd.getRequiredType(), pd);
  +     }
  +
  +     // recursively add 'auto-create' child nodes defined in mixin type
  +     NodeDef[] nda = mixin.getAutoCreateNodeDefs();
  +     for (int i = 0; i < nda.length; i++) {
  +         NodeDefImpl nd = (NodeDefImpl) nda[i];
  +         createChildNode(nd.getQName(), nd, (NodeTypeImpl) 
nd.getDefaultPrimaryType());
  +     }
       }
   
       /**
  @@ -1224,16 +1337,114 @@
       public void removeMixin(String mixinName)
            throws NoSuchNodeTypeException, ConstraintViolationException,
            RepositoryException {
  -     // @todo implement mixin node types support
  -     throw new RepositoryException("not yet implemented");
  +     // check state of this instance
  +     checkItemState();
  +
  +     QName ntName = QName.fromJCRName(mixinName, ticket.getNamespaceResolver());
  +
  +     // check if mixin is assigned
  +     if (!((NodeState) state).getMixinTypeNames().contains(ntName)) {
  +         throw new NoSuchNodeTypeException(mixinName);
  +     }
  +
  +     if (NodeTypeRegistry.MIX_REFERENCEABLE.equals(ntName)) {
  +         /**
  +          * mix:referenceable needs special handling because it has
  +          * special semantics:
  +          * it can only be removed if there no more references to this node
  +          *
  +          * todo check if there are REFERENCE properties pointing to this node
  +          */
  +         throw new ConstraintViolationException(mixinName + " can not be removed");
  +     }
  +
  +     // modify the state of this node
  +     NodeState thisState = (NodeState) getOrCreateTransientItemState();
  +     // remove mixin name
  +     Set mixins = new HashSet(thisState.getMixinTypeNames());
  +     mixins.remove(ntName);
  +     thisState.setMixinTypeNames(mixins);
  +
  +     // set jcr:mixinTypes property
  +     setMixinTypesProperty(mixins);
  +
  +     NodeTypeManagerImpl ntMgr = (NodeTypeManagerImpl) 
ticket.getWorkspace().getNodeTypeManager();
  +     NodeTypeImpl mixin = ntMgr.getNodeType(ntName);
  +
  +     // shortcut
  +     if (mixin.getDeclaredChildNodeDefs().length == 0 &&
  +             mixin.getDeclaredPropertyDefs().length == 0) {
  +         // the node type has neither property nor child node definitions,
  +         // i.e. we're done
  +         return;
  +     }
  +
  +     // walk through properties and child nodes and remove those that have been
  +     // defined by the specified mixin type
  +
  +     // use temp array to avoid ConcurrentModificationException
  +     ArrayList tmp = new ArrayList(thisState.getPropertyEntries());
  +     Iterator iter = tmp.iterator();
  +     while (iter.hasNext()) {
  +         NodeState.PropertyEntry entry = (NodeState.PropertyEntry) iter.next();
  +         PropertyImpl prop = (PropertyImpl) itemMgr.getItem(new 
PropertyId(thisState.getUUID(), entry.getName()));
  +         // check if property has been defined by mixin type
  +         NodeTypeImpl declaringNT = (NodeTypeImpl) 
prop.getDefinition().getDeclaringNodeType();
  +         if (mixin.getQName().equals(declaringNT.getQName())
  +                 || mixin.isDerivedFrom(declaringNT.getQName())) {
  +             // remove property
  +             removeChildProperty(entry.getName());
  +         }
  +     }
  +     // use temp array to avoid ConcurrentModificationException
  +     tmp = new ArrayList(thisState.getChildNodeEntries());
  +     iter = tmp.iterator();
  +     while (iter.hasNext()) {
  +         NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) iter.next();
  +         NodeImpl node = (NodeImpl) itemMgr.getItem(new NodeId(entry.getUUID()));
  +         // check if node has been defined by mixin type
  +         NodeTypeImpl declaringNT = (NodeTypeImpl) 
node.getDefinition().getDeclaringNodeType();
  +         if (mixin.getQName().equals(declaringNT.getQName())
  +                 || mixin.isDerivedFrom(declaringNT.getQName())) {
  +             // remove node
  +             removeChildNode(entry.getName(), entry.getIndex());
  +         }
  +     }
       }
   
       /**
        * @see Node#canAddMixin(String)
        */
       public boolean canAddMixin(String mixinName) throws RepositoryException {
  -     // @todo implement mixin node types support
  -     throw new RepositoryException("not yet implemented");
  +     // check state of this instance
  +     checkItemState();
  +
  +     QName ntName = QName.fromJCRName(mixinName, ticket.getNamespaceResolver());
  +
  +     NodeTypeManagerImpl ntMgr = (NodeTypeManagerImpl) 
ticket.getWorkspace().getNodeTypeManager();
  +     NodeTypeImpl mixin = ntMgr.getNodeType(ntName);
  +     if (!mixin.isMixin()) {
  +         return false;
  +     }
  +     if (nodeType.isDerivedFrom(ntName)) {
  +         return false;
  +     }
  +
  +     // build effective node type of mixins & primary type in order to detect 
conflicts
  +     NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
  +     // existing mixin's
  +     HashSet set = new HashSet(((NodeState) state).getMixinTypeNames());
  +     // new mixin
  +     set.add(ntName);
  +     // primary type
  +     set.add(nodeType.getQName());
  +     try {
  +         ntReg.buildEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
  +     } catch (NodeTypeConflictException ntce) {
  +         return false;
  +     }
  +
  +     return true;
       }
   
       /**
  
  
  
  1.6       +36 -15    
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/Test.java
  
  Index: Test.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/Test.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Test.java 7 Jul 2004 16:05:45 -0000       1.5
  +++ Test.java 9 Jul 2004 16:48:44 -0000       1.6
  @@ -91,15 +91,34 @@
        System.out.println();
        dumpTree(root, System.out);
   
  +     if (root.canAddMixin("mix:versionable")) {
  +         root.addMixin("mix:versionable");
  +         if (root.canAddMixin("mix:accessControllable")) {
  +             root.addMixin("mix:accessControllable");
  +         }
  +         dumpTree(root, System.out);
  +         boolean accessControlable = root.isNodeType("mix:accessControllable");
  +         root.removeMixin("mix:versionable");
  +         dumpTree(root, System.out);
  +         root.save();
  +     }
  +
        //root.setProperty("blob", new FileInputStream(new File("d:/temp/jcrri.zip")));
   
        root.setProperty("bla", 1);
        root.setProperty("bla", 1.4);
        root.setProperty("bla", "blabla");
  -     root.addNode("blu", "nt:file");
  +     Node file = root.addNode("blu", "nt:file");
  +     file.addNode("jcr:content");
        root.addNode("blu", "nt:folder");
        root.addNode("blu");
   
  +     dumpTree(root, System.out);
  +     root.orderBefore("blu", null);
  +     dumpTree(root, System.out);
  +     root.orderBefore("blu[2]", "blu[1]");
  +     dumpTree(root, System.out);
  +
        System.out.println("before save()...");
        System.out.println();
        dumpTree(root, System.out);
  @@ -110,19 +129,21 @@
        System.out.println();
        dumpTree(root, System.out);
   
  -     Property blob = root.getProperty("blob");
  -     InputStream in = blob.getStream();
  -     // spool stream to temp file
  -     FileOutputStream out = new FileOutputStream(new File("d:/temp/scratch.zip"));
  -     try {
  -         byte[] buffer = new byte[8192];
  -         int read = 0;
  -         while ((read = in.read(buffer)) > 0) {
  -             out.write(buffer, 0, read);
  +     if (root.hasProperty("blob")) {
  +         Property blob = root.getProperty("blob");
  +         InputStream in = blob.getStream();
  +         // spool stream to temp file
  +         FileOutputStream out = new FileOutputStream(new 
File("d:/temp/scratch.zip"));
  +         try {
  +             byte[] buffer = new byte[8192];
  +             int read = 0;
  +             while ((read = in.read(buffer)) > 0) {
  +                 out.write(buffer, 0, read);
  +             }
  +         } finally {
  +             out.close();
  +             in.close();
            }
  -     } finally {
  -         out.close();
  -         in.close();
        }
   
        Node misc = root.addNode("misc", "nt:unstructured");
  @@ -153,7 +174,7 @@
   
        Node n = root.addNode("foo", "nt:folder");
        Node n2 = n.addNode("foofile", "nt:file");
  -     Node n3 = n2.getNode("jcr:content");
  +     Node n3 = n2.addNode("jcr:content");
        Property p1 = n3.setProperty("prop1", new LongValue(123));
        Property p2 = n3.setProperty("prop2", new StringValue("blabla"));
   
  
  
  
  1.15      +62 -12    
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/PropertyImpl.java
  
  Index: PropertyImpl.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/PropertyImpl.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- PropertyImpl.java 7 Jul 2004 16:05:25 -0000       1.14
  +++ PropertyImpl.java 9 Jul 2004 16:48:44 -0000       1.15
  @@ -140,16 +140,6 @@
        // check state of this instance
        checkItemState();
   
  -     // check protected flag
  -     if (definition.isProtected()) {
  -         throw new ConstraintViolationException("cannot set the value of a 
protected property " + safeGetJCRPath());
  -     }
  -
  -     // check multi-value flag
  -     if (!definition.isMultiple() && values != null && values.length > 1) {
  -         throw new ConstraintViolationException(safeGetJCRPath() + " is not 
multi-valued");
  -     }
  -
        // modify the state of this property
        PropertyState thisState = (PropertyState) getOrCreateTransientItemState();
   
  @@ -212,6 +202,16 @@
        // check state of this instance
        checkItemState();
   
  +     // check protected flag
  +     if (definition.isProtected()) {
  +         throw new ConstraintViolationException("cannot set the value of a 
protected property " + safeGetJCRPath());
  +     }
  +
  +     // check multi-value flag
  +     if (!definition.isMultiple() && names != null && names.length > 1) {
  +         throw new ConstraintViolationException(safeGetJCRPath() + " is not 
multi-valued");
  +     }
  +
        // check type according to definition of this property
        int reqType = definition.getRequiredType();
        if (reqType == PropertyType.UNDEFINED) {
  @@ -492,6 +492,11 @@
        // check state of this instance
        checkItemState();
   
  +     // check protected flag
  +     if (definition.isProtected()) {
  +         throw new ConstraintViolationException("cannot set the value of a 
protected property " + safeGetJCRPath());
  +     }
  +
        // check type according to definition of this property
        int reqType = definition.getRequiredType();
        if (reqType == PropertyType.UNDEFINED) {
  @@ -522,6 +527,11 @@
        // check state of this instance
        checkItemState();
   
  +     // check protected flag
  +     if (definition.isProtected()) {
  +         throw new ConstraintViolationException("cannot set the value of a 
protected property " + safeGetJCRPath());
  +     }
  +
        // check type according to definition of this property
        int reqType = definition.getRequiredType();
        if (reqType == PropertyType.UNDEFINED) {
  @@ -547,6 +557,11 @@
        // check state of this instance
        checkItemState();
   
  +     // check protected flag
  +     if (definition.isProtected()) {
  +         throw new ConstraintViolationException("cannot set the value of a 
protected property " + safeGetJCRPath());
  +     }
  +
        // check type according to definition of this property
        int reqType = definition.getRequiredType();
        if (reqType == PropertyType.UNDEFINED) {
  @@ -594,6 +609,16 @@
        // check state of this instance
        checkItemState();
   
  +     // check protected flag
  +     if (definition.isProtected()) {
  +         throw new ConstraintViolationException("cannot set the value of a 
protected property " + safeGetJCRPath());
  +     }
  +
  +     // check multi-value flag
  +     if (!definition.isMultiple() && strings != null && strings.length > 1) {
  +         throw new ConstraintViolationException(safeGetJCRPath() + " is not 
multi-valued");
  +     }
  +
        // check type according to definition of this property
        int reqType = definition.getRequiredType();
        if (reqType == PropertyType.UNDEFINED) {
  @@ -630,6 +655,11 @@
        // check state of this instance
        checkItemState();
   
  +     // check protected flag
  +     if (definition.isProtected()) {
  +         throw new ConstraintViolationException("cannot set the value of a 
protected property " + safeGetJCRPath());
  +     }
  +
        // check type according to definition of this property
        int reqType = definition.getRequiredType();
        if (reqType == PropertyType.UNDEFINED) {
  @@ -655,6 +685,11 @@
        // check state of this instance
        checkItemState();
   
  +     // check protected flag
  +     if (definition.isProtected()) {
  +         throw new ConstraintViolationException("cannot set the value of a 
protected property " + safeGetJCRPath());
  +     }
  +
        // @todo implement correct semantics (i.e. referential integrity) for 
REFERENCE values
   
        // check type according to definition of this property
  @@ -694,6 +729,11 @@
        // check state of this instance
        checkItemState();
   
  +     // check protected flag
  +     if (definition.isProtected()) {
  +         throw new ConstraintViolationException("cannot set the value of a 
protected property " + safeGetJCRPath());
  +     }
  +
        // check type according to definition of this property
        int reqType = definition.getRequiredType();
        if (reqType == PropertyType.UNDEFINED) {
  @@ -729,6 +769,16 @@
       public void setValue(Value[] values) throws ValueFormatException, 
RepositoryException {
        // check state of this instance
        checkItemState();
  +
  +     // check protected flag
  +     if (definition.isProtected()) {
  +         throw new ConstraintViolationException("cannot set the value of a 
protected property " + safeGetJCRPath());
  +     }
  +
  +     // check multi-value flag
  +     if (!definition.isMultiple() && values != null && values.length > 1) {
  +         throw new ConstraintViolationException(safeGetJCRPath() + " is not 
multi-valued");
  +     }
   
        int reqType = definition.getRequiredType();
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to