Package org.apache.slide.webdav.method

Source Code of org.apache.slide.webdav.method.LockMethod

/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/LockMethod.java,v 1.19 2001/08/01 16:30:58 cmlenz Exp $
* $Revision: 1.19 $
* $Date: 2001/08/01 16:30:58 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution, if
*    any, must include the following acknowlegement:
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowlegement may appear in the software itself,
*    if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
*    Foundation" must not be used to endorse or promote products derived
*    from this software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
*    nor may "Apache" appear in their names without prior written
*    permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/

package org.apache.slide.webdav.method;

import java.security.Principal;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.*;
import org.xml.sax.SAXException;

import org.apache.util.XMLPrinter;
import org.apache.util.DOMWriter;
import org.apache.util.WebdavStatus;
import org.apache.slide.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.macro.*;
import org.apache.slide.lock.*;
import org.apache.slide.content.*;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.structure.*;

/**
* LOCK method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class LockMethod extends AbstractMultistatusResponseMethod {
   
   
    // -------------------------------------------------------------- Constants
   
   
    /**
     * Default depth is infite.
     */
    private static final int INFINITY = -1;
   
   
    /**
     * Create a new lock.
     */
    private static final int LOCK_CREATION = 0;
   
   
    /**
     * Refresh lock.
     */
    private static final int LOCK_REFRESH = 1;
   
   
    /**
     * Default timeout value.
     */
    private static final int DEFAULT_TIMEOUT = 3600;
   
   
    /**
     * Maximum timeout.
     */
    private static final int MAX_TIMEOUT = 604800;
   
   
    // ----------------------------------------------------- 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;
   
   
    // ----------------------------------------------------------- Constructors
   
   
    /**
     * LOCK method constructor.
     *
     * @param token Namespace access token
     * @param requestUri Request URI
     * @param principal Principal object, given by the servlet container
     * @param req HTTP request
     * @param resp HTTP response
     */
    public LockMethod(NamespaceAccessToken token, HttpServletRequest req,
                      HttpServletResponse resp, WebdavServletConfig config) {
        super(token, req, resp, config);
        readRequestContent();
    }
   
   
    // ------------------------------------------------------ Protected Methods
   
   
    /**
     * Parse request.
     *
     * @exception WebdavException Does not happen
     */
    protected void parseRequest()
        throws WebdavException {
       
        // Loads the associated object from the store.
        lockInfo_lockSubject = requestUri;
        if (lockInfo_lockSubject == null) {
            lockInfo_lockSubject = "/";
        }
       
        String depthStr = req.getHeader("Depth");
   
        if (depthStr == null) {
            depth = INFINITY;
        } else {
            if (depthStr.equals("0")) {
                depth = 0;
            } else {
                depth = INFINITY;
            }
        }
       
        String lockDurationStr = req.getHeader("Timeout");
        if (lockDurationStr != null) {
            if (lockDurationStr.startsWith("Second-")) {
                lockDuration =
                    (new Integer(lockDurationStr.substring(7))).intValue();
            } else {
                if (lockDurationStr.equalsIgnoreCase("infinity")) {
                    lockDuration = MAX_TIMEOUT;
                } else {
                    try {
                        lockDuration =
                            (new Integer(lockDurationStr)).intValue();
                    } catch (NumberFormatException e) {
                        lockDuration = MAX_TIMEOUT;
                    }
                }
            }
            if (lockDuration > MAX_TIMEOUT) {
                lockDuration = MAX_TIMEOUT;
            }
        }
       
        if (req.getContentLength() > 0) {
           
            lockType = LOCK_CREATION;
           
            Node lockInfoNode = null;
           
            try {
                Document document = parseRequestContent();
               
                // Get the root element of the document
                Element rootElement = document.getDocumentElement();
                lockInfoNode = rootElement;
            } catch (SAXException e) {
                resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
                throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
            } catch (ParserConfigurationException e) {
                System.err.println(e.getMessage());
                resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
                throw new WebdavException
                    (WebdavStatus.SC_INTERNAL_SERVER_ERROR);
            } catch (IOException e) {
                System.err.println(e.getMessage());
                e.printStackTrace();
                resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
                throw new WebdavException
                    (WebdavStatus.SC_INTERNAL_SERVER_ERROR);
            }
           
            NodeList childList = lockInfoNode.getChildNodes();
            StringWriter strWriter = null;
            DOMWriter domWriter = null;
           
            Node lockScopeNode = null;
            Node lockTypeNode = null;
            Node lockOwnerNode = null;
           
            for (int i=0; i < childList.getLength(); i++) {
                Node currentNode = childList.item(i);
                switch (currentNode.getNodeType()) {
                case Node.TEXT_NODE:
                    break;
                case Node.ELEMENT_NODE:
                    String nodeName = currentNode.getNodeName();
                    if (nodeName.endsWith("lockscope")) {
                        lockScopeNode = currentNode;
                    }
                    if (nodeName.endsWith("locktype")) {
                        lockTypeNode = currentNode;
                    }
                    if (nodeName.endsWith("owner")) {
                        lockOwnerNode = currentNode;
                    }
                    break;
                }
            }
           
            if (lockScopeNode != null) {
               
                childList = lockScopeNode.getChildNodes();
                for (int i=0; i < childList.getLength(); i++) {
                    Node currentNode = childList.item(i);
                    switch (currentNode.getNodeType()) {
                    case Node.TEXT_NODE:
                        break;
                    case Node.ELEMENT_NODE:
                        String tempScope = currentNode.getNodeName();
                        if (tempScope.indexOf(':') != -1) {
                            lockInfo_lockScope = "<"
                                + tempScope.substring(tempScope.indexOf(':')
                                                      + 1) + "/>";
                        } else {
                            lockInfo_lockScope = "<" + tempScope + "/>";
                        }
//System.out.println("Lock scope : " + lockInfo_lockScope);
                        break;
                    }
                }
               
                if (lockInfo_lockScope == null) {
                    // Bad request
                    resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
                }
               
            } else {
                // Bad request
                resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
            }
           
            if (lockTypeNode != null) {
               
                childList = lockTypeNode.getChildNodes();
                for (int i=0; i < childList.getLength(); i++) {
                    Node currentNode = childList.item(i);
                    switch (currentNode.getNodeType()) {
                    case Node.TEXT_NODE:
                        break;
                    case Node.ELEMENT_NODE:
                        String tempType = currentNode.getNodeName();
                        if (tempType.indexOf(':') != -1) {
                            lockInfo_lockType = "<"
                                + tempType.substring(tempType.indexOf(':') + 1)
                                + "/>";
                        } else {
                            lockInfo_lockType = "<" + tempType + "/>";
                        }
//System.out.println("Lock type : " + lockInfo_lockType);
                        break;
                    }
                }
               
                if (lockInfo_lockType == null) {
                    // Bad request
                    resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
                }
               
            } else {
                // Bad request
                resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
            }
           
            if (lockOwnerNode != null) {
               
                childList = lockOwnerNode.getChildNodes();
                for (int i=0; i < childList.getLength(); i++) {
                    Node currentNode = childList.item(i);
                    switch (currentNode.getNodeType()) {
                    case Node.TEXT_NODE:
                        break;
                    case Node.ELEMENT_NODE:
                        strWriter = new StringWriter();
                        domWriter = new DOMWriter(strWriter, true);
                        domWriter.print(currentNode);
                        lockInfo_lockOwner = strWriter.toString();
//System.out.println("Lock owner : " + lockInfo_lockOwner);
                        break;
                    }
                }
               
                if (lockInfo_lockScope == null) {
                    // Bad request
                    resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
                }
               
            } else {
                lockInfo_lockOwner = new String();
            }
           
        } else {
            lockType = LOCK_REFRESH;
        }
       
    }
   
   
    /**
     * Execute request.
     *
     * @exception WebdavException Unrecoverable error while renewing lock
     */
    protected void executeRequest()
        throws WebdavException {
       
        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);
                   
                    NodeProperty property = null;
                   
                    // Resource type
                    property = new NodeProperty("resourcetype",
                                                "<lock-null/>", true);
                    revisionDescriptor.setProperty(property);
                   
                    // 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()
                                        + (MAX_TIMEOUT * 1000));
                   
                }
               
                SubjectNode credentialsSubject =
                    (SubjectNode) structure.retrieve
                    (slideToken, namespaceConfig.getUsersPath() + "/"
                     + slideToken.getCredentialsToken()
                     .getPublicCredentials());
               
                NodeLock lockToken = null;
               
                inheritance = (depth != 0);
                boolean exclusive =
                    !(lockInfo_lockScope.equals("<shared/>"));
               
                if (lockDate == null)
                    lockDate = new Date((new Date()).getTime()
                                        + (lockDuration * 1000));
               
                lockToken =
                    new NodeLock(toLockSubject, credentialsSubject,
                                 namespaceConfig.getCreateObjectAction(),
                                 lockDate, inheritance, exclusive);
                lock.lock(slideToken, lockToken);
               
                try {
                    lockToken = new NodeLock
                        (lockToken,
                         namespaceConfig.getCreateRevisionMetadataAction()
                         .getUri());
                    lock.lock(slideToken, lockToken);
                } catch (ObjectIsAlreadyLockedException e) {
                    // Silent catch
                }

                try {
                    lockToken = new NodeLock
                        (lockToken,
                         namespaceConfig.getModifyRevisionMetadataAction()
                         .getUri());
                    lock.lock(slideToken, lockToken);
                } catch (ObjectIsAlreadyLockedException e) {
                    // Silent catch
                }
               
                try {
                    lockToken = new NodeLock
                        (lockToken,
                         namespaceConfig.getRemoveRevisionMetadataAction()
                         .getUri());
                    lock.lock(slideToken, lockToken);
                } catch (ObjectIsAlreadyLockedException e) {
                    // Silent catch
                }
               
                try {
                    lockToken = new NodeLock
                        (lockToken,
                         namespaceConfig.getModifyRevisionContentAction()
                         .getUri());
                    lock.lock(slideToken, lockToken);
                } catch (ObjectIsAlreadyLockedException e) {
                    // Silent catch
                }
               
                try {
                    lockToken = new NodeLock
                        (lockToken,
                         namespaceConfig.getRemoveRevisionContentAction()
                         .getUri());
                    lock.lock(slideToken, lockToken);
                } catch (ObjectIsAlreadyLockedException e) {
                    // Silent catch
                }
               
                try {
                    lockToken =
                        new NodeLock(lockToken,
                                     namespaceConfig.getRemoveObjectAction()
                                     .getUri());
                    lock.lock(slideToken, lockToken);
                } catch (ObjectIsAlreadyLockedException e) {
                    // Silent catch
                }
               
                resp.setStatus(WebdavStatus.SC_OK);
               
                // The lock token on which the DAV module will have the info
               
                showLockDiscoveryInfo(lockToken);
               
            } catch (ObjectIsAlreadyLockedException e) {
                if (inheritance && generate207Response(isCollection, e, requestUri)) {
                    // error is on the resource which we attempted to lock
                    String errorMessage = generateErrorMessage(e);
                    // Write it on the servlet writer
                    resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
                    try {
                        resp.getWriter().write(errorMessage);
                    } catch(IOException ex) {
                        // Critical error ... Servlet container is dead or something
                        ex.printStackTrace();
                        throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
                    }
                } 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) {
                resp.setStatus(getErrorCode(e));
                throw new WebdavException(WebdavStatus.SC_ACCEPTED, false);
            }
           
            break;
           
        case LOCK_REFRESH:
           
            try {
               
                Enumeration lockTokens =
                    lock.enumerateLocks(slideToken, lockInfo_lockSubject);
               
                NodeLock currentLockToken = null;
                Date newExpirationDate =
                    new Date((new Date()).getTime() + (lockDuration * 1000));
                while (lockTokens.hasMoreElements()) {
                    currentLockToken = (NodeLock) lockTokens.nextElement();
                    lock.renew(slideToken, currentLockToken,
                               newExpirationDate);
                }
               
                showLockDiscoveryInfo(currentLockToken);
               
            } catch (SlideException e) {
                resp.setStatus(WebdavStatus.SC_PRECONDITION_FAILED);
                e.printStackTrace();
                //
                // 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);
            }
           
            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
       
        XMLPrinter generatedXML = new XMLPrinter();
       
        generatedXML.writeXMLHeader();
        generatedXML.writeElement("d", "DAV:", "prop", XMLPrinter.OPENING);
       
        generatedXML.writeElement("d", null, "lockdiscovery",
                                  XMLPrinter.OPENING);
       
        generatedXML.writeElement("d", null, "activelock", XMLPrinter.OPENING);
       
        generatedXML.writeElement("d", null, "locktype", XMLPrinter.OPENING);
        generatedXML.writeElement("d", null, "write", XMLPrinter.NO_CONTENT);
        generatedXML.writeElement("d", null, "locktype", XMLPrinter.CLOSING);
       
        generatedXML.writeElement("d", null, "lockscope", XMLPrinter.OPENING);
       
        if (token.isExclusive()) {
            generatedXML.writeElement("d", null, "exclusive",
                                      XMLPrinter.NO_CONTENT);
        } else {
            generatedXML.writeElement("d", null, "shared",
                                      XMLPrinter.NO_CONTENT);
        }
        generatedXML.writeElement("d", null, "lockscope", XMLPrinter.CLOSING);
       
        generatedXML.writeElement("d", null, "depth", XMLPrinter.OPENING);
        if (token.isInheritable()) {
            generatedXML.writeText("Infinity");
        } else {
            generatedXML.writeText("0");
        }
        generatedXML.writeElement("d", null, "depth", XMLPrinter.CLOSING);
       
        generatedXML.writeElement("d", null, "owner", XMLPrinter.OPENING);
        //generatedXML.writeText(lockInfo_lockOwner);
        generatedXML.writeText(req.getServletPath() + token.getSubjectUri());
        generatedXML.writeElement("d", null, "owner", XMLPrinter.CLOSING);
       
        generatedXML.writeElement("d", null, "timeout", XMLPrinter.OPENING);
        generatedXML.writeText("Second-"
                               + (new Long((token.getExpirationDate().getTime()
                                            - (new Date()).getTime())/1000))
                               .toString());
        generatedXML.writeElement("d", null, "timeout", XMLPrinter.CLOSING);
       
        generatedXML.writeElement("d", null, "locktoken", XMLPrinter.OPENING);
        generatedXML.writeElement("d", null, "href", XMLPrinter.OPENING);
        // Put here the token Id
        generatedXML.writeText("opaquelocktoken:" + token.getLockId());
       
        generatedXML.writeElement("d", null, "href", XMLPrinter.CLOSING);
        generatedXML.writeElement("d", null, "locktoken", XMLPrinter.CLOSING);
       
        generatedXML.writeElement("d", null, "activelock", XMLPrinter.CLOSING);
       
        generatedXML.writeElement("d", null, "lockdiscovery",
                                  XMLPrinter.CLOSING);
       
        generatedXML.writeElement("d", null, "prop", XMLPrinter.CLOSING);
       
       
        try {
            //System.out.println("Query result");
            //System.out.println(generatedXML.toString());
            Writer writer = resp.getWriter();
            writer.write(generatedXML.toString());
            writer.flush();
        } catch (Exception e) {
            e.printStackTrace();
            throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
        }
       
       
    }
  
   
    /**
     * Returns true
     */
    protected boolean methodNeedsTransactionSupport() {
        return true;
    }
   
  
}


TOP

Related Classes of org.apache.slide.webdav.method.LockMethod

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.