You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2010/02/25 14:10:45 UTC
svn commit: r916278 - in /jackrabbit/trunk:
jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/
jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/
jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ jackrabbit...
Author: angela
Date: Thu Feb 25 13:10:45 2010
New Revision: 916278
URL: http://svn.apache.org/viewvc?rev=916278&view=rev
Log:
JCR-2519: spi2davex: use srcWorkspaceName to build srcPath for clone and copy
JCR-2104: JSR 283 Full Versioning
- jcr2spi: simplify VersionManager.checkpoint if Node is already checkedin
- spi2dav: implement shallow merge
- spi2dav: fix bug in merge (besteffort <-> DAV:no-auto-merge)
- spi2dav: fix bug in restore (nodeId may point to non-existing node -> extract existing parent + relPath
- jcr-server: implement shallow merge
- jcr-server: fix merge. for 1:1 remoting the MERGE response body should list the failed ids instead of the affected resource [DeltaV specified behaviour that doesn't make sense for remoting over SPI]
- jcr-server: prefer VersionManager over deprecated version methods
- jcr-server: fix restore with relPath
Modified:
jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/VersionControlledItemCollection.java
jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java
Modified: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/VersionControlledItemCollection.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/VersionControlledItemCollection.java?rev=916278&r1=916277&r2=916278&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/VersionControlledItemCollection.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/VersionControlledItemCollection.java Thu Feb 25 13:10:45 2010
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.webdav.jcr;
import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.webdav.DavConstants;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavLocatorFactory;
import org.apache.jackrabbit.webdav.DavResource;
@@ -54,6 +55,7 @@
import javax.jcr.observation.EventListener;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionManager;
import java.util.List;
import java.util.Collections;
@@ -153,6 +155,9 @@
}
try {
Node n = (Node) item;
+ VersionManager vMgr = getVersionManager();
+ String path = item.getPath();
+
DavProperty<?> autoMergeSet = null;
DavProperty<?> predecessorSet = null;
/* find DAV:auto-merge-set entries. If none exists no attempt is made
@@ -168,7 +173,7 @@
}
Value[] mergeFailed = n.getProperty(JcrConstants.JCR_MERGEFAILED).getValues();
for (Value value : mergeFailed) {
- n.cancelMerge((Version) getRepositorySession().getNodeByUUID(value.getString()));
+ vMgr.cancelMerge(path, (Version) getRepositorySession().getNodeByIdentifier(value.getString()));
}
// remove this entry from the changeList
changeList.remove(propEntry);
@@ -204,7 +209,7 @@
for (Value value : mergeFailed) {
// build version-href from each entry in the jcr:mergeFailed property
// in order to be able to compare to the entries in the HrefProperty.
- Version version = (Version) session.getNodeByUUID(value.getString());
+ Version version = (Version) session.getNodeByIdentifier(value.getString());
String href = getLocatorFromItem(version).getHref(true);
// Test if that version has been removed from the merge-set.
@@ -216,9 +221,9 @@
// merge-set but not added to the predecessors 'cancelMerge'
// must be called.
if (predecL.contains(href)) {
- n.doneMerge(version);
+ vMgr.doneMerge(path, version);
} else {
- n.cancelMerge(version);
+ vMgr.cancelMerge(path, version);
}
}
}
@@ -273,7 +278,7 @@
throw new DavException(DavServletResponse.SC_METHOD_NOT_ALLOWED);
}
try {
- Version v = ((Node) item).checkin();
+ Version v = getVersionManager().checkin(item.getPath());
String versionHref = getLocatorFromItem(v).getHref(true);
return versionHref;
} catch (RepositoryException e) {
@@ -296,7 +301,7 @@
throw new DavException(DavServletResponse.SC_METHOD_NOT_ALLOWED);
}
try {
- ((Node) item).checkout();
+ getVersionManager().checkout(item.getPath());
} catch (RepositoryException e) {
// UnsupportedRepositoryException should not occur
throw new JcrDavException(e);
@@ -365,8 +370,11 @@
if (relPath == null) {
// restore version by name
node.restore(versionName, removeExisting);
+ } else if (node.hasNode(relPath)) {
+ Version v = node.getNode(relPath).getVersionHistory().getVersion(versionName);
+ node.restore(v, relPath, removeExisting);
} else {
- Version v = node.getVersionHistory().getVersion(versionName);
+ Version v = (Version) getRepositorySession().getNode(versionPath);
node.restore(v, relPath, removeExisting);
}
@@ -416,19 +424,18 @@
MultiStatus ms = new MultiStatus();
try {
- Node node = (Node)item;
-
- // register eventListener in order to be able to report all
- // modified resources.
- EventListener el = new EListener(mergeInfo.getPropertyNameSet(), ms);
- registerEventListener(el, node.getPath());
-
+ // NOTE: RFC requires that all modified resources are reported in the
+ // multistatus response. this doesn't work however with the remoting
+ // there is no way to distinguish the 'failedId's from any other
+ // resources that got modified by this merge operation -> omitted.
+
// todo: RFC allows multiple href elements inside the DAV:source element
String workspaceName = getLocatorFromHref(mergeInfo.getSourceHrefs()[0]).getWorkspaceName();
- NodeIterator failed = node.merge(workspaceName, !mergeInfo.isNoAutoMerge());
- // unregister the event listener again
- unregisterEventListener(el);
+ String depth = DomUtil.getChildTextTrim(mergeInfo.getMergeElement(), DavConstants.XML_DEPTH, DavConstants.NAMESPACE);
+ boolean isShallow = "0".equals(depth);
+
+ NodeIterator failed = getVersionManager().merge(item.getPath(), workspaceName, !mergeInfo.isNoAutoMerge(), isShallow);
// add resources to the multistatus, that failed to be merged
while (failed.hasNext()) {
@@ -612,4 +619,8 @@
String prefix = getLocator().getPrefix();
return f.createResourceLocator(prefix, href);
}
+
+ private VersionManager getVersionManager() throws RepositoryException {
+ return getRepositorySession().getWorkspace().getVersionManager();
+ }
}
Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java?rev=916278&r1=916277&r2=916278&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java Thu Feb 25 13:10:45 2010
@@ -898,8 +898,13 @@
checkIsVersionable();
checkHasPendingChanges();
checkIsLocked();
- NodeEntry newVersion = session.getVersionStateManager().checkpoint(getNodeState());
- return (Version) getItemManager().getItem(newVersion);
+ if (!isCheckedOut()) {
+ checkout();
+ return getBaseVersion();
+ } else {
+ NodeEntry newVersion = session.getVersionStateManager().checkpoint(getNodeState());
+ return (Version) getItemManager().getItem(newVersion);
+ }
}
/**
Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java?rev=916278&r1=916277&r2=916278&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java Thu Feb 25 13:10:45 2010
@@ -65,6 +65,7 @@
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
@@ -402,7 +403,11 @@
}
protected String getItemUri(ItemId itemId, SessionInfo sessionInfo) throws RepositoryException {
- return uriResolver.getItemUri(itemId, sessionInfo.getWorkspaceName(), sessionInfo);
+ return getItemUri(itemId, sessionInfo, sessionInfo.getWorkspaceName());
+ }
+
+ protected String getItemUri(ItemId itemId, SessionInfo sessionInfo, String workspaceName) throws RepositoryException {
+ return uriResolver.getItemUri(itemId, workspaceName, sessionInfo);
}
/**
@@ -1111,10 +1116,11 @@
boolean isMultiValued;
QValue[] values;
- int type = JcrValueType.typeFromContentType(ct);
+ int type;
NamePathResolver resolver = getNamePathResolver(sessionInfo);
- if (type != PropertyType.UNDEFINED) {
+ if (ct.startsWith("jcr-value")) {
+ type = JcrValueType.typeFromContentType(ct);
QValue v;
if (type == PropertyType.BINARY) {
v = getQValueFactory().create(method.getResponseBodyAsStream());
@@ -1144,6 +1150,7 @@
}
return new PropertyInfoImpl(propertyId, path, type, isMultiValued, values);
+
} catch (IOException e) {
throw new RepositoryException(e);
} catch (DavException e) {
@@ -1322,7 +1329,7 @@
String uri = getItemUri(nodeId, sessionInfo);
String workspUri = uriResolver.getWorkspaceUri(srcWorkspaceName);
- update(uri, new String[] {workspUri}, UpdateInfo.UPDATE_BY_WORKSPACE, false, sessionInfo);
+ update(uri, null, new String[] {workspUri}, UpdateInfo.UPDATE_BY_WORKSPACE, false, sessionInfo);
}
/**
@@ -1502,16 +1509,22 @@
* @see RepositoryService#checkout(SessionInfo, NodeId, NodeId)
*/
public void checkout(SessionInfo sessionInfo, NodeId nodeId, NodeId activityId) throws UnsupportedRepositoryOperationException, LockException, RepositoryException {
- // TODO
- throw new UnsupportedOperationException("JCR-2104: JSR 283 Versioning. Implementation missing");
+ if (activityId == null) {
+ checkout(sessionInfo, nodeId);
+ } else {
+ // TODO
+ throw new UnsupportedOperationException("JCR-2104: JSR 283 Versioning. Implementation missing");
+ }
}
/**
* @see RepositoryService#checkpoint(SessionInfo, NodeId)
*/
public NodeId checkpoint(SessionInfo sessionInfo, NodeId nodeId) throws UnsupportedRepositoryOperationException, RepositoryException {
- // TODO
- throw new UnsupportedOperationException("JCR-2104: JSR 283 Versioning. Implementation missing");
+ // TODO review again.
+ NodeId vID = checkin(sessionInfo, nodeId);
+ checkout(sessionInfo, nodeId);
+ return vID;
}
/**
@@ -1530,9 +1543,49 @@
String uri = getItemUri(nodeId, sessionInfo);
String vUri = getItemUri(versionId, sessionInfo);
- update(uri, new String[] {vUri}, UpdateInfo.UPDATE_BY_VERSION, removeExisting, sessionInfo);
+ Path relPath = null;
+ if (!exists(sessionInfo, uri)) {
+ // restore with rel-Path part
+ Path path = nodeId.getPath();
+ if (nodeId.getUniqueID() != null) {
+ uri = getItemUri(idFactory.createNodeId(nodeId.getUniqueID(), null), sessionInfo);
+ relPath = (path.isAbsolute()) ? getPathFactory().getRootPath().computeRelativePath(path) : path;
+ } else {
+ int degree = 0;
+ while (degree < path.getLength()) {
+ Path ancestorPath = path.getAncestor(degree);
+ NodeId parentId = idFactory.createNodeId(nodeId.getUniqueID(), ancestorPath);
+ if (exists(sessionInfo, getItemUri(parentId, sessionInfo))) {
+ uri = getItemUri(parentId, sessionInfo);
+ relPath = ancestorPath.computeRelativePath(path);
+ break;
+ }
+ degree++;
+ }
+ }
+ }
+
+ update(uri, relPath, new String[] {vUri}, UpdateInfo.UPDATE_BY_VERSION, removeExisting, sessionInfo);
}
+ private boolean exists(SessionInfo sInfo, String uri) {
+ HeadMethod method = new HeadMethod(uri);
+ try {
+ int statusCode = getClient(sInfo).executeMethod(method);
+ if (statusCode == DavServletResponse.SC_OK) {
+ return true;
+ }
+ } catch (IOException e) {
+ log.error("Unexpected error while testing existence of item.",e);
+ } catch (RepositoryException e) {
+ log.error(e.getMessage());
+ } finally {
+ method.releaseConnection();
+ }
+ return false;
+ }
+
+
/**
* @see RepositoryService#restore(SessionInfo, NodeId[], boolean)
*/
@@ -1543,15 +1596,21 @@
vUris[i] = getItemUri(versionIds[i], sessionInfo);
}
- update(uri, vUris, UpdateInfo.UPDATE_BY_VERSION, removeExisting, sessionInfo);
+ update(uri, null, vUris, UpdateInfo.UPDATE_BY_VERSION, removeExisting, sessionInfo);
}
- private void update(String uri, String[] updateSource, int updateType, boolean removeExisting, SessionInfo sessionInfo) throws RepositoryException {
+ private void update(String uri, Path relPath, String[] updateSource, int updateType, boolean removeExisting, SessionInfo sessionInfo) throws RepositoryException {
try {
UpdateInfo uInfo;
- if (removeExisting) {
+ if (removeExisting || relPath != null) {
Element uElem = UpdateInfo.createUpdateElement(updateSource, updateType, domFactory);
- DomUtil.addChildElement(uElem, ItemResourceConstants.XML_REMOVEEXISTING, ItemResourceConstants.NAMESPACE);
+ if (removeExisting) {
+ DomUtil.addChildElement(uElem, ItemResourceConstants.XML_REMOVEEXISTING, ItemResourceConstants.NAMESPACE);
+ }
+ if (relPath != null) {
+ DomUtil.addChildElement(uElem, ItemResourceConstants.XML_RELPATH, ItemResourceConstants.NAMESPACE, getNamePathResolver(sessionInfo).getJCRPath(relPath));
+ }
+
uInfo = new UpdateInfo(uElem);
} else {
uInfo = new UpdateInfo(updateSource, updateType, new DavPropertyNameSet());
@@ -1577,30 +1636,28 @@
* @see RepositoryService#merge(SessionInfo, NodeId, String, boolean, boolean)
*/
public Iterator<NodeId> merge(SessionInfo sessionInfo, NodeId nodeId, String srcWorkspaceName, boolean bestEffort, boolean isShallow) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException {
- if (!isShallow) {
- try {
- String wspHref = uriResolver.getWorkspaceUri(srcWorkspaceName);
- Element mElem = MergeInfo.createMergeElement(new String[] {wspHref}, bestEffort, false, domFactory);
- MergeInfo mInfo = new MergeInfo(mElem);
-
- MergeMethod method = new MergeMethod(getItemUri(nodeId, sessionInfo), mInfo);
- execute(method, sessionInfo);
-
- MultiStatusResponse[] resps = method.getResponseBodyAsMultiStatus().getResponses();
- List<NodeId> failedIds = new ArrayList<NodeId>(resps.length);
- for (MultiStatusResponse resp : resps) {
- String href = resp.getHref();
- failedIds.add(uriResolver.getNodeId(href, sessionInfo));
- }
- return failedIds.iterator();
- } catch (IOException e) {
- throw new RepositoryException(e);
- } catch (DavException e) {
- throw ExceptionConverter.generate(e);
+ try {
+ String wspHref = uriResolver.getWorkspaceUri(srcWorkspaceName);
+ Element mElem = MergeInfo.createMergeElement(new String[] {wspHref}, !bestEffort, false, domFactory);
+ if (isShallow) {
+ mElem.appendChild(DomUtil.depthToXml(false, domFactory));
}
- } else {
- // TODO
- throw new UnsupportedOperationException("JCR-2104: JSR 283 Versioning. Implementation missing");
+ MergeInfo mInfo = new MergeInfo(mElem);
+
+ MergeMethod method = new MergeMethod(getItemUri(nodeId, sessionInfo), mInfo);
+ execute(method, sessionInfo);
+
+ MultiStatusResponse[] resps = method.getResponseBodyAsMultiStatus().getResponses();
+ List<NodeId> failedIds = new ArrayList<NodeId>(resps.length);
+ for (MultiStatusResponse resp : resps) {
+ String href = resp.getHref();
+ failedIds.add(uriResolver.getNodeId(href, sessionInfo));
+ }
+ return failedIds.iterator();
+ } catch (IOException e) {
+ throw new RepositoryException(e);
+ } catch (DavException e) {
+ throw ExceptionConverter.generate(e);
}
}
Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java?rev=916278&r1=916277&r2=916278&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java Thu Feb 25 13:10:45 2010
@@ -137,6 +137,10 @@
}
private Path getPath(ItemId itemId, SessionInfo sessionInfo) throws RepositoryException {
+ return getPath(itemId, sessionInfo, sessionInfo.getWorkspaceName());
+ }
+
+ private Path getPath(ItemId itemId, SessionInfo sessionInfo, String workspaceName) throws RepositoryException {
if (itemId.denotesNode()) {
Path p = itemId.getPath();
String uid = itemId.getUniqueID();
@@ -144,7 +148,7 @@
return p;
} else {
NamePathResolver resolver = getNamePathResolver(sessionInfo);
- String uri = super.getItemUri(itemId, sessionInfo);
+ String uri = super.getItemUri(itemId, sessionInfo, workspaceName);
String rootUri = getRootURI(sessionInfo);
String jcrPath;
if (uri.startsWith(rootUri)) {
@@ -162,7 +166,7 @@
}
} else {
PropertyId pId = (PropertyId) itemId;
- Path parentPath = getPath(pId.getParentId(), sessionInfo);
+ Path parentPath = getPath(pId.getParentId(), sessionInfo, workspaceName);
return getPathFactory().create(parentPath, pId.getName(), true);
}
}
@@ -332,7 +336,7 @@
StringBuffer args = new StringBuffer();
args.append(srcWorkspaceName);
args.append(",");
- args.append(resolver.getJCRPath(getPath(srcNodeId, sessionInfo)));
+ args.append(resolver.getJCRPath(getPath(srcNodeId, sessionInfo, srcWorkspaceName)));
args.append(",");
String destParentPath = resolver.getJCRPath(getPath(destParentNodeId, sessionInfo));
String destPath = (destParentPath.endsWith("/") ?
@@ -366,7 +370,7 @@
StringBuffer args = new StringBuffer();
args.append(srcWorkspaceName);
args.append(",");
- args.append(resolver.getJCRPath(getPath(srcNodeId, sessionInfo)));
+ args.append(resolver.getJCRPath(getPath(srcNodeId, sessionInfo, srcWorkspaceName)));
args.append(",");
String destParentPath = resolver.getJCRPath(getPath(destParentNodeId, sessionInfo));
String destPath = (destParentPath.endsWith("/") ?