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