dflorey     2004/07/02 05:04:28

  Modified:    src/webdav/server/org/apache/slide/webdav/event
                        Subscriber.java
               src/webdav/server/org/apache/slide/webdav/method
                        UnlockMethod.java LockMethod.java
                        AbstractWebdavMethod.java
               src/webdav/server/org/apache/slide/webdav/util
                        WebdavConstants.java PropertyHelper.java
  Log:
  Preparation of exchange compatible locking
  
  Revision  Changes    Path
  1.8       +10 -5     
jakarta-slide/src/webdav/server/org/apache/slide/webdav/event/Subscriber.java
  
  Index: Subscriber.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/event/Subscriber.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Subscriber.java   12 May 2004 11:09:47 -0000      1.7
  +++ Subscriber.java   2 Jul 2004 12:04:28 -0000       1.8
  @@ -87,7 +87,12 @@
       }
   
       public boolean matches(String type, ResourceEvent event) {
  -     if ( notificationType.equals(type) ) {
  +     // check if event matches notification-type
  +     // see 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wss/wss/_webdav_notification_type_header.asp
  +     // for details
  +     if ( notificationType.equals(type) || 
  +             ( type.equals(NEW_MEMBER) && notificationType.equals(UPDATE) && depth 
== 1 ) || 
  +             ( type.equals(DELETE) && notificationType.equals(UPDATE) && depth == 1 
) ){
                String eventUri = event.getUri();
                if ( eventUri != null && uri != null ) {
                        if ( depth == 0 && eventUri.equals(uri.toString()) ) return 
true;
  
  
  
  1.34      +264 -217  
jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/UnlockMethod.java
  
  Index: UnlockMethod.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/UnlockMethod.java,v
  retrieving revision 1.33
  retrieving revision 1.34
  diff -u -r1.33 -r1.34
  --- UnlockMethod.java 24 Feb 2004 17:03:34 -0000      1.33
  +++ UnlockMethod.java 2 Jul 2004 12:04:28 -0000       1.34
  @@ -39,6 +39,7 @@
   import org.apache.slide.structure.LinkedObjectNotFoundException;
   import org.apache.slide.structure.ObjectNode;
   import org.apache.slide.structure.ObjectNotFoundException;
  +import org.apache.slide.transaction.ExternalTransactionContext;
   import org.apache.slide.util.Configuration;
   import org.apache.slide.webdav.WebdavException;
   import org.apache.slide.webdav.WebdavServletConfig;
  @@ -47,226 +48,272 @@
   import org.apache.slide.webdav.util.PreconditionViolationException;
   import org.apache.slide.webdav.util.VersioningHelper;
   import org.apache.slide.webdav.util.ViolatedPrecondition;
  +import org.apache.slide.webdav.util.WebdavConstants;
   import org.apache.slide.webdav.util.resourcekind.AbstractResourceKind;
   import org.apache.slide.webdav.util.resourcekind.CheckedOutVersionControlled;
   import org.apache.slide.webdav.util.resourcekind.ResourceKind;
   import org.apache.slide.event.EventDispatcher;
   import org.apache.util.WebdavStatus;
  +import org.jdom.Document;
  +import org.jdom.Element;
   
   /**
    * UNLOCK method.
  - *
  - * @author <a href="mailto:[EMAIL PROTECTED]">Remy Maucherat</a>
  + * 
  + * @author <a href="mailto:[EMAIL PROTECTED]">Remy Maucherat </a>
    */
  -public class UnlockMethod extends AbstractWebdavMethod {
  -    
  -    public static final String LOCK_TOKEN_HEADER_MISSING = "Lock-Token header 
missing";
  -    public static final String INVALID_LOCK_TOKEN = "Lock-Token is invalid";
  -    public static final String UNLOCK_NOT_ALLOWED = "Principal is neither the 
lock-owner nor has DAV:unlock privilege";
  -    public static final String IS_NOT_LOCK_ROOT = "Please try to unlock the root of 
the lock: ";
  -    
  -    // ----------------------------------------------------- Instance Variables
  -    
  -    
  -    /**
  -     * Resource to unlock.
  -     */
  -    private String resourcePath;
  -    
  -    
  -    /**
  -     * Id.
  -     */
  -    private String lockId;
  -    
  -    
  -    // ----------------------------------------------------------- Constructors
  -    
  -    
  -    /**
  -     * Constructor.
  -     *
  -     * @param token     the token for accessing the namespace
  -     * @param config    configuration of the WebDAV servlet
  -     */
  -    public UnlockMethod(NamespaceAccessToken token,
  -                        WebdavServletConfig config) {
  -        super(token, config);
  -    }
  -    
  -    
  -    // ------------------------------------------------------ Protected Methods
  -    
  -    
  -    /**
  -     * Parse the request.
  -     *
  -     * @exception WebdavException Bad request
  -     */
  -    protected void parseRequest()
  -        throws WebdavException {
  -        
  -        // Loads the associated object from the store.
  -        resourcePath = requestUri;
  -        if (resourcePath == null) {
  -            resourcePath = "/";
  -        }
  -        
  -        lockId = requestHeaders.getLockToken();
  -        if (lockId == null) {
  -            sendError( WebdavStatus.SC_PRECONDITION_FAILED, 
LOCK_TOKEN_HEADER_MISSING);
  -            throw new WebdavException( WebdavStatus.SC_PRECONDITION_FAILED );
  -        }
  -    }
  -    
  -    
  -    /**
  -     * Execute the request.
  -     *
  -     * @exception WebdavException
  -     */
  -    protected void executeRequest()
  -        throws WebdavException {
  -        
  -        // Prevent dirty reads
  -        slideToken.setForceStoreEnlistment(true);
  -        
  -        try {
  -            if ( WebdavEvent.UNLOCK.isEnabled() ) 
EventDispatcher.getInstance().fireVetoableEvent(WebdavEvent.UNLOCK, new 
WebdavEvent(this));
  -
  -            checkPreconditions();
  -            lock.unlock(slideToken, requestUri, lockId);
  -            
  -            NodeRevisionDescriptors revisionDescriptors =
  -                content.retrieve(slideToken, requestUri);
  -            NodeRevisionDescriptor revisionDescriptor =
  -                content.retrieve(slideToken, revisionDescriptors);
  -            
  -            // Check if resource must be checked in due to auto-versioning
  -            // semantics.
  -            ResourceKind resourceKind = 
AbstractResourceKind.determineResourceKind(token, requestUri, revisionDescriptor);
  -            if( Configuration.useVersionControl() &&
  -                   (resourceKind instanceof CheckedOutVersionControlled) ) {
  -                NodeProperty checkinLocktokenProperty =
  -                    
revisionDescriptor.getProperty(DeltavConstants.I_CHECKIN_LOCKTOKEN,
  -                                                   NamespaceCache.SLIDE_URI);
  -                if (checkinLocktokenProperty == null) {
  -                    // retry with default (DAV:) namespace which was the
  -                    // former namespace of this property
  -                    checkinLocktokenProperty =
  -                        
revisionDescriptor.getProperty(DeltavConstants.I_CHECKIN_LOCKTOKEN);
  -                }
  -                if ( (checkinLocktokenProperty != null) && 
(checkinLocktokenProperty.getValue() != null) &&
  -                    lockId.equals(checkinLocktokenProperty.getValue().toString()) ) 
{
  -                    VersioningHelper versionHelper = 
VersioningHelper.getVersioningHelper(slideToken, token, req, resp, config);
  -                    versionHelper.checkin(revisionDescriptors, revisionDescriptor, 
false, false, true);
  -                }
  -            }
  -            
  -            // Checking if the resource at the URI isn't a lock-null
  -            // resource, in which case we must attempt to delete it
  -            ObjectNode node = structure.retrieve(slideToken, requestUri);
  -            
  -            if (isLockNull(revisionDescriptor)) {
  -                content.remove(slideToken, requestUri, revisionDescriptor);
  -                content.remove(slideToken, revisionDescriptors);
  -                structure.remove(slideToken, node);
  -            }
  -            
  -            resp.setStatus(WebdavStatus.SC_NO_CONTENT);
  -            
  -            }
  -        catch (PreconditionViolationException e) {
  -            try {
  -                sendPreconditionViolation(e);
  -                throw e;
  -            } catch (IOException x) {}
  -            throw new WebdavException(e.getStatusCode());
  -            }
  -        catch (Exception e) {
  -            int statusCode = getErrorCode( e );
  -            sendError(statusCode, e);
  -            throw new WebdavException( statusCode );
  -        }
  -    }
  -    
  -    
  -    
  -    
  -    
  -    /**
  -     * Get return status based on exception type.
  -     */
  -    protected int getErrorCode(Exception ex) {
  -        try {
  -            throw ex;
  -        } catch (RevisionDescriptorNotFoundException e) {
  -            return WebdavStatus.SC_OK;
  -        } catch (LinkedObjectNotFoundException e) {
  -            return WebdavStatus.SC_NOT_FOUND;
  -        } catch (Exception e) {
  -            return super.getErrorCode(e);
  -        }
  -    }
  -    
  -    
  -    
  -    
  -    /**
  -     * Returns true
  -     */
  -    protected boolean methodNeedsTransactionSupport() {
  -        return true;
  -    }
  -    
  -    private void checkPreconditions() throws SlideException {
  -        Enumeration locksAll = lock.enumerateLocks(slideToken, resourcePath, true);
  -        if (!locksAll.hasMoreElements()) {
  -            return;
  -        }
  -        
  -        NodeLock nodeLock = findMatchingNodeLock(false);
  -        
  -        if (nodeLock != null) {
  -            if (!lock.checkLockOwner(slideToken, nodeLock)) {
  -                throw new PreconditionViolationException(
  -                    new ViolatedPrecondition("lock-owner-or-unlock-privilege",
  -                                             WebdavStatus.SC_FORBIDDEN,
  -                                             UNLOCK_NOT_ALLOWED),
  -                    resourcePath
  -                );
  -            }
  -        }
  -        else {
  -            nodeLock = findMatchingNodeLock(true);
  -            if (nodeLock != null) {
  -                throw new PreconditionViolationException(
  -                    new ViolatedPrecondition("lock-root",
  -                                             WebdavStatus.SC_CONFLICT,
  -                                             
IS_NOT_LOCK_ROOT+getFullPath(nodeLock.getObjectUri())),
  -                    resourcePath
  -                );
  -            }
  -            else {
  -                throw new PreconditionViolationException(
  -                    new ViolatedPrecondition("valid-lock-token",
  -                                             WebdavStatus.SC_CONFLICT,
  -                                             INVALID_LOCK_TOKEN),
  -                    resourcePath
  -                );
  -            }
  -        }
  -    }
  -    
  -    private NodeLock findMatchingNodeLock(boolean inherited) throws 
ObjectNotFoundException, LockTokenNotFoundException, ServiceAccessException {
  -        NodeLock nodeLock = null;
  -        Enumeration locks = lock.enumerateLocks(slideToken, resourcePath, 
inherited);
  -        while ( nodeLock == null && locks.hasMoreElements() ) {
  -            NodeLock nl = (NodeLock) locks.nextElement();
  -            if (nl.getLockId().equals(lockId)) {
  -                nodeLock = nl;
  -            }
  -        }
  -        return nodeLock;
  -    }
  -}
  +public class UnlockMethod extends AbstractWebdavMethod implements
  +             WebdavConstants {
  +
  +     public static final String LOCK_TOKEN_HEADER_MISSING = "Lock-Token header 
missing";
  +
  +     public static final String INVALID_LOCK_TOKEN = "Lock-Token is invalid";
  +
  +     public static final String UNLOCK_NOT_ALLOWED = "Principal is neither the 
lock-owner nor has DAV:unlock privilege";
  +
  +     public static final String IS_NOT_LOCK_ROOT = "Please try to unlock the root 
of the lock: ";
  +
  +     public final static int NO_TRANSACTION = 0;
  +
  +     public final static int ABORT_TRANSACTION = 1;
  +
  +     public final static int COMMIT_TRANSACTION = 2;
  +
  +     // ----------------------------------------------------- Instance Variables
  +
  +     /**
  +      * Resource to unlock.
  +      */
  +     private String resourcePath;
  +
  +     /**
  +      * Id.
  +      */
  +     private String lockId;
  +
  +     private int command = NO_TRANSACTION;
  +
  +     // ----------------------------------------------------------- Constructors
  +
  +     /**
  +      * Constructor.
  +      * 
  +      * @param token
  +      *            the token for accessing the namespace
  +      * @param config
  +      *            configuration of the WebDAV servlet
  +      */
  +     public UnlockMethod(NamespaceAccessToken token, WebdavServletConfig config) {
  +             super(token, config);
  +     }
  +
  +     // ------------------------------------------------------ Protected Methods
  +
  +     /**
  +      * Parse the request.
  +      * 
  +      * @exception WebdavException
  +      *                Bad request
  +      */
  +     protected void parseRequest() throws WebdavException {
  +
  +             // Loads the associated object from the store.
  +             resourcePath = requestUri;
  +             if (resourcePath == null) {
  +                     resourcePath = "/";
  +             }
  +
  +             lockId = requestHeaders.getLockToken();
  +             if (lockId == null) {
  +                     sendError(WebdavStatus.SC_PRECONDITION_FAILED,
  +                                     LOCK_TOKEN_HEADER_MISSING);
  +                     throw new WebdavException(WebdavStatus.SC_PRECONDITION_FAILED);
  +             }
  +             try {
  +                     Document requestContent = parseRequestContent();
  +                     if (requestContent != null) {
  +                             Element transactioninfo = 
requestContent.getRootElement();
  +                             if 
(E_TRANSACTIONINFO.equals(transactioninfo.getName())) {
  +                                     Element transactionstatus = transactioninfo
  +                                                     .getChild(E_TRANSACTIONINFO);
  +                                     if (transactionstatus != null) {
  +                                             Element action = (Element) 
transactioninfo
  +                                                             .getChildren().get(0);
  +                                             if (action != null) {
  +                                                     if 
(E_COMMIT.equals(action.getName())) {
  +                                                             command = 
COMMIT_TRANSACTION;
  +                                                     } else if 
(E_COMMIT.equals(action.getName())) {
  +                                                             command = 
ABORT_TRANSACTION;
  +                                                     }
  +                                             }
  +                                     }
  +                             }
  +                     }
  +             } catch (Exception exception) {
  +                     throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
  +             }
  +     }
  +
  +     /**
  +      * Execute the request.
  +      * 
  +      * @exception WebdavException
  +      */
  +     protected void executeRequest() throws WebdavException {
  +
  +             // Prevent dirty reads
  +             slideToken.setForceStoreEnlistment(true);
  +             if (command == COMMIT_TRANSACTION) {
  +                     try {
  +                             token.commit();
  +                             ExternalTransactionContext.deregisterContext(lockId);
  +                     } catch (Exception exception) {
  +                             resp.setStatus(WebdavStatus.SC_METHOD_FAILURE);
  +                     }
  +             } else if (command == ABORT_TRANSACTION) {
  +                     try {
  +                             token.rollback();
  +                             ExternalTransactionContext.deregisterContext(lockId);
  +                     } catch (Exception exception) {
  +                             resp.setStatus(WebdavStatus.SC_METHOD_FAILURE);
  +                     }
  +             } else {
  +                     try {
  +                             if (WebdavEvent.UNLOCK.isEnabled())
  +                                     
EventDispatcher.getInstance().fireVetoableEvent(
  +                                                     WebdavEvent.UNLOCK, new 
WebdavEvent(this));
  +
  +                             checkPreconditions();
  +                             lock.unlock(slideToken, requestUri, lockId);
  +
  +                             NodeRevisionDescriptors revisionDescriptors = 
content.retrieve(
  +                                             slideToken, requestUri);
  +                             NodeRevisionDescriptor revisionDescriptor = 
content.retrieve(
  +                                             slideToken, revisionDescriptors);
  +
  +                             // Check if resource must be checked in due to 
auto-versioning
  +                             // semantics.
  +                             ResourceKind resourceKind = AbstractResourceKind
  +                                             .determineResourceKind(token, 
requestUri,
  +                                                             revisionDescriptor);
  +                             if (Configuration.useVersionControl()
  +                                             && (resourceKind instanceof 
CheckedOutVersionControlled)) {
  +                                     NodeProperty checkinLocktokenProperty = 
revisionDescriptor
  +                                                     
.getProperty(DeltavConstants.I_CHECKIN_LOCKTOKEN,
  +                                                                     
NamespaceCache.SLIDE_URI);
  +                                     if (checkinLocktokenProperty == null) {
  +                                             // retry with default (DAV:) namespace 
which was the
  +                                             // former namespace of this property
  +                                             checkinLocktokenProperty = 
revisionDescriptor
  +                                                             
.getProperty(DeltavConstants.I_CHECKIN_LOCKTOKEN);
  +                                     }
  +                                     if ((checkinLocktokenProperty != null)
  +                                                     && 
(checkinLocktokenProperty.getValue() != null)
  +                                                     && 
lockId.equals(checkinLocktokenProperty
  +                                                                     
.getValue().toString())) {
  +                                             VersioningHelper versionHelper = 
VersioningHelper
  +                                                             
.getVersioningHelper(slideToken, token, req,
  +                                                                             resp, 
config);
  +                                             
versionHelper.checkin(revisionDescriptors,
  +                                                             revisionDescriptor, 
false, false, true);
  +                                     }
  +                             }
  +
  +                             // Checking if the resource at the URI isn't a 
lock-null
  +                             // resource, in which case we must attempt to delete it
  +                             ObjectNode node = structure.retrieve(slideToken, 
requestUri);
  +
  +                             if (isLockNull(revisionDescriptor)) {
  +                                     content.remove(slideToken, requestUri, 
revisionDescriptor);
  +                                     content.remove(slideToken, 
revisionDescriptors);
  +                                     structure.remove(slideToken, node);
  +                             }
  +
  +                             resp.setStatus(WebdavStatus.SC_NO_CONTENT);
  +
  +                     } catch (PreconditionViolationException e) {
  +                             try {
  +                                     sendPreconditionViolation(e);
  +                                     throw e;
  +                             } catch (IOException x) {
  +                             }
  +                             throw new WebdavException(e.getStatusCode());
  +                     } catch (Exception e) {
  +                             int statusCode = getErrorCode(e);
  +                             sendError(statusCode, e);
  +                             throw new WebdavException(statusCode);
  +                     }
  +             }
  +     }
  +
  +     /**
  +      * Get return status based on exception type.
  +      */
  +     protected int getErrorCode(Exception ex) {
  +             try {
  +                     throw ex;
  +             } catch (RevisionDescriptorNotFoundException e) {
  +                     return WebdavStatus.SC_OK;
  +             } catch (LinkedObjectNotFoundException e) {
  +                     return WebdavStatus.SC_NOT_FOUND;
  +             } catch (Exception e) {
  +                     return super.getErrorCode(e);
  +             }
  +     }
  +
  +     /**
  +      * Returns true
  +      */
  +     protected boolean methodNeedsTransactionSupport() {
  +             return true;
  +     }
  +
  +     private void checkPreconditions() throws SlideException {
  +             Enumeration locksAll = lock.enumerateLocks(slideToken, resourcePath,
  +                             true);
  +             if (!locksAll.hasMoreElements()) {
  +                     return;
  +             }
  +
  +             NodeLock nodeLock = findMatchingNodeLock(false);
  +
  +             if (nodeLock != null) {
  +                     if (!lock.checkLockOwner(slideToken, nodeLock)) {
  +                             throw new PreconditionViolationException(
  +                                             new ViolatedPrecondition(
  +                                                             
"lock-owner-or-unlock-privilege",
  +                                                             
WebdavStatus.SC_FORBIDDEN, UNLOCK_NOT_ALLOWED),
  +                                             resourcePath);
  +                     }
  +             } else {
  +                     nodeLock = findMatchingNodeLock(true);
  +                     if (nodeLock != null) {
  +                             throw new PreconditionViolationException(
  +                                             new ViolatedPrecondition("lock-root",
  +                                                             
WebdavStatus.SC_CONFLICT, IS_NOT_LOCK_ROOT
  +                                                                             + 
getFullPath(nodeLock.getObjectUri())),
  +                                             resourcePath);
  +                     } else {
  +                             throw new PreconditionViolationException(
  +                                             new 
ViolatedPrecondition("valid-lock-token",
  +                                                             
WebdavStatus.SC_CONFLICT, INVALID_LOCK_TOKEN),
  +                                             resourcePath);
  +                     }
  +             }
  +     }
  +
  +     private NodeLock findMatchingNodeLock(boolean inherited)
  +                     throws ObjectNotFoundException, LockTokenNotFoundException,
  +                     ServiceAccessException {
  +             NodeLock nodeLock = null;
  +             Enumeration locks = lock.enumerateLocks(slideToken, resourcePath,
  +                             inherited);
  +             while (nodeLock == null && locks.hasMoreElements()) {
  +                     NodeLock nl = (NodeLock) locks.nextElement();
  +                     if (nl.getLockId().equals(lockId)) {
  +                             nodeLock = nl;
  +                     }
  +             }
  +             return nodeLock;
  +     }
  +}
  \ No newline at end of file
  
  
  
  1.63      +482 -466  
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.62
  retrieving revision 1.63
  diff -u -r1.62 -r1.63
  --- LockMethod.java   21 Jun 2004 08:52:47 -0000      1.62
  +++ LockMethod.java   2 Jul 2004 12:04:28 -0000       1.63
  @@ -30,6 +30,9 @@
   import java.util.Enumeration;
   import java.util.Iterator;
   import java.util.List;
  +
  +import javax.transaction.Transaction;
  +
   import org.apache.slide.common.NamespaceAccessToken;
   import org.apache.slide.common.NamespaceConfig;
   import org.apache.slide.common.SlideException;
  @@ -38,6 +41,7 @@
   import org.apache.slide.lock.ObjectIsAlreadyLockedException;
   import org.apache.slide.structure.ObjectNotFoundException;
   import org.apache.slide.structure.SubjectNode;
  +import org.apache.slide.transaction.ExternalTransactionContext;
   import org.apache.slide.util.XMLValue;
   import org.apache.slide.webdav.WebdavException;
   import org.apache.slide.webdav.WebdavServletConfig;
  @@ -50,469 +54,481 @@
   
   /**
    * LOCK method.
  - *
  - * @author <a href="mailto:[EMAIL PROTECTED]">Remy Maucherat</a>
  + * 
  + * @author <a href="mailto:[EMAIL PROTECTED]">Remy Maucherat </a>
    */
  -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 ([EMAIL PROTECTED] #LOCK_CREATION} or [EMAIL 
PROTECTED] #LOCK_REFRESH}).
  -     */
  -    private int lockType;
  -    
  -    /**
  -     * Lock duration.
  -     */
  -    private int lockDuration = DEFAULT_TIMEOUT;
  -    
  -    /**
  -     * Lock scope.
  -     */
  -    private String lockInfo_lockScope;
  -    
  -    /*
  -     * Lock type.
  -     * Never used, because currently only write locks are known.
  -     */
  -    //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;
  -        
  -    
  -    // ----------------------------------------------------------- Constructors
  -    
  -    /**
  -     * Constructor.
  -     *
  -     * @param token     the token for accessing the namespace
  -     * @param config    configuration of the WebDAV servlet
  -     */
  -    public LockMethod(NamespaceAccessToken token, WebdavServletConfig config) {
  -        super(token, config);
  -    }
  -    
  -    
  -    // ------------------------------------------------------ Protected Methods
  -    
  -    
  -    /**
  -     * Parse request.
  -     *
  -     * @exception WebdavException Does not happen
  -     */
  -    protected void parseRequest()
  -        throws WebdavException {
  -        
  -        propertyHelper = PropertyHelper.getPropertyHelper(slideToken, token, 
getConfig());
  -        //        readRequestContent();
  -        
  -        
  -        // 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>&lt;lockinfo&gt;</code> request content document.
  -     *
  -     * @throws     WebdavException  if parsing the request failed or if
  -     *                              the request is not valid.
  -     */
  -    private void parseLockInfo() throws WebdavException {
  -        
  -        lockType = LOCK_CREATION;
  -        
  -        try {
  -            Iterator childrenIterator = parseRequestContent(E_LOCKINFO)
  -                                                     .getChildren().iterator();
  -            while (childrenIterator.hasNext()) {
  -                Element currentElement = (Element)childrenIterator.next();
  -                if (E_LOCKSCOPE.equals(currentElement.getName())) {
  -                    parseLockScope(currentElement);
  -                }
  -                else if (E_LOCKTYPE.equals(currentElement.getName())) {
  -                    parseLockType(currentElement);
  -                }
  -                else if (E_OWNER.equals(currentElement.getName())) {
  -                   parseOwner(currentElement);
  -                }
  -            }
  -        }
  -        catch (JDOMException e) {
  -            int statusCode = WebdavStatus.SC_BAD_REQUEST;
  -            sendError( statusCode, e );
  -            throw new WebdavException( statusCode );
  -        }
  -        catch (IOException e) {
  -            int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR;
  -            sendError( statusCode, e );
  -            throw new WebdavException( statusCode );
  -        }
  -    }
  -    
  -    /**
  -     * Parses the <code>&lt;lockscope&gt;</code> part of the request content
  -     * document.
  -     *
  -     * @param      lockScopeElement  the <code>&lt;lockscope&gt;</code> to parse.
  -     *
  -     * @throws     JDOMException  if parsing the request failed or if
  -     *                           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();
  -        if (!(E_EXCLUSIVE.equals(lockInfo_lockScope)  
  -            || E_SHARED.equals(lockInfo_lockScope))) 
  -        {
  -           throw new JDOMException("<"+E_LOCKSCOPE+"> can only contain one of <" +
  -               E_EXCLUSIVE + "> or <" + E_SHARED + ">");
  -        }
  -    }
  -    
  -    /**
  -     * Parses the <code>&lt;locktype&gt;</code> part of the request content
  -     * document.
  -     *
  -     * @param      lockTypeElement  the <code>&lt;locktype&gt;</code> to parse.
  -     *
  -     * @throws     JDOMException  if parsing the request failed or if
  -     *                           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");
  -        }
  -        
  -        if (!((Element)children.get(0)).getName().equals(E_WRITE)) {
  -            throw new JDOMException("Only write locks are supported");
  -        }
  -        //lockInfo_lockType = ((Element)children.get(0)).getName();
  -    }
  -    
  -    /**
  -     * Parses the <code>&lt;owner&gt;</code> part of the request content
  -     * document.
  -     *
  -     * @param      ownerElement  the <code>&lt;owner&gt;</code> to parse.
  -     *
  -     * @throws     JDOMException  if parsing the request failed or if
  -     *                           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 {
  -            xmlOutputter.outputElementContent(ownerElement, stringWriter);
  -        }
  -        catch (IOException e) {
  -            // this should not happen since we do no "real" I/O but
  -            // only print to a PrintWriter
  -            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.
  -     *
  -     * @exception WebdavException Unrecoverable error while renewing lock
  -     */
  -    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);
  -                    }
  -                    
  -                    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()+">");
  -                    
  -                    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
  -                        String errorMessage = generateErrorMessage(e);
  -                        // Write it on the servlet writer
  -                        resp.setContentType(TEXT_XML_UTF_8);
  -                        resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
  -                        try {
  -                            resp.getWriter().write(errorMessage);
  -                        } catch(IOException ex) {
  -                            // Critical error ... Servlet container is dead or 
something
  -                            int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR;
  -                            sendError( statusCode, e );
  -                            throw new WebdavException( statusCode );
  -                        }
  -                    } else {
  -                        // Returning 207 on non-collection requests is generally
  -                        // considered bad. So let's not do it, since this way
  -                        // makes clients generally behave better.
  -                        resp.setStatus(WebdavStatus.SC_LOCKED);
  -                    }
  -                    //
  -                    // make sure the transaction is aborted
  -                    // throw any WebDAV exception to indicate the transaction wants 
to be aborted
  -                    //
  -                    throw new WebdavException(WebdavStatus.SC_ACCEPTED, false);
  -                } catch (Exception e) {
  -                    int statusCode = getErrorCode( e );
  -                    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));
  -                    while (lockTokens.hasMoreElements()) {
  -                        currentLockToken = (NodeLock) lockTokens.nextElement();
  -                        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.
  -     */
  -    protected int getErrorCode(Exception ex) {
  -        try {
  -            throw ex;
  -        } catch (ObjectNotFoundException e) {
  -            return WebdavStatus.SC_PRECONDITION_FAILED;
  -        } catch (Exception e) {
  -            return super.getErrorCode(e);
  -        }
  -    }
  -    
  -    
  -    /**
  -     * Show lockdiscovery info.
  -     *
  -     * @exception WebdavException Something is wrong with the servlet container
  -     */
  -    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);
  -        prop.addContent(lockdiscovery);
  -        XMLValue xmlValue = propertyHelper.computeLockDiscovery(token,
  -                                                                
getSlideContextPath());
  -        Iterator iterator = xmlValue.iterator();
  -        while (iterator.hasNext()) {
  -            lockdiscovery.addContent((org.jdom.Element)iterator.next());
  -        }
  -        
  -        try {
  -            //System.out.println("Query result");
  -            //System.out.println(generatedXML.toString());
  -            resp.setContentType(TEXT_XML_UTF_8);
  -            Writer writer = resp.getWriter();
  -            org.jdom.output.Format format = 
org.jdom.output.Format.getPrettyFormat();
  -            format.setIndent(XML_RESPONSE_INDENT);
  -            new org.jdom.output.XMLOutputter(format).output(new 
org.jdom.Document(prop), writer);
  -            writer.flush();
  -        } catch (Exception e) {
  -            int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR;
  -            sendError( statusCode, e );
  -            throw new WebdavException( statusCode );
  -        }
  -        
  -        
  -    }
  -    
  -    
  -    /**
  -     * Returns true
  -     */
  -    protected boolean methodNeedsTransactionSupport() {
  -        return true;
  -    }
  -    
  -    
  -}
  +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 ([EMAIL PROTECTED] #LOCK_CREATION}or [EMAIL 
PROTECTED] #LOCK_REFRESH}).
  +      */
  +     private int lockType;
  +
  +     /**
  +      * Lock duration.
  +      */
  +     private int lockDuration = DEFAULT_TIMEOUT;
  +
  +     /**
  +      * 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;
  +
  +     // ----------------------------------------------------------- Constructors
  +
  +     /**
  +      * Constructor.
  +      * 
  +      * @param token
  +      *            the token for accessing the namespace
  +      * @param config
  +      *            configuration of the WebDAV servlet
  +      */
  +     public LockMethod(NamespaceAccessToken token, WebdavServletConfig config) {
  +             super(token, config);
  +     }
  +
  +     // ------------------------------------------------------ Protected Methods
  +
  +     /**
  +      * Parse request.
  +      * 
  +      * @exception WebdavException
  +      *                Does not happen
  +      */
  +     protected void parseRequest() throws WebdavException {
  +
  +             propertyHelper = PropertyHelper.getPropertyHelper(slideToken, token,
  +                             getConfig());
  +             //        readRequestContent();
  +
  +             // 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>&lt;lockinfo&gt;</code> request content document.
  +      * 
  +      * @throws WebdavException
  +      *             if parsing the request failed or if the request is not valid.
  +      */
  +     private void parseLockInfo() throws WebdavException {
  +
  +             lockType = LOCK_CREATION;
  +
  +             try {
  +                     Iterator childrenIterator = parseRequestContent(E_LOCKINFO)
  +                                     .getChildren().iterator();
  +                     while (childrenIterator.hasNext()) {
  +                             Element currentElement = (Element) 
childrenIterator.next();
  +                             if (E_LOCKSCOPE.equals(currentElement.getName())) {
  +                                     parseLockScope(currentElement);
  +                             } else if 
(E_LOCKTYPE.equals(currentElement.getName())) {
  +                                     parseLockType(currentElement);
  +                             } else if (E_OWNER.equals(currentElement.getName())) {
  +                                     parseOwner(currentElement);
  +                             }
  +                     }
  +             } catch (JDOMException e) {
  +                     int statusCode = WebdavStatus.SC_BAD_REQUEST;
  +                     sendError(statusCode, e);
  +                     throw new WebdavException(statusCode);
  +             } catch (IOException e) {
  +                     int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR;
  +                     sendError(statusCode, e);
  +                     throw new WebdavException(statusCode);
  +             }
  +     }
  +
  +     /**
  +      * Parses the <code>&lt;lockscope&gt;</code> part of the request content
  +      * document.
  +      * 
  +      * @param lockScopeElement
  +      *            the <code>&lt;lockscope&gt;</code> to parse.
  +      * 
  +      * @throws JDOMException
  +      *             if parsing the request failed or if 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();
  +             if (!(E_EXCLUSIVE.equals(lockInfo_lockScope)
  +                             || E_SHARED.equals(lockInfo_lockScope) || E_LOCAL
  +                             .equals(lockInfo_lockScope))) {
  +                     throw new JDOMException("<" + E_LOCKSCOPE
  +                                     + "> can only contain one of <" + E_EXCLUSIVE 
+ "> or <"
  +                                     + E_SHARED + "> or <" + E_LOCAL + ">");
  +             }
  +     }
  +
  +     /**
  +      * Parses the <code>&lt;locktype&gt;</code> part of the request content
  +      * document.
  +      * 
  +      * @param lockTypeElement
  +      *            the <code>&lt;locktype&gt;</code> to parse.
  +      * 
  +      * @throws JDOMException
  +      *             if parsing the request failed or if 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");
  +             }
  +             String lockTypeName = ((Element) children.get(0)).getName();
  +             if (!E_WRITE.equals(lockTypeName)
  +                             && !E_TRANSACTION.equals(lockTypeName)) {
  +                     throw new JDOMException(
  +                                     "Only write and transaction locks are 
supported");
  +             }
  +             lockInfo_lockType = ((Element) children.get(0)).getName();
  +     }
  +
  +     /**
  +      * Parses the <code>&lt;owner&gt;</code> part of the request content
  +      * document.
  +      * 
  +      * @param ownerElement
  +      *            the <code>&lt;owner&gt;</code> to parse.
  +      * 
  +      * @throws JDOMException
  +      *             if parsing the request failed or if 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 {
  +                     xmlOutputter.outputElementContent(ownerElement, stringWriter);
  +             } catch (IOException e) {
  +                     // this should not happen since we do no "real" I/O but
  +                     // only print to a PrintWriter
  +                     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.
  +      * 
  +      * @exception WebdavException
  +      *                Unrecoverable error while renewing lock
  +      */
  +     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:
  +                     if (lockInfo_lockType.equals(E_TRANSACTION)) {
  +                             try {
  +                                     NamespaceConfig namespaceConfig = token
  +                                     .getNamespaceConfig();
  +                                     NodeLock lockToken = new 
NodeLock(toLockSubject.getUri(),((SubjectNode)security.getPrincipal(slideToken)).getUri(),
  +                                                     
namespaceConfig.getCreateObjectAction().getUri(), lockDate,
  +                                                     inheritance, NodeLock.LOCAL, 
lockInfo_lockOwner);
  +                                     Transaction transaction = 
token.getTransactionManager()
  +                                                     .suspend();
  +                                     Object txId = lockToken.getLockId();
  +                                     
ExternalTransactionContext.registerContext(txId,
  +                                                     transaction);
  +                                     slideToken.setExternalTx();
  +                                     showLockDiscoveryInfo(lockToken);
  +                             } catch (Exception e) {
  +                                     int statusCode = getErrorCode(e);
  +                                     sendError(statusCode, e);
  +                                     throw new WebdavException(statusCode);
  +                             }
  +                     } else if (lockInfo_lockType.equals(E_WRITE)) {
  +                             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);
  +                                     }
  +
  +                                     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() + ">");
  +
  +                                     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
  +                                             String errorMessage = 
