Package org.apache.slide.webdav.method

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

/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/CopyMethod.java,v 1.58.2.1 2004/02/05 16:11:23 mholz Exp $
* $Revision: 1.58.2.1 $
* $Date: 2004/02/05 16:11:23 $
*
* ====================================================================
*
* Copyright 1999-2002 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.slide.webdav.method;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.SlideException;
import org.apache.slide.content.BranchNotFoundException;
import org.apache.slide.content.NodeNotVersionedException;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.content.RevisionAlreadyExistException;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.content.RevisionNotFoundException;
import org.apache.slide.lock.ObjectLockedException;
import org.apache.slide.macro.CopyListener;
import org.apache.slide.macro.CopyRouteRedirector;
import org.apache.slide.macro.DeleteListener;
import org.apache.slide.macro.Macro;
import org.apache.slide.macro.MacroException;
import org.apache.slide.macro.MacroParameters;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.structure.LinkedObjectNotFoundException;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.util.Configuration;
import org.apache.slide.webdav.WebdavException;
import org.apache.slide.webdav.WebdavServletConfig;
import org.apache.slide.webdav.util.AclConstants;
import org.apache.slide.webdav.util.BindConstants;
import org.apache.slide.webdav.util.DeltavConstants;
import org.apache.slide.webdav.util.LabeledRevisionNotFoundException;
import org.apache.slide.webdav.util.PreconditionViolationException;
import org.apache.slide.webdav.util.PropertyHelper;
import org.apache.slide.webdav.util.UriHandler;
import org.apache.slide.webdav.util.VersioningHelper;
import org.apache.slide.webdav.util.ViolatedPrecondition;
import org.apache.slide.webdav.util.WebdavUtils;
import org.apache.slide.util.XMLValue;
import org.apache.slide.webdav.util.resourcekind.AbstractResourceKind;
import org.apache.slide.webdav.util.resourcekind.CheckedInVersionControlled;
import org.apache.slide.webdav.util.resourcekind.ResourceKind;
import org.apache.slide.webdav.util.resourcekind.VersionableImpl;
import org.apache.util.WebdavStatus;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;

/**
* COPY Method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
* @author Juergen Pill
*/
public class CopyMethod extends AbstractMultistatusResponseMethod implements DeltavConstants, AclConstants, BindConstants, CopyListener, DeleteListener, CopyRouteRedirector {
   
   
   
    /**
     * The VersioningHelper used by this instance.
     */
    protected VersioningHelper versioningHelper = null;
   
    /**
     * Maps the URI of a destination to its descriptor.
     * Used by {@link #beforeCopy beforeCopy()} and {@link #afterCopy afterCopy()}.
     */
    protected Map destinationDescriptorMap = new HashMap();
   
    /**
     * Maps the URI of a destination to its backup descriptor.
     * Used by {@link #beforeCopy beforeCopy()} and {@link #afterCopy afterCopy()}.
     */
    protected Map destinationBackupDescriptorMap = new HashMap();
   
    /**
     * The value of the <code>Label</code> header.
     */
    protected String labelHeader = null;
   
    private boolean isInVersioncontrolExcludePath = false;
    private MacroParameters macroParameters = null;
   
   
    // ----------------------------------------------------------- Constructors
   
   
    /**
     * Constructor.
     *
     * @param token     the token for accessing the namespace
     * @param config    configuration of the WebDAV servlet
     */
    public CopyMethod(NamespaceAccessToken token, WebdavServletConfig config) {
        super(token, config);
    }
   
   
    // ------------------------------------------------------ Protected Methods
   
    /**
     * Parse request.
     *
     * @exception WebdavException Does not happen
     */
    protected void parseRequest() throws WebdavException {
        super.parseRequest();
       
        versioningHelper =
            VersioningHelper.getVersioningHelper(slideToken, token, req, resp, config);
        labelHeader = WebdavUtils.fixTomcatHeader(requestHeaders.getLabel(), "UTF-8");
    }
   
