You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by st...@apache.org on 2004/07/16 18:38:08 UTC

cvs commit: jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core ItemLifeCycleListener.java ItemManager.java NamespaceRegistryImpl.java NamespaceResolver.java NodeId.java NodeImpl.java NoPrefixDeclaredException.java

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>{@link #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>{@link 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>{@link 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>{@link 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>{@link 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: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org