pnever 2003/12/05 08:13:05
Modified: src/share/org/apache/slide/content ContentImpl.java
src/webdav/server/org/apache/slide/webdav/method
LockMethod.java PutMethod.java
Log:
Fixed lock-null problems
Revision Changes Path
1.49 +38 -4
jakarta-slide/src/share/org/apache/slide/content/ContentImpl.java
Index: ContentImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/src/share/org/apache/slide/content/ContentImpl.java,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- ContentImpl.java 5 Nov 2003 14:24:37 -0000 1.48
+++ ContentImpl.java 5 Dec 2003 16:13:05 -0000 1.49
@@ -400,6 +400,9 @@
LinkedObjectNotFoundException, ServiceAccessException,
ObjectLockedException {
+ // Check parent exists and is not lock-null
+ checkParentExists(strUri, token);
+
// Retrieve the associated object
ObjectNode associatedObject =
structureHelper.retrieve(token, strUri, false);
@@ -446,6 +449,9 @@
RevisionAlreadyExistException, LinkedObjectNotFoundException,
ServiceAccessException, ObjectLockedException {
+ // Check parent exists and is not lock-null
+ checkParentExists(strUri, token);
+
// Retrieve the associated object
ObjectNode associatedObject =
structureHelper.retrieve(token, strUri, false);
@@ -674,6 +680,9 @@
ObjectLockedException, NodeNotVersionedException,
BranchNotFoundException {
+ // Check parent exists and is not lock-null
+ checkParentExists(strUri, token);
+
Uri objectUri = namespace.getUri(token, strUri);
NodeRevisionDescriptors revisionDescriptors = objectUri.getStore()
@@ -1453,6 +1462,31 @@
return result;
}
+ private boolean isLockNull( NodeRevisionDescriptor nrd ) {
+ return nrd.propertyValueContains("resourcetype", "lock-null");
+ }
+
+ private void checkParentExists(String strUri, SlideToken token)
+ throws ServiceAccessException, ObjectLockedException, AccessDeniedException,
+ LinkedObjectNotFoundException, ObjectNotFoundException {
+
+ if (namespaceConfig.getCreateObjectAction() == ActionNode.DEFAULT) {
+ // do not check during start-up
+ return;
+ }
+
+ String parentUri = String.valueOf(new UriPath(strUri).parent());
+ try {
+ NodeRevisionDescriptor parentNrd =
+ retrieve(token, retrieve(token, parentUri));
+ if (isLockNull(parentNrd)) {
+ throw new ObjectNotFoundException(parentUri);
+ }
+ }
+ catch (RevisionDescriptorNotFoundException e) {
+ throw new ObjectNotFoundException(parentUri);
+ }
+ }
}
1.55 +121 -122
jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/LockMethod.java
Index: LockMethod.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/LockMethod.java,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- LockMethod.java 1 Dec 2003 12:10:50 -0000 1.54
+++ LockMethod.java 5 Dec 2003 16:13:05 -0000 1.55
@@ -76,7 +76,6 @@
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.lock.NodeLock;
import org.apache.slide.lock.ObjectIsAlreadyLockedException;
-import org.apache.slide.structure.ActionNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.structure.SubjectNode;
import org.apache.slide.util.XMLValue;
@@ -96,98 +95,98 @@
*/
public class LockMethod extends AbstractMultistatusResponseMethod
implements WebdavConstants {
-
-
+
+
// -------------------------------------------------------------- Constants
-
-
-
+
+
+
/**
* Create a new lock.
*/
private static final int LOCK_CREATION = 0;
-
-
+
+
/**
* Refresh lock.
*/
private static final int LOCK_REFRESH = 1;
-
+
/**
* Maximum and default timeout.
*/
private static final int MAX_TIMEOUT = Integer.MAX_VALUE;
private static final int DEFAULT_TIMEOUT = MAX_TIMEOUT;
-
+
/**
* The default owner if not explicitely specified by the request.
*/
public static final String DEFAULT_LOCK_OWNER = "";
-
+
// ----------------------------------------------------- Instance Variables
-
-
+
+
/**
* Depth.
*/
private int depth;
-
-
+
+
/**
* Type of the LOCK method.
*/
private int lockType;
-
-
+
+
/**
* Lock duration.
*/
private int lockDuration = DEFAULT_TIMEOUT;
-
-
+
+
/**
* DAV Namespace support.
*/
private boolean davNative;
-
-
+
+
/**
* Lock scope.
*/
private String lockInfo_lockScope;
-
-
+
+
/**
* Lock type.
*/
private String lockInfo_lockType;
-
-
+
+
/**
* Lock owner.
*/
private String lockInfo_lockOwner;
-
-
+
+
/**
* Lock subject.
*/
private String lockInfo_lockSubject;
-
+
/**
* The PropertyHelper used by this instance.
*/
protected PropertyHelper propertyHelper = null;
-
+
/**
* The URL of the server, e.g. <code>http://www.aloha.com:8080</code>
*/
protected String serverURL = null;
-
-
+
+
// ----------------------------------------------------------- Constructors
-
-
+
+
/**
* Constructor.
*
@@ -197,11 +196,11 @@
public LockMethod(NamespaceAccessToken token, WebdavServletConfig config) {
super(token, config);
}
-
-
+
+
// ------------------------------------------------------ Protected Methods
-
-
+
+
/**
* Parse request.
*
@@ -209,36 +208,36 @@
*/
protected void parseRequest()
throws WebdavException {
-
+
propertyHelper = PropertyHelper.getPropertyHelper(slideToken, token,
getConfig());
-// readRequestContent();
-
+ // readRequestContent();
+
serverURL = HTTP_PROTOCOL + req.getServerName()+ ":" + req.getServerPort();
-
+
// Loads the associated object from the store.
lockInfo_lockSubject = requestUri;
if (lockInfo_lockSubject == null) {
lockInfo_lockSubject = "/";
}
-
+
depth = requestHeaders.getDepth(INFINITY);
if (depth != 0 && depth != INFINITY) {
int sc = WebdavStatus.SC_PRECONDITION_FAILED;
sendError( sc, "Invalid header Depth: "+depth );
throw new WebdavException( sc );
}
-
+
lockDuration = requestHeaders.getTimeout(MAX_TIMEOUT);
-
+
if (req.getContentLength() > 0) {
parseLockInfo();
}
else {
lockType = LOCK_REFRESH;
}
-
+
}
-
+
/**
* Parses the <code><lockinfo></code> request content document.
*
@@ -246,9 +245,9 @@
* the request is not valid.
*/
private void parseLockInfo() throws WebdavException {
-
+
lockType = LOCK_CREATION;
-
+
try {
Element lockScopeElement = null;
Element lockTypeElement = null;
@@ -267,7 +266,7 @@
lockOwnerElement = currentElement;
}
}
-
+
parseLockScope(lockScopeElement);
parseLockType(lockTypeElement);
parseOwner(lockOwnerElement);
@@ -283,7 +282,7 @@
throw new WebdavException( statusCode );
}
}
-
+
/**
* Parses the <code><lockscope></code> part of the request content
* document.
@@ -294,19 +293,19 @@
* the request is not valid.
*/
private void parseLockScope(Element lockScopeElement) throws JDOMException {
-
+
if (lockScopeElement == null) {
throw new JDOMException("Expected <"+E_LOCKSCOPE+"> element");
}
-
+
List children = lockScopeElement.getChildren();
if (children.size() != 1) {
throw new JDOMException("<"+E_LOCKSCOPE+"> must have exactly one child
element");
}
-
+
lockInfo_lockScope = ((Element)children.get(0)).getName();
}
-
+
/**
* Parses the <code><locktype></code> part of the request content
* document.
@@ -317,19 +316,19 @@
* the request is not valid.
*/
private void parseLockType(Element lockTypeElement) throws JDOMException {
-
+
if (lockTypeElement == null) {
throw new JDOMException("Expected <"+E_LOCKTYPE+"> element");
}
-
+
List children = lockTypeElement.getChildren();
if (children.size() != 1) {
throw new JDOMException("<"+E_LOCKTYPE+"> must have exactly one child
element");
}
-
+
lockInfo_lockType = ((Element)children.get(0)).getName();
}
-
+
/**
* Parses the <code><owner></code> part of the request content
* document.
@@ -340,13 +339,13 @@
* the request is not valid.
*/
private void parseOwner(Element ownerElement) throws JDOMException {
-
+
if (ownerElement == null) {
lockInfo_lockOwner = DEFAULT_LOCK_OWNER;
return;
// throw new JDOMException("Expected <"+E_OWNER+"> element");
}
-
+
StringWriter stringWriter = new StringWriter();
XMLOutputter xmlOutputter = new XMLOutputter();
try {
@@ -358,14 +357,14 @@
e.printStackTrace();
}
lockInfo_lockOwner = stringWriter.toString();
-
+
if (lockInfo_lockOwner.length() == 0) {
lockInfo_lockOwner = DEFAULT_LOCK_OWNER;
// throw new JDOMException("<"+E_OWNER+"> element must not be
empty");
}
}
-
-
+
+
/**
* Execute request.
*
@@ -373,87 +372,87 @@
*/
protected void executeRequest()
throws WebdavException {
-
+
// Prevent dirty reads
slideToken.setForceStoreEnlistment(true);
-
-
+
+
SubjectNode toLockSubject = null;
boolean isCollection = isCollection(lockInfo_lockSubject);
boolean inheritance = false;
Date lockDate = null;
-
+
switch (lockType) {
-
+
case LOCK_CREATION:
-
+
try {
-
+
NamespaceConfig namespaceConfig = token.getNamespaceConfig();
-
+
try {
toLockSubject = (SubjectNode) structure
.retrieve(slideToken, lockInfo_lockSubject);
} catch (ObjectNotFoundException ex) {
-
+
// Creating a lock null resource
toLockSubject = new SubjectNode();
-
+
// Creating new subject
structure.create(slideToken, toLockSubject,
lockInfo_lockSubject);
-
+
NodeRevisionDescriptor revisionDescriptor =
new NodeRevisionDescriptor(0);
-
+
// Resource type
XMLValue lockNull =
new XMLValue(new Element(E_LOCKNULL, DNSP));
revisionDescriptor.setResourceType(lockNull.toString());
-
+
// Creating the revision descriptor
content.create(slideToken, lockInfo_lockSubject,
revisionDescriptor, null);
-
+
// HACK
// Setting a max timeout when creating a lock-null
// resource because the associated lock-null wouldn't
// be automatically removed when the lock expires
lockDate = new Date((new Date()).getTime()
+ ((long)MAX_TIMEOUT * 1000L));
-
+
}
-
+
NodeLock lockToken = null;
-
+
inheritance = (depth != 0);
boolean exclusive =
!(lockInfo_lockScope.equals(E_SHARED));
-
+
if (lockDate == null)
lockDate = new Date((new Date()).getTime()
+ ((long)lockDuration * 1000L));
-
+
lockToken =
new NodeLock(toLockSubject,
(SubjectNode)security.getPrincipal(slideToken),
namespaceConfig.getCreateObjectAction(),
lockDate, inheritance, exclusive,
lockInfo_lockOwner);
lock.lock(slideToken, lockToken);
-
- // Set the lock-token header
- // [RFC 2518, 9.5] " The Lock-Token response header is used
- // with the LOCK method to indicate the lock token created as
- // a result of a successful LOCK request to create a new
- // lock."
- resp.setHeader("Lock-Token",
- "<"+S_LOCK_TOKEN+lockToken.getLockId()+">");
-
+
+ // Set the lock-token header
+ // [RFC 2518, 9.5] " The Lock-Token response header is used
+ // with the LOCK method to indicate the lock token created as
+ // a result of a successful LOCK request to create a new
+ // lock."
+ resp.setHeader("Lock-Token",
+ "<"+S_LOCK_TOKEN+lockToken.getLockId()+">");
+
resp.setStatus(WebdavStatus.SC_OK);
-
+
// The lock token on which the DAV module will have the info
-
+
showLockDiscoveryInfo(lockToken);
-
+
} catch (ObjectIsAlreadyLockedException e) {
if (inheritance && generateMultiStatusResponse(isCollection, e,
requestUri)) {
// error is on the resource which we attempted to lock
@@ -485,16 +484,16 @@
sendError( statusCode, e );
throw new WebdavException( statusCode );
}
-
+
break;
-
+
case LOCK_REFRESH:
-
+
try {
-
+
Enumeration lockTokens =
lock.enumerateLocks(slideToken, lockInfo_lockSubject,
false);
-
+
NodeLock currentLockToken = null;
Date newExpirationDate =
new Date((new Date()).getTime() + ((long)lockDuration *
1000L));
@@ -503,25 +502,25 @@
lock.renew(slideToken, currentLockToken,
newExpirationDate);
}
-
+
showLockDiscoveryInfo(currentLockToken);
-
+
} catch (SlideException e) {
int statusCode = WebdavStatus.SC_PRECONDITION_FAILED;
sendError( statusCode, e );
throw new WebdavException( statusCode );
}
-
+
break;
-
+
}
-
+
}
-
-
-
-
-
+
+
+
+
+
/**
* Get return status based on exception type.
*/
@@ -534,8 +533,8 @@
return super.getErrorCode(e);
}
}
-
-
+
+
/**
* Show lockdiscovery info.
*
@@ -543,7 +542,7 @@
*/
protected void showLockDiscoveryInfo(NodeLock token)
throws WebdavException {
-
+
// Generating XML response
org.jdom.Element prop = new org.jdom.Element(E_PROP, DNSP);
org.jdom.Element lockdiscovery = new org.jdom.Element(E_LOCKDISCOVERY,
DNSP);
@@ -555,7 +554,7 @@
while (iterator.hasNext()) {
lockdiscovery.addContent((org.jdom.Element)iterator.next());
}
-
+
try {
//System.out.println("Query result");
//System.out.println(generatedXML.toString());
@@ -568,19 +567,19 @@
sendError( statusCode, e );
throw new WebdavException( statusCode );
}
-
-
+
+
}
-
-
+
+
/**
* Returns true
*/
protected boolean methodNeedsTransactionSupport() {
return true;
}
-
-
+
+
}
1.69 +8 -22
jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PutMethod.java
Index: PutMethod.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PutMethod.java,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -r1.68 -r1.69
--- PutMethod.java 4 Dec 2003 17:31:38 -0000 1.68
+++ PutMethod.java 5 Dec 2003 16:13:05 -0000 1.69
@@ -70,7 +70,6 @@
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.SlideException;
import org.apache.slide.common.SlideToken;
-import org.apache.slide.common.UriPath;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.content.NodeRevisionContent;
import org.apache.slide.content.NodeRevisionDescriptor;
@@ -96,7 +95,6 @@
import org.apache.slide.webdav.util.resourcekind.CheckedInVersionControlled;
import org.apache.slide.webdav.util.resourcekind.ResourceKind;
import org.apache.util.WebdavStatus;
-import org.apache.slide.security.AccessDeniedException;
/**
* PUT method.
@@ -330,23 +328,6 @@
sendError( statusCode, e );
throw new WebdavException( statusCode );
} catch (ObjectNotFoundException e) {
- // check parent exists
- UriPath upath = new UriPath(resourcePath);
- try {
- structure.retrieve(slideToken, upath.parent().toString());
- }
- catch (ObjectNotFoundException x) {
- throw new PreconditionViolationException(
- new ViolatedPrecondition("parent-collection-must-exist",
- WebdavStatus.SC_CONFLICT,
- "Parent collection
"+upath.parent().toString()+" not found"),
- resourcePath
- );
- }
- catch (SlideException x) {
- throw x;
- }
-
SubjectNode subject = new SubjectNode();
// Creating an object
structure.create(slideToken, subject, resourcePath);
@@ -449,6 +430,11 @@
catch (PreconditionViolationException e) {
sendPreconditionViolation(e);
throw e;
+ }
+ catch (SlideException e) {
+ int statusCode = getErrorCode( e );
+ sendError( statusCode, e );
+ throw new WebdavException( statusCode );
}
catch (Exception e) {
int statusCode = getErrorCode( e );
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]