    /**
     * Execute request.
     *
     * @exception WebdavException Unrecoverable error occured while copying
     */
    protected void executeRequest()
        throws WebdavException, IOException {
       
        // Prevent dirty reads
        slideToken.setForceStoreEnlistment(true);
       
        boolean isCollection = isCollection(sourceUri);
       
        // check lock-null resources
        try {
            if (isLockNull(sourceUri)) {
                int statusCode = WebdavStatus.SC_NOT_FOUND;
                sendError( statusCode, "lock-null resource", new Object[]{sourceUri} );
                throw new WebdavException( statusCode );
            }
        }
        catch (ServiceAccessException e) {
            int statusCode = getErrorCode((Exception)e);
            sendError( statusCode, e );
            throw new WebdavException( statusCode );
        }
       
        // check destination URI
        UriHandler destUh = UriHandler.getUriHandler(destinationUri);
        if( VersionControlMethod.VERSIONCONTROL_EXCLUDEPATH != null && VersionControlMethod.VERSIONCONTROL_EXCLUDEPATH.length() > 0 ) {
            UriHandler exUh = UriHandler.getUriHandler( VersionControlMethod.VERSIONCONTROL_EXCLUDEPATH );
            if( exUh.isAncestorOf(destUh) )
                isInVersioncontrolExcludePath = true;
        }
       
        if (destUh.isRestrictedUri()) {
            boolean sendError = true;
            if( destUh.isWorkspaceUri()        ||
               destUh.isWorkingresourceUri()
              ) {
                // COPY on existing WSs or WRs is *not* restricted !!!
                try {
                    content.retrieve(slideToken, destinationUri);
                    sendError = false;
                }
                catch( ServiceAccessException x ) {
                    int statusCode = getErrorCode((SlideException)x);
                    sendError( statusCode, x );
                    throw new WebdavException( statusCode );
                }
                catch( SlideException x ) {};
            }
            if( sendError ) {
                int statusCode = WebdavStatus.SC_FORBIDDEN;
                sendError( statusCode, getClass().getName()+".restrictedDestinationUri", new Object[]{destinationUri} );
                throw new WebdavException( statusCode );
            }
        }
       
        try {
            // compare resource types of source and destination
            boolean sameResourceType = isSameResourcetype();
            int 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 );
            }
           
            boolean recursive = (depth == INFINITY);
           
            if (overwrite && sameResourceType) {
                macroParameters = new MacroParameters(recursive, true, false);
            }
            else if (overwrite && !sameResourceType) {
                macroParameters = new MacroParameters(recursive, true, true);
            }
            else {
                macroParameters = new MacroParameters(recursive, false, false);
            }
           
            boolean destinationExistsBefore = exists( destinationUri );
           
            if (!overwrite && destinationExistsBefore) {
                int statusCode = WebdavStatus.SC_PRECONDITION_FAILED;
                sendError( statusCode, getClass().getName()+".noOverwrite", new Object[]{destinationUri} );
                throw new WebdavException( statusCode );
            }
           
            macro.copy(slideToken, sourceUri, destinationUri, macroParameters, this, this, null, this);
           
