stefan      2004/07/16 09:38:08

  Modified:    proposals/jcrri/src/org/apache/slide/jcr/core
                        ItemLifeCycleListener.java ItemManager.java
                        NamespaceRegistryImpl.java NamespaceResolver.java
                        NodeId.java NodeImpl.java
                        NoPrefixDeclaredException.java
  Log:
  jcrri
  
  Revision  Changes    Path
  1.4       +3 -3      
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ItemLifeCycleListener.java
  
  Index: ItemLifeCycleListener.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ItemLifeCycleListener.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ItemLifeCycleListener.java        22 Jun 2004 18:03:07 -0000      1.3
  +++ ItemLifeCycleListener.java        16 Jul 2004 16:38:08 -0000      1.4
  @@ -31,7 +31,7 @@
    * @version $Revision$, $Date$
    * @see ItemImpl#addLifeCycleListener
    */
  -interface ItemLifeCycleListener {
  +public interface ItemLifeCycleListener {
   
       /**
        * Called when an <code>ItemImpl</code> instance has been created.
  
  
  
  1.8       +28 -21    
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ItemManager.java
  
  Index: ItemManager.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ItemManager.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ItemManager.java  7 Jul 2004 16:05:45 -0000       1.7
  +++ ItemManager.java  16 Jul 2004 16:38:08 -0000      1.8
  @@ -26,9 +26,11 @@
   import org.apache.commons.collections.ReferenceMap;
   import org.apache.log4j.Logger;
   import org.apache.slide.jcr.core.nodetype.NodeDefId;
  -import org.apache.slide.jcr.core.nodetype.NodeTypeImpl;
  +import org.apache.slide.jcr.core.nodetype.NodeTypeRegistry;
   import org.apache.slide.jcr.core.nodetype.PropDefId;
   import org.apache.slide.jcr.core.state.*;
  +import org.apache.slide.jcr.core.version.VersionHistoryImpl;
  +import org.apache.slide.jcr.core.version.VersionImpl;
   import org.apache.slide.jcr.util.IteratorHelper;
   
   import javax.jcr.*;
  @@ -195,7 +197,7 @@
       public synchronized ItemImpl getItem(ItemId id)
            throws ItemNotFoundException, AccessDeniedException, RepositoryException {
        // check privileges
  -     if (!((AccessManagerImpl) ticket.getAccessManager()).isGranted(id, 
Permission.READ_ITEM)) {
  +     if (!ticket.getAccessManager().isGranted(id, Permission.READ_ITEM)) {
            // clear cache
            if (isCached(id)) {
                evictItem(id);
  @@ -227,7 +229,7 @@
       synchronized NodeIterator getChildNodes(NodeId parentId)
            throws ItemNotFoundException, AccessDeniedException, RepositoryException {
        // check privileges
  -     if (!((AccessManagerImpl) ticket.getAccessManager()).isGranted(parentId, 
Permission.READ_ITEM)) {
  +     if (!ticket.getAccessManager().isGranted(parentId, Permission.READ_ITEM)) {
            // clear cache
            ItemImpl item = retrieveItem(parentId);
            if (item != null) {
  @@ -283,7 +285,7 @@
       synchronized PropertyIterator getChildProperties(NodeId parentId)
            throws PathNotFoundException, AccessDeniedException, RepositoryException {
        // check privileges
  -     if (!((AccessManagerImpl) ticket.getAccessManager()).isGranted(parentId, 
Permission.READ_ITEM)) {
  +     if (!ticket.getAccessManager().isGranted(parentId, Permission.READ_ITEM)) {
            ItemImpl item = retrieveItem(parentId);
            if (item != null) {
                evictItem(parentId);
  @@ -357,9 +359,16 @@
        // we want to be informed on life cycle changes of the new node object
        // in order to maintain item cache consistency
        ItemLifeCycleListener[] listeners = new ItemLifeCycleListener[]{this};
  -     // create node object
  -     NodeImpl node = new NodeImpl(this, ticket, id, state, def, listeners);
  -     return node;
  +
  +     // create node object; create specialized nodes for nodes of specific
  +     // primary types (i.e. nt:version & nt:versionHistory)
  +     if (state.getNodeTypeName().equals(NodeTypeRegistry.NT_VERSION_HISTORY)) {
  +         return new VersionHistoryImpl(this, ticket, id, state, def, listeners);
  +     } else if (state.getNodeTypeName().equals(NodeTypeRegistry.NT_VERSION)) {
  +         return new VersionImpl(this, ticket, id, state, def, listeners);
  +     } else {
  +         return new NodeImpl(this, ticket, id, state, def, listeners);
  +     }
       }
   
       NodeImpl createNodeInstance(NodeState state) throws RepositoryException {
  @@ -368,16 +377,15 @@
        // 1. get parent node
        NodeId parentId = new NodeId(state.getParentUUID());
        NodeImpl parent = (NodeImpl) getItem(parentId);
  -     // 2. get its node type
  -     NodeTypeImpl ntParent = (NodeTypeImpl) parent.getPrimaryNodeType();
  -     // 3. get definition for the specified child node
  +     // 2. get definition for the specified child node
        NodeDef def = null;
        NodeDefId defId = state.getDefinitionId();
        if (defId != null) {
            def = ticket.getNodeTypeManager().getNodeDef(defId);
        }
        if (def == null) {
  -         // fallback: find matching definition in parent node's node type
  +         // fallback: find matching definition in parent node's node type and mixin 
types
  +         // find the node's name in parent's child list
            NodeState parentState = (NodeState) parent.getItemState();
            List entries = parentState.getChildNodeEntries(state.getUUID());
            if (entries.isEmpty()) {
  @@ -386,10 +394,11 @@
                throw new RepositoryException(msg);
            }
            NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) entries.get(0);
  -         def = ntParent.getApplicableChildNodeDef(entry.getName(), 
state.getNodeTypeName());
  +         // find matching definiton
  +         def = parent.getApplicableChildNodeDef(entry.getName(), 
state.getNodeTypeName());
        }
   
  -     // create instance
  +     // 3. create instance
        return createNodeInstance(state, def);
       }
   
  @@ -410,20 +419,18 @@
        // 1. get parent node
        NodeId parentId = new NodeId(state.getParentUUID());
        NodeImpl parent = (NodeImpl) getItem(parentId);
  -     // 2. get its node type
  -     NodeTypeImpl ntParent = (NodeTypeImpl) parent.getPrimaryNodeType();
  -     // 3. get matching definition for the specified property
  +     // 2. get matching definition for the specified property
        PropertyDef def = null;
        PropDefId defId = state.getDefinitionId();
        if (defId != null) {
            def = ticket.getNodeTypeManager().getPropDef(defId);
        }
        if (def == null) {
  -         // fallback: find matching definition in parent node's node type
  -         def = ntParent.getApplicablePropertyDef(state.getName(), state.getType());
  +         // fallback: find matching definition in parent node's node type and mixin 
types
  +         def = parent.getApplicablePropertyDef(state.getName(), state.getType());
        }
   
  -     // create instance
  +     // 3. create instance
        return createPropertyInstance(state, def);
       }
   
  
  
  
  1.6       +0 -0      
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NamespaceRegistryImpl.java
  
  Index: NamespaceRegistryImpl.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NamespaceRegistryImpl.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  
  
  
  1.4       +3 -3      
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NamespaceResolver.java
  
  Index: NamespaceResolver.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NamespaceResolver.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- NamespaceResolver.java    22 Jun 2004 18:03:07 -0000      1.3
  +++ NamespaceResolver.java    16 Jul 2004 16:38:08 -0000      1.4
  @@ -49,5 +49,5 @@
        * @return the prefix mapped to the given URI.
        * @throws NamespaceException if the URI is unknown.
        */
  -    public String getPrefix(String uri)throws NamespaceException;
  +    public String getPrefix(String uri) throws NamespaceException;
   }
  
  
  
  1.4       +0 -0      
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NodeId.java
  
  Index: NodeId.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NodeId.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  
  
  
  1.22      +328 -68   
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.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- NodeImpl.java     13 Jul 2004 15:52:38 -0000      1.21
  +++ NodeImpl.java     16 Jul 2004 16:38:08 -0000      1.22
  @@ -26,6 +26,7 @@
   import org.apache.log4j.Logger;
   import org.apache.slide.jcr.core.nodetype.*;
   import org.apache.slide.jcr.core.state.*;
  +import org.apache.slide.jcr.core.version.VersionImpl;
   import org.apache.slide.jcr.util.ChildrenCollector;
   import org.apache.slide.jcr.util.IteratorHelper;
   import org.apache.slide.jcr.util.MalformedPathException;
  @@ -149,11 +150,23 @@
            // does not exist yet:
            // find definition for the specified property and create property
            QName qName = QName.fromJCRName(name, ticket.getNamespaceResolver());
  -         PropertyDefImpl def = nodeType.getApplicablePropertyDef(qName, type);
  +         PropertyDefImpl def = getApplicablePropertyDef(qName, type);
            return createChildProperty(qName, type, def);
        }
       }
   
  +    protected PropertyImpl getOrCreateProperty(QName name, int type)
  +         throws RepositoryException {
  +     try {
  +         return (PropertyImpl) getProperty(name);
  +     } catch (PathNotFoundException pnfe) {
  +         // does not exist yet:
  +         // find definition for the specified property and create property
  +         PropertyDefImpl def = getApplicablePropertyDef(name, type);
  +         return createChildProperty(name, type, def);
  +     }
  +    }
  +
       protected synchronized PropertyImpl createChildProperty(QName name, int type, 
PropertyDefImpl def)
            throws RepositoryException {
        // check for name collisions with existing child nodes
  @@ -376,12 +389,11 @@
                throw new ConstraintViolationException(msg);
            }
            parentNode = (NodeImpl) parent;
  -         NodeTypeImpl ntParent = (NodeTypeImpl) parentNode.getPrimaryNodeType();
            try {
  -             def = ntParent.getApplicableChildNodeDef(nodeName, nodeType == null ? 
null : nodeType.getQName());
  +             def = getApplicableChildNodeDef(nodeName, nodeType == null ? null : 
nodeType.getQName());
            } catch (RepositoryException re) {
                String msg = "no definition found in parent node's node type for new 
node";
  -             log.error(msg);
  +             log.error(msg, re);
                throw new ConstraintViolationException(msg, re);
            }
            if (nodeType == null) {
  @@ -397,12 +409,13 @@
            ItemImpl item = itemMgr.getItem(nodePath);
            if (!item.isNode()) {
                // there's already a property with that name
  -             throw new ItemExistsException(relPath);
  +             throw new ItemExistsException(item.safeGetJCRPath());
            } else {
                // there's already a node with that name
  -             // check same-name sibling setting
  -             if (!def.allowSameNameSibs()) {
  -                 throw new ItemExistsException(relPath);
  +             // check same-name sibling setting of both new and existing node
  +             if (!def.allowSameNameSibs() ||
  +                     !((NodeImpl) item).getDefinition().allowSameNameSibs()) {
  +                 throw new ItemExistsException(item.safeGetJCRPath());
                }
            }
        } catch (PathNotFoundException pnfe) {
  @@ -421,7 +434,7 @@
            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);
  +         PropertyDefImpl def = getApplicablePropertyDef(PROPNAME_MIXINTYPES, 
PropertyType.STRING);
            prop = createChildProperty(PROPNAME_MIXINTYPES, PropertyType.STRING, def);
        }
        // call internalSetValue for setting the jcr:mixinTypes property
  @@ -435,6 +448,94 @@
        prop.internalSetValue(vals, PropertyType.STRING);
       }
   
  +    /**
  +     * Returns the effective (i.e. merged and resolved) node type representation
  +     * of this node's primary and mixin node types.
  +     *
  +     * @return the effective node type
  +     * @throws RepositoryException
  +     */
  +    protected EffectiveNodeType getEffectiveNodeType() throws RepositoryException {
  +     // build effective node type of mixins & primary type
  +     NodeTypeRegistry ntReg = ticket.getNodeTypeManager().getNodeTypeRegistry();
  +     // existing mixin's
  +     HashSet set = new HashSet(((NodeState) state).getMixinTypeNames());
  +     // primary type
  +     set.add(nodeType.getQName());
  +     try {
  +         return ntReg.buildEffectiveNodeType((QName[]) set.toArray(new 
QName[set.size()]));
  +     } catch (NodeTypeConflictException ntce) {
  +         String msg = "internal error: failed to build effective node type for node 
" + safeGetJCRPath();
  +         log.error(msg, ntce);
  +         throw new RepositoryException(msg, ntce);
  +     }
  +    }
  +
  +    /**
  +     * Returns the applicable child node definition for a child node with the
  +     * specified name and node type.
  +     *
  +     * @param nodeName
  +     * @param nodeTypeName
  +     * @return
  +     * @throws RepositoryException if no applicable child node definition
  +     *                             could be found
  +     */
  +    protected NodeDefImpl getApplicableChildNodeDef(QName nodeName, QName 
nodeTypeName)
  +         throws RepositoryException {
  +/*
  +     return new 
NodeDefImpl(getEffectiveNodeType().getApplicableChildNodeDef(nodeName, nodeTypeName),
  +             ticket.getNodeTypeManager(), ticket.getNamespaceResolver());
  +*/
  +     ArrayList nodeTypeNames = new ArrayList();
  +     nodeTypeNames.add(nodeType.getQName());
  +     nodeTypeNames.addAll(((NodeState) state).getMixinTypeNames());
  +
  +     Iterator iter = nodeTypeNames.iterator();
  +
  +     while (iter.hasNext()) {
  +         NodeTypeImpl nt = ticket.getNodeTypeManager().getNodeType((QName) 
iter.next());
  +         try {
  +             return nt.getApplicableChildNodeDef(nodeName, nodeTypeName);
  +         } catch (RepositoryException re) {
  +             continue;
  +         }
  +     }
  +     throw new RepositoryException("no definition found for child node with name " 
+ nodeName);
  +    }
  +
  +    /**
  +     * Returns the applicable property definition for a property with the
  +     * specified name and type.
  +     *
  +     * @param propertyName
  +     * @param type
  +     * @return
  +     * @throws RepositoryException if no applicable property definition
  +     *                             could be found
  +     */
  +    protected PropertyDefImpl getApplicablePropertyDef(QName propertyName, int type)
  +         throws RepositoryException {
  +/*
  +     return new 
PropertyDefImpl(getEffectiveNodeType().getApplicablePropertyDef(propertyName, type),
  +             ticket.getNodeTypeManager(), ticket.getNamespaceResolver());
  +*/
  +     ArrayList nodeTypeNames = new ArrayList();
  +     nodeTypeNames.add(nodeType.getQName());
  +     nodeTypeNames.addAll(((NodeState) state).getMixinTypeNames());
  +
  +     Iterator iter = nodeTypeNames.iterator();
  +     while (iter.hasNext()) {
  +         NodeTypeImpl nt = ticket.getNodeTypeManager().getNodeType((QName) 
iter.next());
  +         try {
  +             return nt.getApplicablePropertyDef(propertyName, type);
  +         } catch (RepositoryException re) {
  +             continue;
  +         }
  +     }
  +     throw new RepositoryException("no definition found for property with name " + 
propertyName);
  +    }
  +
       protected void makePersistent() throws RepositoryException {
        if (!isTransient()) {
            log.debug(safeGetJCRPath() + " (" + id + "): there's no transient state to 
persist");
  @@ -455,6 +556,8 @@
            persistentState.setParentUUIDs(transientState.getParentUUIDs());
            // mixin types
            persistentState.setMixinTypeNames(transientState.getMixinTypeNames());
  +         // id of definition
  +         persistentState.setDefinitionId(transientState.getDefinitionId());
            // child node entries
            persistentState.setChildNodeEntries(transientState.getChildNodeEntries());
            // property entries
  @@ -488,10 +591,135 @@
       }
   
       protected boolean isRepositoryRoot() {
  -     RepositoryImpl rep = (RepositoryImpl) ticket.getRepository();
        return ((NodeState) state).getUUID().equals(rep.getRootNodeUUID());
       }
   
  +    /**
  +     * Sets the internal value of a property without checking any constraints.
  +     *
  +     * @param name
  +     * @param value
  +     * @return
  +     * @throws ValueFormatException
  +     * @throws RepositoryException
  +     */
  +    protected Property internalSetProperty(QName name, InternalValue value)
  +         throws ValueFormatException, RepositoryException {
  +     // check state of this instance
  +     checkItemState();
  +
  +     int type = (value == null) ? PropertyType.STRING : value.getType();
  +     PropertyImpl prop = getOrCreateProperty(name, type);
  +     prop.internalSetValue(new InternalValue[]{value}, type);
  +     return prop;
  +    }
  +
  +    /**
  +     * Sets the internal value of a property without checking any constraints.
  +     *
  +     * @param name
  +     * @param values
  +     * @return
  +     * @throws ValueFormatException
  +     * @throws RepositoryException
  +     */
  +    protected Property internalSetProperty(QName name, InternalValue[] values)
  +         throws ValueFormatException, RepositoryException {
  +     // check state of this instance
  +     checkItemState();
  +
  +     int type;
  +     if (values == null || values.length == 0) {
  +         type = PropertyType.STRING;
  +     } else {
  +         type = values[0].getType();
  +     }
  +     PropertyImpl prop = getOrCreateProperty(name, type);
  +     prop.internalSetValue(values, type);
  +     return prop;
  +    }
  +
  +    /**
  +     * Returns the property of <code>this</code> node with the specified
  +     * <code>name</code>. The same <code>save</code> and reacquisition
  +     * semantics apply as with <code>[EMAIL PROTECTED] #getProperty(String)}</code>.
  +     *
  +     * @param name The qualified name of the property to retrieve.
  +     * @return The property with the specified <code>name</code>.
  +     * @throws ItemNotFoundException If no property exists with the
  +     *                               specified name.
  +     * @throws RepositoryException   If another error occurs.
  +     */
  +    public Property getProperty(QName name)
  +         throws ItemNotFoundException, RepositoryException {
  +     // check state of this instance
  +     checkItemState();
  +
  +     PropertyId propId = new PropertyId(((NodeState) state).getUUID(), name);
  +     try {
  +         return (Property) itemMgr.getItem(propId);
  +     } catch (AccessDeniedException ade) {
  +         throw new ItemNotFoundException(name.toString());
  +     }
  +    }
  +
  +    /**
  +     * Indicates whether a property with the specified <code>name</code> exists.
  +     * Returns <code>true</code> if the property exists and <code>false</code>
  +     * otherwise.
  +     *
  +     * @param name The qualified name of the property.
  +     * @return <code>true</code> if the property exists; <code>false</code> 
otherwise.
  +     * @throws RepositoryException If an unspecified error occurs.
  +     */
  +    public boolean hasProperty(QName name) throws RepositoryException {
  +     try {
  +         return getProperty(name) != null;
  +     } catch (ItemNotFoundException pnfe) {
  +         return false;
  +     }
  +    }
  +
  +    /**
  +     * 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
  +     * @throws ValueFormatException
  +     * @throws RepositoryException
  +     */
  +    public Property setProperty(String name, QName value) throws 
ValueFormatException, RepositoryException {
  +     // check state of this instance
  +     checkItemState();
  +
  +     PropertyImpl prop = getOrCreateProperty(name, PropertyType.STRING);
  +     prop.setValue(value);
  +     return prop;
  +    }
  +
  +    /**
  +     * 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
  +     * @throws ValueFormatException
  +     * @throws RepositoryException
  +     */
  +    public Property setProperty(String name, QName[] values) throws 
ValueFormatException, RepositoryException {
  +     // check state of this instance
  +     checkItemState();
  +
  +     PropertyImpl prop = getOrCreateProperty(name, PropertyType.STRING);
  +     prop.setValue(values);
  +     return prop;
  +    }
  +
       //-----------------------------------------------------------------< Item >
       /**
        * @see Item#isNode()
  @@ -576,46 +804,6 @@
        return new IteratorHelper(Collections.unmodifiableList(parents));
       }
   
  -    /**
  -     * 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
  -     * @throws ValueFormatException
  -     * @throws RepositoryException
  -     */
  -    public Property setProperty(String name, QName value) throws 
ValueFormatException, RepositoryException {
  -     // check state of this instance
  -     checkItemState();
  -
  -     PropertyImpl prop = getOrCreateProperty(name, PropertyType.STRING);
  -     prop.setValue(value);
  -     return prop;
  -    }
  -
  -    /**
  -     * 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
  -     * @throws ValueFormatException
  -     * @throws RepositoryException
  -     */
  -    public Property setProperty(String name, QName[] values) throws 
ValueFormatException, RepositoryException {
  -     // check state of this instance
  -     checkItemState();
  -
  -     PropertyImpl prop = getOrCreateProperty(name, PropertyType.STRING);
  -     prop.setValue(values);
  -     return prop;
  -    }
  -
       //-----------------------------------------------------------------< Node >
       /**
        * @see Node#remove(String)
  @@ -639,7 +827,7 @@
        }
   
        // check if the specified item exists and if it is protected
  -     Item targetItem;
  +     ItemImpl targetItem;
        try {
            targetItem = itemMgr.getItem(targetPath);
            if (targetItem.isNode()) {
  @@ -647,7 +835,7 @@
                NodeDef def = node.getDefinition();
                // check protected flag
                if (def.isProtected()) {
  -                 String msg = targetPath + ": cannot remove a protected node";
  +                 String msg = targetItem.safeGetJCRPath() + ": cannot remove a 
protected node";
                    log.error(msg);
                    throw new ConstraintViolationException(msg);
                }
  @@ -656,7 +844,7 @@
                PropertyDef def = prop.getDefinition();
                // check protected flag
                if (def.isProtected()) {
  -                 String msg = targetPath + ": cannot remove a protected property";
  +                 String msg = targetItem.safeGetJCRPath() + ": cannot remove a 
protected property";
                    log.error(msg);
                    throw new ConstraintViolationException(msg);
                }
  @@ -667,9 +855,10 @@
   
        NodeImpl parentNode;
        try {
  -         Item parent = itemMgr.getItem(parentPath);
  +         ItemImpl parent = itemMgr.getItem(parentPath);
            if (!parent.isNode()) {
  -             String msg = "cannot remove an item from a property " + parentPath;
  +             // should never get here
  +             String msg = "cannot remove an item from a property " + 
parent.safeGetJCRPath();
                log.error(msg);
                throw new RepositoryException(msg);
            }
  @@ -680,6 +869,13 @@
            throw new PathNotFoundException(relPath);
        }
   
  +     // check protected flag of parent node
  +     if (parentNode.getDefinition().isProtected()) {
  +         String msg = parentNode.safeGetJCRPath() + ": cannot remove a child of a 
protected node";
  +         log.error(msg);
  +         throw new ConstraintViolationException(msg);
  +     }
  +
        // delegate the removal of the child item to the parent node
        if (targetItem.isNode()) {
            parentNode.removeChildNode(targetName.getName(), targetName.getIndex());
  @@ -743,12 +939,13 @@
            ItemImpl item = itemMgr.getItem(path);
            if (!item.isNode()) {
                // there's already a property with that name
  -             throw new ItemExistsException(name);
  +             throw new ItemExistsException(item.safeGetJCRPath());
            } else {
  -             // there's already a node with that name:
  -             // check same-name sibling setting
  -             if (!definition.allowSameNameSibs()) {
  -                 throw new ItemExistsException(name);
  +             // there's already a node with that name
  +             // check same-name sibling setting of both target and existing node
  +             if (!node.getDefinition().allowSameNameSibs() ||
  +                     !((NodeImpl) item).getDefinition().allowSameNameSibs()) {
  +                 throw new ItemExistsException(item.safeGetJCRPath());
                }
            }
        } catch (MalformedPathException mpe) {
  @@ -1280,6 +1477,13 @@
        // check state of this instance
        checkItemState();
   
  +     // check protected flag
  +     if (definition.isProtected()) {
  +         String msg = safeGetJCRPath() + ": cannot add a mixin node type to a 
protected node";
  +         log.error(msg);
  +         throw new ConstraintViolationException(msg);
  +     }
  +
        QName ntName = QName.fromJCRName(mixinName, ticket.getNamespaceResolver());
   
        NodeTypeManagerImpl ntMgr = (NodeTypeManagerImpl) 
ticket.getWorkspace().getNodeTypeManager();
  @@ -1340,6 +1544,13 @@
        // check state of this instance
        checkItemState();
   
  +     // check protected flag
  +     if (definition.isProtected()) {
  +         String msg = safeGetJCRPath() + ": cannot remove a mixin node type from a 
protected node";
  +         log.error(msg);
  +         throw new ConstraintViolationException(msg);
  +     }
  +
        QName ntName = QName.fromJCRName(mixinName, ticket.getNamespaceResolver());
   
        // check if mixin is assigned
  @@ -1425,6 +1636,11 @@
        // check state of this instance
        checkItemState();
   
  +     // check protected flag
  +     if (definition.isProtected()) {
  +         return false;
  +     }
  +
        QName ntName = QName.fromJCRName(mixinName, ticket.getNamespaceResolver());
   
        NodeTypeManagerImpl ntMgr = (NodeTypeManagerImpl) 
ticket.getWorkspace().getNodeTypeManager();
  @@ -1552,11 +1768,29 @@
        return thisState.getUUID();
       }
   
  +    //---------------------------------------------------< versioning support >
  +    /**
  +     * Checks if this node is versionable, i.e. has 'mix:versionable'.
  +     *
  +     * @throws UnsupportedRepositoryOperationException
  +     *          if this node is not versionable
  +     */
  +    private void checkVersionable()
  +         throws UnsupportedRepositoryOperationException, RepositoryException {
  +     if (!isNodeType(NodeTypeRegistry.MIX_VERSIONABLE)) {
  +         String msg = "Unable to perform versioning operation on non versionable 
node: " + safeGetJCRPath();
  +         log.warn(msg);
  +         throw new UnsupportedRepositoryOperationException(msg);
  +     }
  +    }
  +
       /**
        * @see Node#checkin()
        */
       public Version checkin()
            throws UnsupportedRepositoryOperationException, RepositoryException {
  +     checkVersionable();
  +
        // @todo implement versioning support
        throw new UnsupportedRepositoryOperationException();
       }
  @@ -1566,6 +1800,8 @@
        */
       public void checkout()
            throws UnsupportedRepositoryOperationException, RepositoryException {
  +     checkVersionable();
  +
        // @todo implement versioning support
        throw new UnsupportedRepositoryOperationException();
       }
  @@ -1576,6 +1812,8 @@
       public void addPredecessor(Version v)
            throws VersionException, UnsupportedRepositoryOperationException,
            RepositoryException {
  +     checkVersionable();
  +
        // @todo implement versioning support
        throw new UnsupportedRepositoryOperationException();
       }
  @@ -1586,6 +1824,8 @@
       public void removePredecessor(Version v)
            throws VersionException, UnsupportedRepositoryOperationException,
            RepositoryException {
  +     checkVersionable();
  +
        // @todo implement versioning support
        throw new UnsupportedRepositoryOperationException();
       }
  @@ -1595,6 +1835,8 @@
        */
       public void update(String srcWorkspaceName, boolean deep)
            throws NoSuchWorkspaceException, RepositoryException {
  +     checkVersionable();
  +
        // @todo implement versioning support
        throw new UnsupportedRepositoryOperationException();
       }
  @@ -1605,6 +1847,8 @@
       public void merge(String srcWorkspace, boolean deep)
            throws UnsupportedRepositoryOperationException, NoSuchWorkspaceException,
            MergeException, RepositoryException {
  +     checkVersionable();
  +
        // @todo implement versioning support
        throw new UnsupportedRepositoryOperationException();
       }
  @@ -1614,8 +1858,13 @@
        */
       public boolean isCheckedOut()
            throws UnsupportedRepositoryOperationException, RepositoryException {
  -     // @todo implement versioning support
  -     throw new UnsupportedRepositoryOperationException();
  +     checkVersionable();
  +
  +     try {
  +         return getProperty(VersionImpl.PROPNAME_IS_CHECKED_OUT).getBoolean();
  +     } catch (ItemNotFoundException infe) {
  +         return false;
  +     }
       }
   
       /**
  @@ -1624,6 +1873,8 @@
       public void restore(String versionName)
            throws VersionException, UnsupportedRepositoryOperationException,
            RepositoryException {
  +     checkVersionable();
  +
        // @todo implement versioning support
        throw new UnsupportedRepositoryOperationException();
       }
  @@ -1633,6 +1884,8 @@
        */
       public void restore(Version version)
            throws UnsupportedRepositoryOperationException, RepositoryException {
  +     checkVersionable();
  +
        // @todo implement versioning support
        throw new UnsupportedRepositoryOperationException();
       }
  @@ -1644,6 +1897,8 @@
            throws PathNotFoundException, ItemExistsException,
            ConstraintViolationException, UnsupportedRepositoryOperationException,
            RepositoryException {
  +     checkVersionable();
  +
        // @todo implement versioning support
        throw new UnsupportedRepositoryOperationException();
       }
  @@ -1653,6 +1908,8 @@
        */
       public void restoreByLabel(String versionLabel)
            throws UnsupportedRepositoryOperationException, RepositoryException {
  +     checkVersionable();
  +
        // @todo implement versioning support
        throw new UnsupportedRepositoryOperationException();
       }
  @@ -1662,8 +1919,9 @@
        */
       public VersionHistory getVersionHistory()
            throws UnsupportedRepositoryOperationException, RepositoryException {
  -     // @todo implement versioning support
  -     throw new UnsupportedRepositoryOperationException();
  +     checkVersionable();
  +
  +     return rep.getVersionManager().getVersionHistory(this);
       }
   
       /**
  @@ -1671,10 +1929,12 @@
        */
       public Version getBaseVersion()
            throws UnsupportedRepositoryOperationException, RepositoryException {
  -     // @todo implement versioning support
  -     throw new UnsupportedRepositoryOperationException();
  +     checkVersionable();
  +
  +     return rep.getVersionManager().getBaseVersion(this);
       }
   
  +    //------------------------------------------------------< locking support >
       /**
        * @see Node#lock(boolean, boolean)
        */
  
  
  
  1.4       +0 -0      
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NoPrefixDeclaredException.java
  
  Index: NoPrefixDeclaredException.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NoPrefixDeclaredException.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  
  
  

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

Reply via email to