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/22 18:14:23 UTC

cvs commit: jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/nodetype NodeTypeDef.java NodeTypeRegistry.java

stefan      2004/07/22 09:14:22

  Modified:    proposals/jcrri/src/org/apache/slide/jcr/core NodeImpl.java
                        Test.java TicketImpl.java WorkspaceImpl.java
               proposals/jcrri/src/org/apache/slide/jcr/core/nodetype
                        NodeTypeDef.java NodeTypeRegistry.java
  Log:
  jcrri
  
  Revision  Changes    Path
  1.25      +44 -7     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.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- NodeImpl.java	21 Jul 2004 16:58:03 -0000	1.24
  +++ NodeImpl.java	22 Jul 2004 16:14:22 -0000	1.25
  @@ -312,6 +312,15 @@
   	}
       }
   
  +    protected void onRedefine(NodeDefId defId) throws RepositoryException {
  +	NodeDefImpl newDef = ticket.getNodeTypeManager().getNodeDef(defId);
  +	// modify the state of 'this', i.e. the target node
  +	NodeState thisState = (NodeState) getOrCreateTransientItemState();
  +	// set id of new definition
  +	thisState.setDefinitionId(defId);
  +	definition = newDef;
  +    }
  +
       protected void onLink(NodeState parentState) throws RepositoryException {
   	// modify the state of 'this', i.e. the target node
   	NodeState thisState = (NodeState) getOrCreateTransientItemState();
  @@ -490,10 +499,9 @@
        */
       protected NodeDefImpl getApplicableChildNodeDef(QName nodeName, QName nodeTypeName)
   	    throws RepositoryException {
  +	ChildNodeDef cnd = getEffectiveNodeType().getApplicableChildNodeDef(nodeName, nodeTypeName);
  +	return ticket.getNodeTypeManager().getNodeDef(new NodeDefId(cnd));
   /*
  -	return new NodeDefImpl(getEffectiveNodeType().getApplicableChildNodeDef(nodeName, nodeTypeName),
  -		ticket.getNodeTypeManager(), ticket.getNamespaceResolver());
  -*/
   	ArrayList nodeTypeNames = new ArrayList();
   	nodeTypeNames.add(nodeType.getQName());
   	nodeTypeNames.addAll(((NodeState) state).getMixinTypeNames());
  @@ -509,6 +517,7 @@
   	    }
   	}
   	throw new RepositoryException("no definition found for child node with name " + nodeName);
  +*/
       }
   
       /**
  @@ -605,7 +614,7 @@
        * Sets the internal value of a property without checking any constraints.
        * <p/>
        * Note that no type conversion is being performed, i.e. it's the caller's
  -     * responsibility to make sure the type of the given value is compatible
  +     * responsibility to make sure that the type of the given value is compatible
        * with the specified property's definition.
        *
        * @param name
  @@ -623,7 +632,7 @@
        * Sets the internal value of a property without checking any constraints.
        * <p/>
        * Note that no type conversion is being performed, i.e. it's the caller's
  -     * responsibility to make sure the type of the given values is compatible
  +     * responsibility to make sure that the type of the given values is compatible
        * with the specified property's definition.
        *
        * @param name
  @@ -965,6 +974,13 @@
   	    // no name collision
   	}
   
  +	// check protected flag
  +	if (definition.isProtected()) {
  +	    String msg = safeGetJCRPath() + ": cannot add a child node to a protected node";
  +	    log.error(msg);
  +	    throw new ConstraintViolationException(msg);
  +	}
  +
   	return createChildNodeLink(QName.fromJCRName(name, ticket.getNamespaceResolver()), targetNode.getUUID());
       }
   
  @@ -1960,11 +1976,28 @@
   
       //------------------------------------------------------< locking support >
       /**
  +     * Checks if this node is lockable, i.e. has 'mix:lockable'.
  +     *
  +     * @throws UnsupportedRepositoryOperationException
  +     *          if this node is not lockable
  +     */
  +    private void checkLockable()
  +	    throws UnsupportedRepositoryOperationException, RepositoryException {
  +	if (!isNodeType(NodeTypeRegistry.MIX_LOCKABLE)) {
  +	    String msg = "Unable to perform locking operation on non lockable node: " + safeGetJCRPath();
  +	    log.debug(msg);
  +	    throw new UnsupportedRepositoryOperationException(msg);
  +	}
  +    }
  +
  +    /**
        * @see Node#lock(boolean, boolean)
        */
       public Lock lock(boolean isDeep, boolean isTicketScoped)
   	    throws UnsupportedRepositoryOperationException, LockException,
   	    AccessDeniedException, RepositoryException {
  +	checkLockable();
  +
   	// @todo implement locking support
   	throw new UnsupportedRepositoryOperationException();
       }
  @@ -1975,6 +2008,8 @@
       public Lock getLock()
   	    throws UnsupportedRepositoryOperationException, LockException,
   	    AccessDeniedException, RepositoryException {
  +	checkLockable();
  +
   	// @todo implement locking support
   	throw new UnsupportedRepositoryOperationException();
       }
  @@ -1985,6 +2020,8 @@
       public void unlock()
   	    throws UnsupportedRepositoryOperationException, LockException,
   	    AccessDeniedException, RepositoryException {
  +	checkLockable();
  +
   	// @todo implement locking support
   	throw new UnsupportedRepositoryOperationException();
       }
  
  
  
  1.11      +6 -1      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.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- Test.java	21 Jul 2004 16:58:03 -0000	1.10
  +++ Test.java	22 Jul 2004 16:14:22 -0000	1.11
  @@ -92,6 +92,11 @@
   	System.out.println();
   	dumpTree(root, System.out);
   
  +	t.move("/foo", "/misc/bla");
  +	System.out.println("after move...");
  +	System.out.println();
  +	dumpTree(root, System.out);
  +
   	if (root.canAddMixin("mix:versionable")) {
   	    root.addMixin("mix:versionable");
   	    if (root.canAddMixin("mix:accessControllable")) {
  
  
  
  1.16      +108 -36   jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/TicketImpl.java
  
  Index: TicketImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/TicketImpl.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- TicketImpl.java	21 Jul 2004 16:58:03 -0000	1.15
  +++ TicketImpl.java	22 Jul 2004 16:14:22 -0000	1.16
  @@ -24,8 +24,8 @@
   package org.apache.slide.jcr.core;
   
   import org.apache.log4j.Logger;
  -import org.apache.slide.jcr.core.nodetype.NodeTypeManagerImpl;
  -import org.apache.slide.jcr.core.nodetype.NodeTypeRegistry;
  +import org.apache.slide.jcr.core.nodetype.*;
  +import org.apache.slide.jcr.core.state.NodeState;
   import org.apache.slide.jcr.core.state.TicketItemStateManager;
   import org.apache.slide.jcr.util.MalformedPathException;
   import org.xml.sax.ContentHandler;
  @@ -327,57 +327,128 @@
       /**
        * @see Ticket#move(String, String)
        */
  -    public void move(String srcAbsPath, String destAbsPath) throws ItemExistsException, PathNotFoundException, ConstraintViolationException, RepositoryException {
  -	// @todo implement move
  -	throw new RepositoryException("Ticket.move() is not implemented yet.");
  -/*
  -	// get source node
  -	Item srcItem = null;
  +    public void move(String srcAbsPath, String destAbsPath)
  +	    throws ItemExistsException, PathNotFoundException,
  +	    ConstraintViolationException, RepositoryException {
  +
  +	// check paths & get node instances
  +
  +	Path srcPath;
  +	Path.PathElement srcName;
  +	Path srcParentPath;
  +	NodeImpl targetNode;
  +	NodeImpl srcParentNode;
   	try {
  -	    srcItem = itemMgr.getItem(Path.create(srcAbsPath, getNamespaceResolver(), true));
  +	    srcPath = Path.create(srcAbsPath, getNamespaceResolver(), true);
  +	    srcName = srcPath.getNameElement();
  +	    srcParentPath = srcPath.getAncestor(1);
  +	    ItemImpl item = itemMgr.getItem(srcPath);
  +	    if (!item.isNode()) {
  +		throw new PathNotFoundException(srcAbsPath);
  +	    }
  +	    targetNode = (NodeImpl) item;
  +	    srcParentNode = (NodeImpl) itemMgr.getItem(srcParentPath);
  +	} catch (AccessDeniedException ade) {
  +	    throw new PathNotFoundException(srcAbsPath);
   	} catch (MalformedPathException mpe) {
  -	    String msg = "invalid path: " + srcAbsPath;
  +	    String msg = srcAbsPath + ": invalid path";
   	    log.error(msg, mpe);
   	    throw new RepositoryException(msg, mpe);
  -	} catch (AccessDeniedException ade) {
  -	    throw new PathNotFoundException(srcAbsPath);
   	}
  -	if (!srcItem.isNode()) {
  -	    log.error("node expected: " + srcAbsPath);
  -	    throw new RepositoryException("node expected: " + srcAbsPath);
  -	}
  -	Node srcNode = (Node) srcItem;
  -	Node srcParentNode = srcNode.getParent();
   
  -	// get destination parent node
  -	Item destParentItem = null;
  +	Path destPath;
  +	Path.PathElement destName;
  +	Path destParentPath;
  +	NodeImpl destParentNode;
   	try {
  -	    destParentItem = itemMgr.getItem(Path.create(destAbsPath, getNamespaceResolver(), true).getAncestor(1));
  +	    destPath = Path.create(destAbsPath, getNamespaceResolver(), true);
  +	    destName = destPath.getNameElement();
  +	    destParentPath = destPath.getAncestor(1);
  +	    destParentNode = (NodeImpl) itemMgr.getItem(destParentPath);
  +	} catch (AccessDeniedException ade) {
  +	    throw new PathNotFoundException(destAbsPath);
   	} catch (MalformedPathException mpe) {
  -	    String msg = "invalid destination path: " + destAbsPath;
  +	    String msg = destAbsPath + ": invalid path";
   	    log.error(msg, mpe);
   	    throw new RepositoryException(msg, mpe);
  +	}
  +	int ind = destName.getIndex();
  +	if (ind > 0) {
  +	    // subscript in name element
  +	    String msg = destAbsPath + ": invalid destination path (subscript in name element is not allowed)";
  +	    log.error(msg);
  +	    throw new RepositoryException(msg);
  +	}
  +
  +	// check for name collisions
  +
  +	try {
  +	    ItemImpl item = itemMgr.getItem(destPath);
  +	    if (!item.isNode()) {
  +		// there's already a property with that name
  +		throw new ItemExistsException(item.safeGetJCRPath());
  +	    } else {
  +		// there's already a node with that name
  +		// check same-name sibling setting of both new and existing node
  +		if (!destParentNode.getDefinition().allowSameNameSibs() ||
  +			!((NodeImpl) item).getDefinition().allowSameNameSibs()) {
  +		    throw new ItemExistsException(item.safeGetJCRPath());
  +		}
  +	    }
   	} catch (AccessDeniedException ade) {
  -	    throw new PathNotFoundException(destAbsPath);
  +	    // FIXME by throwing ItemExistsException we're disclosing too much information
  +	    throw new ItemExistsException(destAbsPath);
  +	} catch (PathNotFoundException pnfe) {
  +	    // no name collision
   	}
   
  -	if (!destParentItem.isNode()) {
  -	    String msg = "invalid destination path: " + destAbsPath;
  +	// check constraints
  +
  +	// get applicable definition of target node at new location
  +	NodeTypeImpl nt = (NodeTypeImpl) targetNode.getPrimaryNodeType();
  +	NodeDefImpl newTargetDef;
  +	try {
  +	    newTargetDef = destParentNode.getApplicableChildNodeDef(destName.getName(), nt.getQName());
  +	} catch (RepositoryException re) {
  +	    String msg = destAbsPath + ": no definition found in parent node's node type for new node";
  +	    log.error(msg, re);
  +	    throw new ConstraintViolationException(msg, re);
  +	}
  +	// check protected flag of old & new parent
  +	if (destParentNode.getDefinition().isProtected()) {
  +	    String msg = destAbsPath + ": cannot add a child node to a protected node";
   	    log.error(msg);
  -	    throw new RepositoryException(msg);
  +	    throw new ConstraintViolationException(msg);
  +	}
  +	if (srcParentNode.getDefinition().isProtected()) {
  +	    String msg = srcAbsPath + ": cannot remove a child node from a protected node";
  +	    log.error(msg);
  +	    throw new ConstraintViolationException(msg);
   	}
  -	Node destParentNode = (Node) destParentItem;
   
  -	// FIXME: poor man's move...
  -	copy(srcAbsPath, destAbsPath);
  -	getRootNode().remove(srcAbsPath);
  -*/
  +	// do move operation
  +
  +	String targetUUID = ((NodeState) targetNode.getItemState()).getUUID();
  +	// add target to new parent
  +	destParentNode.createChildNodeLink(destName.getName(), targetUUID);
  +	// remove target from old parent
  +	srcParentNode.removeChildNode(srcName.getName(), srcName.getIndex() == 0 ? 1 : srcName.getIndex());
  +	// change definition of target if necessary
  +	NodeDefImpl oldTargetDef = (NodeDefImpl) targetNode.getDefinition();
  +	NodeDefId oldTargetDefId = new NodeDefId(oldTargetDef.unwrap());
  +	NodeDefId newTargetDefId = new NodeDefId(newTargetDef.unwrap());
  +	if (!oldTargetDefId.equals(newTargetDefId)) {
  +	    targetNode.onRedefine(newTargetDefId);
  +	}
       }
   
       /**
        * @see Ticket#importXML(String, InputStream)
        */
  -    public void importXML(String parentAbsPath, InputStream in) throws IOException, PathNotFoundException, ItemExistsException, ConstraintViolationException, InvalidSerializedDataException, RepositoryException {
  +    public void importXML(String parentAbsPath, InputStream in)
  +	    throws IOException, PathNotFoundException, ItemExistsException,
  +	    ConstraintViolationException, InvalidSerializedDataException,
  +	    RepositoryException {
   	// @todo implement importXML
   	throw new RepositoryException("Ticket.importXML() is not implemented yet.");
   
  @@ -419,9 +490,10 @@
   	// discard all transient changes
   	itemStateMgr.disposeAllTransientItemStates();
   
  -	log.debug("disposing workspace");
  +	// @todo invalidate ticket, release ticket-scoped locks, free resources, prepare to get gc'ed etc.
  +
  +	log.debug("disposing workspace...");
   	wsp.dispose();
  -	// @todo implement logout, i.e. invalidate ticket, free resources, prepare to get gc'ed etc.
       }
   
       /**
  
  
  
  1.8       +28 -6     jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/WorkspaceImpl.java
  
  Index: WorkspaceImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/WorkspaceImpl.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- WorkspaceImpl.java	21 Jul 2004 16:58:03 -0000	1.7
  +++ WorkspaceImpl.java	22 Jul 2004 16:14:22 -0000	1.8
  @@ -46,10 +46,8 @@
   import java.io.IOException;
   import java.io.OutputStream;
   import java.io.PrintStream;
  -import java.util.ArrayList;
   import java.util.HashSet;
   import java.util.Iterator;
  -import java.util.List;
   
   /**
    * A <code>WorkspaceImpl</code> ...
  @@ -606,6 +604,13 @@
   	    log.error(msg, mpe);
   	    throw new RepositoryException(msg, mpe);
   	}
  +	int ind = destName.getIndex();
  +	if (ind > 0) {
  +	    // subscript in name element
  +	    String msg = destAbsPath + ": invalid destination path (subscript in name element is not allowed)";
  +	    log.error(msg);
  +	    throw new RepositoryException(msg);
  +	}
   
   	// 2. check access rights & node type constraints
   
  @@ -621,6 +626,7 @@
   	}
   	// check node type constraints
   	checkAddNode(destPath, srcState.getNodeTypeName(), ntReg, accessMgr, destHierMgr, destStateMgr);
  +/*
   	// check if target node needs to be inserted at specific location in child node entries list
   	boolean insertTargetEntry = false;
   	int ind = destName.getIndex();
  @@ -641,7 +647,7 @@
   		throw new ConstraintViolationException(destAbsPath + ": parent node's node type does not allow explicit ordering of child nodes");
   	    }
   	}
  -
  +*/
   	// 3. do copy operation (modify and persist affected states)
   
   	// create deep copy of source node state
  @@ -649,6 +655,8 @@
   		ntReg, srcHierMgr, srcStateMgr, destStateMgr);
   
   	// add to new parent
  +	destParentState.addChildNodeEntry(destName.getName(), newState.getUUID());
  +/*
   	if (!insertTargetEntry) {
   	    // append target entry
   	    destParentState.addChildNodeEntry(destName.getName(), newState.getUUID());
  @@ -665,6 +673,7 @@
   		destParentState.addChildNodeEntry(entry.getName(), entry.getUUID());
   	    }
   	}
  +*/
   	// change definition (id) of new node
   	ChildNodeDef newNodeDef = findApplicableDefinition(destName.getName(), srcState.getNodeTypeName(), destParentState, ntReg);
   	newState.setDefinitionId(new NodeDefId(newNodeDef));
  @@ -778,6 +787,13 @@
   	    log.error(msg, mpe);
   	    throw new RepositoryException(msg, mpe);
   	}
  +	int ind = destName.getIndex();
  +	if (ind > 0) {
  +	    // subscript in name element
  +	    String msg = destAbsPath + ": invalid destination path (subscript in name element is not allowed)";
  +	    log.error(msg);
  +	    throw new RepositoryException(msg);
  +	}
   
   	// 2. check node type constraints & access rights
   
  @@ -785,6 +801,7 @@
   	checkAddNode(destPath, targetState.getNodeTypeName(),
   		rep.getNodeTypeRegistry(), ticket.getAccessManager(),
   		hierMgr, persistentStateMgr);
  +/*
   	// check if target node needs to be inserted at specific location in child node entries list
   	boolean insertTargetEntry = false;
   	int ind = destName.getIndex();
  @@ -805,7 +822,7 @@
   		throw new ConstraintViolationException(destAbsPath + ": parent node's node type does not allow explicit ordering of child nodes");
   	    }
   	}
  -
  +*/
   	// 3. do move operation (modify and persist affected states)
   
   	boolean renameOnly = srcParentState.getUUID().equals(destParentState.getUUID());
  @@ -814,6 +831,8 @@
   	if (!renameOnly) {
   	    targetState.addParentUUID(destParentState.getUUID());
   	}
  +	destParentState.addChildNodeEntry(destName.getName(), targetState.getUUID());
  +/*
   	if (!insertTargetEntry) {
   	    // append target entry
   	    destParentState.addChildNodeEntry(destName.getName(), targetState.getUUID());
  @@ -830,6 +849,7 @@
   		destParentState.addChildNodeEntry(entry.getName(), entry.getUUID());
   	    }
   	}
  +*/
   	// change definition (id) of target node
   	ChildNodeDef newTargetDef = findApplicableDefinition(destName.getName(), targetState.getNodeTypeName(), destParentState, rep.getNodeTypeRegistry());
   	targetState.setDefinitionId(new NodeDefId(newTargetDef));
  @@ -839,6 +859,7 @@
   	    targetState.removeParentUUID(srcParentState.getUUID());
   	}
   	int srcNameIndex = srcName.getIndex() == 0 ? 1 : srcName.getIndex();
  +/*
   	// if the net result of the move is changing the position of a child node
   	// among its same-same siblings, the subscript of the child node entry
   	// to be removed might need adjustment
  @@ -846,6 +867,7 @@
   		insertTargetEntry && destName.getIndex() <= srcNameIndex) {
   	    srcNameIndex++;
   	}
  +*/
   	srcParentState.removeChildNodeEntry(srcName.getName(), srcNameIndex);
   
   	// persist states
  
  
  
  1.9       +5 -3      jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/nodetype/NodeTypeDef.java
  
  Index: NodeTypeDef.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/nodetype/NodeTypeDef.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- NodeTypeDef.java	20 Jul 2004 08:28:35 -0000	1.8
  +++ NodeTypeDef.java	22 Jul 2004 16:14:22 -0000	1.9
  @@ -86,7 +86,9 @@
   		}
   		QName[] ntNames = nodeDefs[i].getRequiredPrimaryTypes();
   		for (int j = 0; j < ntNames.length; j++) {
  -		    dependencies.add(ntNames[j]);
  +		    if (ntNames[j] != null && !name.equals(ntNames[j])) {
  +			dependencies.add(ntNames[j]);
  +		    }
   		}
   	    }
   	}
  
  
  
  1.11      +5 -2      jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/nodetype/NodeTypeRegistry.java
  
  Index: NodeTypeRegistry.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/nodetype/NodeTypeRegistry.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- NodeTypeRegistry.java	21 Jul 2004 16:58:04 -0000	1.10
  +++ NodeTypeRegistry.java	22 Jul 2004 16:14:22 -0000	1.11
  @@ -63,6 +63,9 @@
       // mix:referenceable
       public static final QName MIX_REFERENCEABLE =
   	    new QName(NamespaceRegistryImpl.NS_MIX_URI, "referenceable");
  +    // mix:lockable
  +    public static final QName MIX_LOCKABLE =
  +	    new QName(NamespaceRegistryImpl.NS_MIX_URI, "lockable");
       // mix:versionable
       public static final QName MIX_VERSIONABLE =
   	    new QName(NamespaceRegistryImpl.NS_MIX_URI, "versionable");
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org