            if (overwrite && destinationExistsBefore) {
                resp.setStatus(WebdavStatus.SC_NO_CONTENT);
            } else {
                resp.setStatus(WebdavStatus.SC_CREATED);
            }
        } catch (MacroException e) {
            if(generateMultiStatusResponse(isCollection, e, requestUri)) {
                String errorMessage = generateErrorMessage(e);
                // Write it on the servlet writer
                resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
                try {
                    resp.setContentType(TEXT_XML_UTF_8);
                    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.
                SlideException exception = (SlideException)e.enumerateExceptions().nextElement();
                if (exception instanceof PreconditionViolationException) {
                    try {
                        sendPreconditionViolation((PreconditionViolationException)exception);
                    } 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 {
                    int statusCode = getErrorCode( exception );
                    sendError( statusCode, exception );
                    throw new WebdavException( statusCode );
                }
            }
            //
            // 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 (WebdavException e) {
            throw e;
        }
        catch (SlideException e) {
            int statusCode = getErrorCode( e );
            sendError( statusCode, e );
            throw new WebdavException( statusCode );
        }
    }
   
    private boolean isSameResourcetype() throws ServiceAccessException {
        boolean sameResourceType = false;
        try {
            NodeRevisionDescriptor sourceNrd =
                content.retrieve( slideToken, content.retrieve(slideToken, sourceUri) );
            NodeRevisionDescriptor destinationNrd =
                content.retrieve( slideToken, content.retrieve(slideToken, destinationUri) );
            sameResourceType =
                sourceNrd.getResourceType().equals(destinationNrd.getResourceType());
        }
        catch (ServiceAccessException e) {
            throw e;
        }
        catch (SlideException e) {
            // ignore silently
        }
        return sameResourceType;
    }
   
   
   
    /**
     * Get return status based on exception type.
     */
    protected int getErrorCode(SlideException ex) {
        try {
            throw ex;
        } catch(RevisionNotFoundException e) {
            return WebdavStatus.SC_NOT_FOUND;
        } catch (SlideException e) {
            return super.getErrorCode(e);
        }
    }
   
    /**
     * Restores all live properties that should not be copied.
     *
     * @param      destinationRevisionDescriptor          the descriptor to restore.
     * @param      existingDestinationRevisionDescriptor  the descriptor that has been overwritten.
     */
    private void restoreLiveProperties(String destinationUri, NodeRevisionDescriptor destinationNrd, NodeRevisionDescriptor existingNrd) {
       
        // remove all live properties
        Enumeration propertyEnum = destinationNrd.enumerateProperties();
        NodeProperty property = null;
        while (propertyEnum.hasMoreElements()) {
            property = (NodeProperty)propertyEnum.nextElement();
            if (isLivePropertyToRestore(destinationUri, property)) {
                destinationNrd.removeProperty(property);
            }
        }
       
        // copy all live properties of the existing destination
        propertyEnum = existingNrd.enumerateProperties();
        property = null;
        while (propertyEnum.hasMoreElements()) {
            property = (NodeProperty)propertyEnum.nextElement();
            if (isLivePropertyToRestore(destinationUri, property)) {
                destinationNrd.setProperty(property);
            }
        }
    }
   
    /**
     * Indicates if the given property is a live property to restore.
     *
     * @param      property  the NodeProperty to decide.
     *
     * @return     <code>true</code> if this is a live property to restore.
     */
    private boolean isLivePropertyToRestore(String uri, NodeProperty property) {
        boolean isLivePropertyToRestore = property.isLiveProperty() && (
            DeltavConstants.DELTAV_PROPERTY_LIST.contains(property.getName()) ||
                AclConstants.ACL_PROPERTY_LIST.contains(property.getName())   ||
                BindConstants.BIND_PROPERTY_LIST.contains(property.getName()) ||
                P_CREATIONDATE.equals(property.getName())                     ||
            ( P_DISPLAYNAME.equals(property.getName()) &&
                 Configuration.useBinding(token.getUri(slideToken, uri).getStore()) )
        );
        return isLivePropertyToRestore;
    }
   
    /**
     * Sets all DeltaV specific properties of the given NodeRevisionDescriptor
     * to their initial value.
     *
     * @param      revisionDescriptor  the NodeRevisionDescriptor whose DeltaV
     *                                 properties should be reset.
     */
    private void resetDeltavProperties(NodeRevisionDescriptor revisionDescriptor) {
       
        // use initial values for DeltaV properties
        PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(slideToken, token, getConfig());
        ResourceKind resourceKind = VersionableImpl.getInstance();
        Iterator initialPropertyIterator =
            propertyHelper.createInitialProperties(resourceKind).iterator();
        NodeProperty property = null;
        List initialDeltavProperties = new ArrayList();
        while (initialPropertyIterator.hasNext()) {
            property = (NodeProperty)initialPropertyIterator.next();
            if (DeltavConstants.DELTAV_PROPERTY_LIST.contains(property.getName())) {
                initialDeltavProperties.add(property);
            }
        }
       
        Enumeration propertyEnum = revisionDescriptor.enumerateProperties();
        property = null;
        int index = 0;
        while (propertyEnum.hasMoreElements()) {
            property = (NodeProperty)propertyEnum.nextElement();
            if (DeltavConstants.DELTAV_PROPERTY_LIST.contains(property.getName())) {
                index = initialDeltavProperties.indexOf(property);
                if (index >= 0) {
                    revisionDescriptor.setProperty((NodeProperty)initialDeltavProperties.get(index));
                }
                else {
                    revisionDescriptor.removeProperty(property);
                }
            }
        }
    }
   
    /**
     * Restores the "backup" NodeRevisionDescriptor which has been saved in
     * method {@link #beforeDelete beforeDelete()}.
     *
     * @param      destinationUri                  the Uri of the resource.
     * @param      destinationRevisionDescriptors  the NodeRevisionDescriptors of
     *                                             the resource.
     */
    private void restoreBackupRevisionDescriptor(String destinationUri, NodeRevisionDescriptors destinationNrds) throws RevisionNotFoundException, ServiceAccessException, RevisionAlreadyExistException, ObjectNotFoundException, LinkedObjectNotFoundException, ObjectLockedException, AccessDeniedException, RevisionDescriptorNotFoundException, BranchNotFoundException, NodeNotVersionedException {
       
        NodeRevisionDescriptor backupNrd =
            (NodeRevisionDescriptor)destinationBackupDescriptorMap.get(destinationUri);
        if (backupNrd != null) {
            try {
                content.retrieve( slideToken,
                                 destinationNrds,
                                 NodeRevisionNumber.HIDDEN_0_0 );
                content.store( slideToken,
                              destinationNrds.getUri(),
                              backupNrd,
                              null );
            }
            catch (RevisionDescriptorNotFoundException e) {
                content.create( slideToken,
                               destinationNrds.getUri(),
                               null,
                               backupNrd,
                               null ); // branch=null, revisionContent=null
            }
        }
    }
   
   
    // ------------------------------------------------------ Interface CopyRouteRedirector
   
    /**
     * Returns the (redirected) CopyRoute to use. Must not be <code>null</code>.
     *
     * @param      the original CopyRoute.
     *
     * @return     the (redirected) CopyRoute to use.
     *
     * @throws     SlideException  this Exception will be passed to the caller
     *                             of the Macro helper (contained in the
     *                             MacroCopyException).
     */
    public CopyRoute getRedirectedCopyRoute(CopyRoute copyRoute) throws SlideException {
       
        if (Configuration.useVersionControl()) {
           
            String sourceUri = copyRoute.getSourceUri();
            String destinationUri = copyRoute.getDestinationUri();
           
            try {
                sourceUri = versioningHelper.getLabeledResourceUri(sourceUri, labelHeader);
            }
            catch (LabeledRevisionNotFoundException e) {
                ViolatedPrecondition violatedPrecondition =
                    new ViolatedPrecondition(DeltavConstants.C_MUST_SELECT_VERSION_IN_HISTORY,
                                             WebdavStatus.SC_CONFLICT);
                throw new PreconditionViolationException(violatedPrecondition, sourceUri);
            }
           
            copyRoute = new CopyRoute(sourceUri, destinationUri);
        }
       
        return copyRoute;
    }
   
   
    // ------------------------------------------------------ Interface CopyListener
   
    /**
     * This method is called prior to copying the resource associated by
     * the given <code>sourceUri</code>. The copy can be prohibited by
     * throwing a SlideException.
     *
     * @param      sourceUri       the Uri of the resource that will be copied.
     * @param      destinationUri  the Uri of the copy.
     *
     * @throws     SlideException  this Exception will be passed to the caller
     *                             of the Macro helper (contained in the
     *                             MacroDeleteException.
     */
    public void beforeCopy(String sourceUri, String destinationUri, boolean isRootOfCopy) throws SlideException {
        if(Configuration.useVersionControl()) {
           
            UriHandler sourceUh = UriHandler.getUriHandler(sourceUri);
            if (sourceUh.isHistoryUri()) {
                throw new PreconditionViolationException(
                    new ViolatedPrecondition(DeltavConstants.C_CANNOT_COPY_HISTORY, WebdavStatus.SC_FORBIDDEN), sourceUri);
            }
           
            if (!macroParameters.isDeleteCreate()) {
                beforeUpdateOrDelete( destinationUri );
            }
        }
        if (isRootOfCopy && Configuration.useBinding(token.getUri(slideToken, destinationUri).getStore())) {
            // collect the parent bindings of the destination node
            Map parentBindings = new HashMap();
            try {
                NodeRevisionDescriptor destinationNrd =
                    content.retrieve( slideToken, content.retrieve(slideToken, destinationUri) );
                XMLValue v = new XMLValue( (String)destinationNrd.getProperty( P_PARENT_SET ).getValue() );
                Iterator i = v.iterator();
                while (i.hasNext()) {
                    Namespace dnsp = Namespace.getNamespace(S_DAV);
                    Element parentElm = (Element)i.next();
                    String segment = parentElm.getChild(E_SEGMENT, dnsp).getTextTrim();
                    String href = parentElm.getChild(E_HREF, dnsp).getTextTrim();
                    parentBindings.put( href, segment );
                }
            }
            catch( ServiceAccessException x ) {
                throw x;
            }
            catch (SlideException e) {}
            catch (JDOMException e) {}
            macroParameters.setParameter( Macro.PARENT_BINDINGS, parentBindings );
        }
    }
   
    /**
     * This method is called after copying the resource to
     * the given <code>destinationUri</code>.
     *
     * @param      sourceUri       the Uri of the resource that has been copied.
     * @param      destinationUri  the Uri of the copy.
     *
     * @throws     SlideException  this Exception will be passed to the caller
     *                             of the Macro helper (contained in the
     *                             MacroDeleteException.
     */
    public void afterCopy(String sourceUri, String destinationUri, boolean isRootOfCopy) throws SlideException {
       
        if(Configuration.useVersionControl()) {
           
            NodeRevisionDescriptors destinationNrds = content.retrieve( slideToken, destinationUri);
            NodeRevisionDescriptor destinationNrd = content.retrieve( slideToken, destinationNrds);
           
            // restore backup descriptor
            restoreBackupRevisionDescriptor(destinationUri, destinationNrds);
           
            NodeRevisionDescriptor existingNrd =
                (NodeRevisionDescriptor)destinationDescriptorMap.get(destinationUri);
            if (existingNrd != null) {
               
                // there has been an existing destination, so restore live properties
                restoreLiveProperties(destinationUri, destinationNrd, existingNrd);
            }
            else {
               
                // DAV:must-not-copy-versioning-property
                resetDeltavProperties(destinationNrd);
            }
           
            // set <workspace> property
            versioningHelper.setWorkspaceProperty(destinationUri, destinationNrd);
           
            // set some other properties
            destinationNrd.setLastModified( new Date() ); // P_GETLASTMODIFIED
            destinationNrd.setETag( PropertyHelper.computeEtag(destinationUri, destinationNrd) ); // P_GETETAG
           
            content.store(slideToken, destinationNrds.getUri(), destinationNrd, null);
           
            // checkin if necessary
            boolean mustCheckin = versioningHelper.mustCheckinAutoVersionedVCR(slideToken, destinationNrds, destinationNrd);
            if (mustCheckin) {
                try {
                    versioningHelper.checkin(destinationUri, false, false, true ); //forkOk=false, keepCheckedOut=false
                }
                catch (IOException e) {
                    throw new SlideException("Checkin failed: " + e.getMessage());
                }
                catch (JDOMException e) {
                    throw new SlideException("Checkin failed: " + e.getMessage());
                }
            }
           
            // check if the resource should be put under version-control
            if( PutMethod.AUTO_VERSION_CONTROL && !isCollection(destinationUri) && !isInVersioncontrolExcludePath ) {
                versioningHelper.versionControl(destinationUri);
            }
           
        }
        if (isRootOfCopy && Configuration.useBinding(token.getUri(slideToken, destinationUri).getStore())) {
            // try to restore the parent bindings
            if (macroParameters.getParameter(Macro.PARENT_BINDINGS) != null) {
                Map parentBindings = (Map)macroParameters.getParameter(Macro.PARENT_BINDINGS);
                Iterator i = parentBindings.entrySet().iterator();
                while (i.hasNext()) {
                    Map.Entry me = (Map.Entry)i.next();
                    ObjectNode parentNode = structure.retrieve( slideToken, (String)me.getKey() );
                    ObjectNode destinationNode = structure.retrieve( slideToken, destinationUri );
                    String segment = (String)me.getValue();
                    structure.addBinding( slideToken, parentNode, segment, destinationNode );
                }
            }
        }
    }
   
   
   
    // ------------------------------------------------------ Interface DeleteListener
   
    /**
     * This method is called prior to deleting the resource associated by
     * the given <code>targetUri</code>. The deletion can be prohibited by
     * throwing a SlideException.
     *
     * @param      destinationUri  the Uri of the resource that will be deleted.
     *
     * @throws     SlideException  this Exception will be passed to the caller
     *                             of the Macro helper (contained in the
     *                             MacroDeleteException.
     */
    public void beforeDelete(String destinationUri) throws SlideException {
        beforeUpdateOrDelete( destinationUri );
    }
   
    /**
     * This method is called prior to deleting the resource associated by
     * the given <code>targetUri</code>. The deletion can be prohibited by
     * throwing a SlideException.
     *
     * @param      destinationUri  the Uri of the resource that will be deleted.
     *
     * @throws     SlideException  this Exception will be passed to the caller
     *                             of the Macro helper (contained in the
     *                             MacroDeleteException.
     */
    private void beforeUpdateOrDelete(String destinationUri) throws SlideException {
        if( Configuration.useVersionControl() ) {
            NodeRevisionDescriptors destinationNrds = null;
            NodeRevisionDescriptor destinationNrd = null;
           
            try {
                destinationNrds = content.retrieve( slideToken, destinationUri);
                destinationNrd = content.retrieve( slideToken, destinationNrds);
            }
            catch (ObjectNotFoundException e) {}
           
            if (destinationNrds != null && destinationNrd != null) {
               
                ResourceKind resourceKind = AbstractResourceKind.determineResourceKind(token, destinationUri, destinationNrd);
                if (resourceKind instanceof CheckedInVersionControlled) {
                   
                    // check precondition DAV:cannot-modify-version-controlled-content
                    String autoVersion = versioningHelper.getAutoVersionElementName(destinationNrd);
                    if (autoVersion == null) {
                        autoVersion = "";
                    }
                    if ( !E_CHECKOUT_CHECKIN.equals(autoVersion) &&
                        !E_CHECKOUT_UNLOCKED_CHECKIN.equals(autoVersion) &&
                        !E_CHECKOUT.equals(autoVersion) &&
                        !E_LOCKED_CHECKOUT.equals(autoVersion) ) {
                        throw new PreconditionViolationException(new ViolatedPrecondition(C_CANNOT_MODIFY_VERSION_CONTROLLED_CONTENT,
                                                                                          WebdavStatus.SC_FORBIDDEN), destinationUri);
                    }
                    if ( E_LOCKED_CHECKOUT.equals(autoVersion) &&
                            ( !versioningHelper.isWriteLocked(slideToken, destinationNrds) ) ) {
                        throw new PreconditionViolationException(new ViolatedPrecondition(C_CANNOT_MODIFY_VERSION_CONTROLLED_CONTENT,
                                                                                          WebdavStatus.SC_FORBIDDEN), destinationUri);
                    }
                }
               
                // check precondition DAV:cannot-modify-version
                UriHandler uriHandler = UriHandler.getUriHandler(destinationUri);
                if (uriHandler.isVersionUri()) {
                    throw new PreconditionViolationException(new ViolatedPrecondition(C_CANNOT_MODIFY_VERSION,
                                                                                      WebdavStatus.SC_FORBIDDEN), destinationUri);
                }
               
                // checkout if necessary
                if( Configuration.useVersionControl() &&
                       (resourceKind instanceof CheckedInVersionControlled) &&
                   versioningHelper.mustCheckoutAutoVersionedVCR(destinationNrds, destinationNrd) ) {
                   
                    try {
                        versioningHelper.checkout(destinationNrds, destinationNrd, false, false, true );
                    }
                    catch (IOException e) {
                        throw new SlideException("Checkout failed: " + e.getMessage());
                    }
                    catch (JDOMException e) {
                        throw new SlideException("Checkout failed: " + e.getMessage());
                    }
                }
               
                // store the descriptor(s) in order to restore it in afterDelete()
                // (the COPY specification for DeltaV says that an existing destination
                //  must not be deleted)
                try {
                    NodeRevisionDescriptor backupNrd =
                        content.retrieve( slideToken, destinationNrds, NodeRevisionNumber.HIDDEN_0_0 );
                    destinationBackupDescriptorMap.put(destinationUri, backupNrd);
                }
                catch (RevisionDescriptorNotFoundException e) {
                }
                destinationDescriptorMap.put(destinationUri, destinationNrd);
            }
        }
    }
   
    /**
     * This method is called after deleting the resource associated by
     * the given <code>targetUri</code>.
     *
     * @param      targetUri       the Uri of the resource that has been deleted.
     *
     * @throws     SlideException  this Exception will be passed to the caller
     *                             of the Macro helper (contained in the
     *                     targetUricroDeleteException.
     */
    public void afterDelete(String targetUri) throws SlideException {
    }
   
   
   
   
}





TOP

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

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.