generateErrorMessage(e);
  +                                             // Write it on the servlet writer
  +                                             resp.setContentType(TEXT_XML_UTF_8);
  +                                             
resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
  +                                             try {
  +                                                     
resp.getWriter().write(errorMessage);
  +                                             } catch (IOException ex) {
  +                                                     // Critical error ... Servlet 
container is dead or
  +                                                     // something
  +                                                     int statusCode = 
WebdavStatus.SC_INTERNAL_SERVER_ERROR;
  +                                                     sendError(statusCode, e);
  +                                                     throw new 
WebdavException(statusCode);
  +                                             }
  +                                     } else {
  +                                             // Returning 207 on non-collection 
requests is generally
  +                                             // considered bad. So let's not do it, 
since this way
  +                                             // makes clients generally behave 
better.
  +                                             resp.setStatus(WebdavStatus.SC_LOCKED);
  +                                     }
  +                                     //
  +                                     // make sure the transaction is aborted
  +                                     // throw any WebDAV exception to indicate the 
transaction
  +                                     // wants to be aborted
  +                                     //
  +                                     throw new 
WebdavException(WebdavStatus.SC_ACCEPTED, false);
  +                             } catch (Exception e) {
  +                                     int statusCode = getErrorCode(e);
  +                                     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));
  +                             while (lockTokens.hasMoreElements()) {
  +                                     currentLockToken = (NodeLock) 
lockTokens.nextElement();
  +                                     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.
  +      */
  +     protected int getErrorCode(Exception ex) {
  +             try {
  +                     throw ex;
  +             } catch (ObjectNotFoundException e) {
  +                     return WebdavStatus.SC_PRECONDITION_FAILED;
  +             } catch (Exception e) {
  +                     return super.getErrorCode(e);
  +             }
  +     }
  +
  +     /**
  +      * Show lockdiscovery info.
  +      * 
  +      * @exception WebdavException
  +      *                Something is wrong with the servlet container
  +      */
  +     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);
  +             prop.addContent(lockdiscovery);
  +             XMLValue xmlValue = propertyHelper.computeLockDiscovery(token,
  +                             getSlideContextPath());
  +             Iterator iterator = xmlValue.iterator();
  +             while (iterator.hasNext()) {
  +                     lockdiscovery.addContent((org.jdom.Element) iterator.next());
  +             }
  +
  +             try {
  +                     //System.out.println("Query result");
  +                     //System.out.println(generatedXML.toString());
  +                     resp.setContentType(TEXT_XML_UTF_8);
  +                     Writer writer = resp.getWriter();
  +                     org.jdom.output.Format format = org.jdom.output.Format
  +                                     .getPrettyFormat();
  +                     format.setIndent(XML_RESPONSE_INDENT);
  +                     new org.jdom.output.XMLOutputter(format).output(
  +                                     new org.jdom.Document(prop), writer);
  +                     writer.flush();
  +             } catch (Exception e) {
  +                     int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR;
  +                     sendError(statusCode, e);
  +                     throw new WebdavException(statusCode);
  +             }
  +
  +     }
  +
  +     /**
  +      * Returns true
  +      */
  +     protected boolean methodNeedsTransactionSupport() {
  +             return true;
  +     }
  +
  +}
   
  
  
  
  1.34      +4 -4      
jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/AbstractWebdavMethod.java
  
  Index: AbstractWebdavMethod.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/AbstractWebdavMethod.java,v
  retrieving revision 1.33
  retrieving revision 1.34
  diff -u -r1.33 -r1.34
  --- AbstractWebdavMethod.java 28 Jun 2004 16:32:08 -0000      1.33
  +++ AbstractWebdavMethod.java 2 Jul 2004 12:04:28 -0000       1.34
  @@ -1479,7 +1479,7 @@
   
           protected void parse() {
               // TramsactionId header
  -            hTxIdStr = req.getHeader(H_TRANSACTION_ID);
  +            hTxIdStr = req.getHeader(H_TRANSACTION);
               if (hTxIdStr != null) {
                   stTxId = ST_DEFINED;
                   try {
  
  
  
  1.21      +11 -3     
jakarta-slide/src/webdav/server/org/apache/slide/webdav/util/WebdavConstants.java
  
  Index: WebdavConstants.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/util/WebdavConstants.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- WebdavConstants.java      11 Feb 2004 11:30:35 -0000      1.20
  +++ WebdavConstants.java      2 Jul 2004 12:04:28 -0000       1.21
  @@ -69,18 +69,23 @@
       String H_OVERWRITE            = "Overwrite";
       String H_STATUS_URI           = "Status-URI";
       String H_TIMEOUT              = "Timeout";
  +    String H_TRANSACTION          = "Transaction";
   
       /** XML Elements */
  +    String E_ABORT                = "abort";
       String E_ACTIVELOCK           = "activelock";
       String E_ALLPROP              = "allprop";
  +    String E_COMMIT               = "commit";
       String E_COLLECTION           = "collection";
       String E_DEPTH                = "depth";
       String E_DST                  = "dst";
       String E_EXCLUSIVE            = "exclusive";
       String E_ERROR                = "error";
  +    String E_GROUPOPERATION       = "groupoperation";
       String E_HREF                 = "href";
       String E_KEEPALIVE            = "keepalive";
       String E_LINK                 = "link";
  +    String E_LOCAL                = "local";
       String E_LOCKDISCOVERY        = "lockdiscovery";
       String E_LOCKENTRY            = "lockentry";
       String E_LOCKINFO             = "lockinfo";
  @@ -106,6 +111,9 @@
       String E_SRC                  = "src";
       String E_STATUS               = "status";
       String E_TIMEOUT              = "timeout";
  +    String E_TRANSACTION          = "transaction";
  +    String E_TRANSACTIONINFO      = "transactioninfo";
  +    String E_TRANSACTIONSTATUS    = "transactionstatus";
       String E_WRITE                = "write";
   
       /** Live Properties */
  
  
  
  1.73      +15 -6     
jakarta-slide/src/webdav/server/org/apache/slide/webdav/util/PropertyHelper.java
  
  Index: PropertyHelper.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/util/PropertyHelper.java,v
  retrieving revision 1.72
  retrieving revision 1.73
  diff -u -r1.72 -r1.73
  --- PropertyHelper.java       24 Jun 2004 13:18:52 -0000      1.72
  +++ PropertyHelper.java       2 Jul 2004 12:04:28 -0000       1.73
  @@ -1380,15 +1380,24 @@
               activelock = new Element(E_ACTIVELOCK, DNSP);
               Element locktype = new Element(E_LOCKTYPE, DNSP);
               activelock.addContent(locktype);
  -            Element write = new Element(E_WRITE, DNSP);
  -            locktype.addContent(write);
  +            if (objectLockToken.isLocal()) {
  +                Element transaction = new Element(E_TRANSACTION, DNSP);
  +                Element groupoperation = new Element(E_GROUPOPERATION, DNSP);
  +                transaction.addContent(groupoperation);
  +                locktype.addContent(transaction);
  +            } else {
  +             Element write = new Element(E_WRITE, DNSP);
  +             locktype.addContent(write);
  +            }
               Element lockscope = new Element(E_LOCKSCOPE, DNSP);
               activelock.addContent(lockscope);
               Element lockscopeValue = null;
               if (objectLockToken.isExclusive()) {
                   lockscopeValue = new Element(E_EXCLUSIVE, DNSP);
  -            } else {
  +            } else if (objectLockToken.isExclusive()) {
                   lockscopeValue = new Element(E_SHARED, DNSP);
  +            } else if (objectLockToken.isLocal()) {
  +                lockscopeValue = new Element(E_LOCAL, DNSP);
               }
               lockscope.addContent(lockscopeValue);
               Element depth = new Element(E_DEPTH, DNSP);
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to