pnever      2003/08/17 23:57:37

  Modified:    src/webdav/server/org/apache/slide/webdav/method
                        CopyMethod.java MoveMethod.java
  Log:
  Adapted to new binding semantics and fixed bugs
  
  Revision  Changes    Path
  1.54      +293 -226  
jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/CopyMethod.java
  
  Index: CopyMethod.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/CopyMethod.java,v
  retrieving revision 1.53
  retrieving revision 1.54
  diff -u -r1.53 -r1.54
  --- CopyMethod.java   21 May 2003 15:49:46 -0000      1.53
  +++ CopyMethod.java   18 Aug 2003 06:57:37 -0000      1.54
  @@ -65,6 +65,7 @@
   
   import java.io.IOException;
   import java.util.ArrayList;
  +import java.util.Date;
   import java.util.Enumeration;
   import java.util.HashMap;
   import java.util.Iterator;
  @@ -73,6 +74,7 @@
   import org.apache.slide.common.NamespaceAccessToken;
   import org.apache.slide.common.ServiceAccessException;
   import org.apache.slide.common.SlideException;
  +import org.apache.slide.common.Uri;
   import org.apache.slide.content.BranchNotFoundException;
   import org.apache.slide.content.NodeNotVersionedException;
   import org.apache.slide.content.NodeProperty;
  @@ -95,6 +97,8 @@
   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;
  @@ -116,38 +120,39 @@
    * @author <a href="mailto:[EMAIL PROTECTED]">Remy Maucherat</a>
    * @author Juergen Pill
    */
  -public class CopyMethod extends AbstractMultistatusResponseMethod implements 
DeltavConstants, CopyListener, DeleteListener, CopyRouteRedirector {
  -
  -
  -
  +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 [EMAIL PROTECTED] #beforeCopy beforeCopy()} and [EMAIL PROTECTED] 
#afterCopy afterCopy()}.
        */
       protected Map destinationDescriptorMap = new HashMap();
  -
  +    
       /**
        * Maps the URI of a destination to its backup descriptor.
        * Used by [EMAIL PROTECTED] #beforeCopy beforeCopy()} and [EMAIL PROTECTED] 
#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.
        *
  @@ -157,10 +162,10 @@
       public CopyMethod(NamespaceAccessToken token, WebdavServletConfig config) {
           super(token, config);
       }
  -
  -
  +    
  +    
       // ------------------------------------------------------ Protected Methods
  -
  +    
       /**
        * Parse request.
        *
  @@ -168,13 +173,13 @@
        */
       protected void parseRequest() throws WebdavException {
           super.parseRequest();
  -
  +        
           versioningHelper =
               VersioningHelper.getVersioningHelper(slideToken, token, req, resp, 
config);
           labelHeader = 
WebdavUtils.fixTomcatHeader(req.getHeader(DeltavConstants.H_LABEL), "UTF-8");
  -
  +        
       }
  -
  +    
       /**
        * Execute request.
        *
  @@ -182,19 +187,12 @@
        */
       protected void executeRequest()
           throws WebdavException, IOException {
  -
  +        
           // Prevent dirty reads
           slideToken.setForceStoreEnlistment(true);
  -
  -        MacroParameters macroParameters = null;
  +        
           boolean isCollection = isCollection(sourceUri);
  -
  -        if (overwrite) {
  -            macroParameters = Macro.RECURSIVE_OVERWRITE_PARAMETERS;
  -        } else {
  -            macroParameters = Macro.DEFAULT_PARAMETERS;
  -        }
  -
  +        
           // check destination URI
           UriHandler destUh = UriHandler.getUriHandler(destinationUri);
           if( VersionControlMethod.VERSIONCONTROL_EXCLUDEPATH != null && 
VersionControlMethod.VERSIONCONTROL_EXCLUDEPATH.length() > 0 ) {
  @@ -202,7 +200,7 @@
               if( exUh.isAncestorOf(destUh) )
                   isInVersioncontrolExcludePath = true;
           }
  -
  +        
           if (destUh.isRestrictedUri()) {
               boolean sendError = true;
               if( destUh.isWorkspaceUri()        ||
  @@ -221,10 +219,32 @@
                   throw new WebdavException( statusCode );
               }
           }
  -
  +        
  +        // compare resource types of source and destination
  +        boolean sameResourceType = isSameResourcetype();
  +        
  +        if (overwrite && sameResourceType) {
  +            macroParameters = new MacroParameters(true, true, false);
  +        }
  +        else if (overwrite && !sameResourceType) {
  +            macroParameters = new MacroParameters(true, true, true);
  +        }
  +        else {
  +            macroParameters = Macro.DEFAULT_PARAMETERS;
  +        }
  +        
           try {
  +            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) {
  +            
  +            if (overwrite && destinationExistsBefore) {
                   resp.setStatus(WebdavStatus.SC_NO_CONTENT);
               } else {
                   resp.setStatus(WebdavStatus.SC_CREATED);
  @@ -270,11 +290,31 @@
               //
               throw new WebdavException(WebdavStatus.SC_ACCEPTED, false);
           }
  -
  +        catch (SlideException e) {
  +            int statusCode = getErrorCode( e );
  +            sendError( statusCode, e );
  +            throw new WebdavException( statusCode );
  +        }
       }
  -
  -
  -
  +    
  +    private boolean isSameResourcetype() {
  +        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 (Throwable e) {
  +            // ignore silently
  +        }
  +        return sameResourceType;
  +    }
  +    
  +    
  +    
       /**
        * Get return status based on exception type.
        */
  @@ -287,9 +327,130 @@
               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 [EMAIL PROTECTED] #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>.
        *
  @@ -302,12 +463,12 @@
        *                             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);
               }
  @@ -317,15 +478,16 @@
                                                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
  @@ -340,17 +502,19 @@
        */
       public void beforeCopy(String sourceUri, String destinationUri) throws 
SlideException {
           if(Configuration.useVersionControl()) {
  -
  -            UriHandler uriHandler = UriHandler.getUriHandler(sourceUri);
  -            if (uriHandler.isHistoryUri()) {
  -                throw new PreconditionViolationException(new 
ViolatedPrecondition(DeltavConstants.C_CANNOT_COPY_HISTORY,
  -                                                                                  
WebdavStatus.SC_FORBIDDEN),
  -                                                         sourceUri);
  +            
  +            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 );
               }
  -
           }
       }
  -
  +    
       /**
        * This method is called after copying the resource to
        * the given <code>destinationUri</code>.
  @@ -363,35 +527,39 @@
        *                             MacroDeleteException.
        */
       public void afterCopy(String sourceUri, String destinationUri) throws 
SlideException {
  -
  +        
           if(Configuration.useVersionControl()) {
  -
  -            NodeRevisionDescriptors destinationRevisionDescriptors = 
content.retrieve( slideToken, destinationUri);
  -            NodeRevisionDescriptor destinationRevisionDescriptor = 
content.retrieve( slideToken, destinationRevisionDescriptors);
  -
  +            
  +            NodeRevisionDescriptors destinationNrds = content.retrieve( slideToken, 
destinationUri);
  +            NodeRevisionDescriptor destinationNrd = content.retrieve( slideToken, 
destinationNrds);
  +            
               // restore backup descriptor
  -            restoreBackupRevisionDescriptor(destinationUri, 
destinationRevisionDescriptors);
  -
  -            NodeRevisionDescriptor existingDestinationRevisionDescriptor =
  +            restoreBackupRevisionDescriptor(destinationUri, destinationNrds);
  +            
  +            NodeRevisionDescriptor existingNrd =
                   
(NodeRevisionDescriptor)destinationDescriptorMap.get(destinationUri);
  -            if (existingDestinationRevisionDescriptor != null) {
  -
  +            if (existingNrd != null) {
  +                
                   // there has been an existing destination, so restore live 
properties
  -                restoreLiveProperties(destinationRevisionDescriptor, 
existingDestinationRevisionDescriptor);
  +                restoreLiveProperties(destinationUri, destinationNrd, existingNrd);
               }
               else {
  -
  +                
                   // DAV:must-not-copy-versioning-property
  -                resetDeltavProperties(destinationRevisionDescriptor);
  +                resetDeltavProperties(destinationNrd);
               }
  -
  +            
               // set <workspace> property
  -            versioningHelper.setWorkspaceProperty(destinationUri, 
destinationRevisionDescriptor);
  -
  -            content.store(slideToken, destinationRevisionDescriptors.getUri(), 
destinationRevisionDescriptor, null);
  -
  +            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, 
destinationRevisionDescriptors, destinationRevisionDescriptor);
  +            boolean mustCheckin = 
versioningHelper.mustCheckinAutoVersionedVCR(slideToken, destinationNrds, 
destinationNrd);
               if (mustCheckin) {
                   try {
                       versioningHelper.checkin(destinationUri, false, false, true ); 
//forkOk=false, keepCheckedOut=false
  @@ -403,164 +571,64 @@
                       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);
               }
  -
  -        }
  -
  -    }
  -
  -    /**
  -     * 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(NodeRevisionDescriptor 
destinationRevisionDescriptor, NodeRevisionDescriptor 
existingDestinationRevisionDescriptor) {
  -
  -        // remove all live properties
  -        Enumeration propertyEnum = 
destinationRevisionDescriptor.enumerateProperties();
  -        NodeProperty property = null;
  -        while (propertyEnum.hasMoreElements()) {
  -            property = (NodeProperty)propertyEnum.nextElement();
  -            if (isLivePropertyToRestore(property)) {
  -                destinationRevisionDescriptor.removeProperty(property);
  -            }
  -        }
  -
  -        // copy all live properties of the existing destination
  -        propertyEnum = existingDestinationRevisionDescriptor.enumerateProperties();
  -        property = null;
  -        while (propertyEnum.hasMoreElements()) {
  -            property = (NodeProperty)propertyEnum.nextElement();
  -            if (isLivePropertyToRestore(property)) {
  -                destinationRevisionDescriptor.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(NodeProperty property) {
  -        return (property.isLiveProperty() &&
  -                    
DeltavConstants.DELTAV_PROPERTY_LIST.contains(property.getName()));
  -    }
  -
  +    
  +    
  +    
  +    // ------------------------------------------------------ Interface 
DeleteListener
  +    
       /**
  -     * Sets all DeltaV specific properties of the given NodeRevisionDescriptor
  -     * to their initial value.
  +     * 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      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 [EMAIL PROTECTED] #beforeDelete beforeDelete()}.
  +     * @param      destinationUri  the Uri of the resource that will be deleted.
        *
  -     * @param      destinationUri                  the Uri of the resource.
  -     * @param      destinationRevisionDescriptors  the NodeRevisionDescriptors of
  -     *                                             the resource.
  +     * @throws     SlideException  this Exception will be passed to the caller
  +     *                             of the Macro helper (contained in the
  +     *                             MacroDeleteException.
        */
  -    private void restoreBackupRevisionDescriptor(String destinationUri, 
NodeRevisionDescriptors destinationRevisionDescriptors) throws 
RevisionNotFoundException, ServiceAccessException, RevisionAlreadyExistException, 
ObjectNotFoundException, LinkedObjectNotFoundException, ObjectLockedException, 
AccessDeniedException, RevisionDescriptorNotFoundException, BranchNotFoundException, 
NodeNotVersionedException {
  -
  -        NodeRevisionDescriptor destinationBackupDescriptor =
  -            
(NodeRevisionDescriptor)destinationBackupDescriptorMap.get(destinationUri);
  -        if (destinationBackupDescriptor != null) {
  -            try {
  -                content.retrieve( slideToken,
  -                                 destinationRevisionDescriptors,
  -                                 NodeRevisionNumber.HIDDEN_0_0 );
  -                content.store( slideToken,
  -                              destinationRevisionDescriptors.getUri(),
  -                              destinationBackupDescriptor,
  -                              null );
  -            }
  -            catch (RevisionDescriptorNotFoundException e) {
  -                content.create( slideToken,
  -                               destinationRevisionDescriptors.getUri(),
  -                               null,
  -                               destinationBackupDescriptor,
  -                               null ); // branch=null, revisionContent=null
  -            }
  -        }
  +    public void beforeDelete(String destinationUri) throws SlideException {
  +        beforeUpdateOrDelete( destinationUri );
       }
  -
  -
  -    // ------------------------------------------------------ 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      targetUri       the Uri of the resource that will be deleted.
  +     * @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 targetUri) throws SlideException {
  -
  +    private void beforeUpdateOrDelete(String destinationUri) throws SlideException {
           if( Configuration.useVersionControl() ) {
  -
  -            boolean destinationExists = false;
  -            NodeRevisionDescriptors revisionDescriptors = null;
  -            NodeRevisionDescriptor revisionDescriptor = null;
  +            NodeRevisionDescriptors destinationNrds = null;
  +            NodeRevisionDescriptor destinationNrd = null;
  +            
               try {
  -                revisionDescriptors = content.retrieve( slideToken, targetUri);
  -                revisionDescriptor = content.retrieve( slideToken, 
revisionDescriptors);
  -                destinationExists = true;
  +                destinationNrds = content.retrieve( slideToken, destinationUri);
  +                destinationNrd = content.retrieve( slideToken, destinationNrds);
               }
               catch (ObjectNotFoundException e) {}
  -
  -            if (destinationExists) {
  -
  -                ResourceKind resourceKind = 
AbstractResourceKind.determineResourceKind(token, targetUri, revisionDescriptor);
  +            
  +            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(revisionDescriptor);
  +                    String autoVersion = 
versioningHelper.getAutoVersionElementName(destinationNrd);
                       if (autoVersion == null) {
                           autoVersion = "";
                       }
  @@ -569,29 +637,29 @@
                           !E_CHECKOUT.equals(autoVersion) &&
                           !E_LOCKED_CHECKOUT.equals(autoVersion) ) {
                           throw new PreconditionViolationException(new 
ViolatedPrecondition(C_CANNOT_MODIFY_VERSION_CONTROLLED_CONTENT,
  -                                                                                    
      WebdavStatus.SC_FORBIDDEN), targetUri);
  +                                                                                    
      WebdavStatus.SC_FORBIDDEN), destinationUri);
                       }
                       if ( E_LOCKED_CHECKOUT.equals(autoVersion) &&
  -                            ( !versioningHelper.isWriteLocked(slideToken, 
revisionDescriptors) ) ) {
  +                            ( !versioningHelper.isWriteLocked(slideToken, 
destinationNrds) ) ) {
                           throw new PreconditionViolationException(new 
ViolatedPrecondition(C_CANNOT_MODIFY_VERSION_CONTROLLED_CONTENT,
  -                                                                                    
      WebdavStatus.SC_FORBIDDEN), targetUri);
  +                                                                                    
      WebdavStatus.SC_FORBIDDEN), destinationUri);
                       }
                   }
  -
  +                
                   // check precondition DAV:cannot-modify-version
  -                UriHandler uriHandler = UriHandler.getUriHandler(targetUri);
  +                UriHandler uriHandler = UriHandler.getUriHandler(destinationUri);
                   if (uriHandler.isVersionUri()) {
                       throw new PreconditionViolationException(new 
ViolatedPrecondition(C_CANNOT_MODIFY_VERSION,
  -                                                                                    
  WebdavStatus.SC_FORBIDDEN), targetUri);
  +                                                                                    
  WebdavStatus.SC_FORBIDDEN), destinationUri);
                   }
  -
  +                
                   // checkout if necessary
                   if( Configuration.useVersionControl() &&
                          (resourceKind instanceof CheckedInVersionControlled) &&
  -                   
versioningHelper.mustCheckoutAutoVersionedVCR(revisionDescriptors, revisionDescriptor) 
) {
  -
  +                   versioningHelper.mustCheckoutAutoVersionedVCR(destinationNrds, 
destinationNrd) ) {
  +                    
                       try {
  -                        versioningHelper.checkout(revisionDescriptors, 
revisionDescriptor, false, false, true );
  +                        versioningHelper.checkout(destinationNrds, destinationNrd, 
false, false, true );
                       }
                       catch (IOException e) {
                           throw new SlideException("Checkout failed: " + 
e.getMessage());
  @@ -600,22 +668,22 @@
                           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 backupDescriptor =
  -                        content.retrieve( slideToken, revisionDescriptors, 
NodeRevisionNumber.HIDDEN_0_0 );
  -                    destinationBackupDescriptorMap.put(targetUri, backupDescriptor);
  +                    NodeRevisionDescriptor backupNrd =
  +                        content.retrieve( slideToken, destinationNrds, 
NodeRevisionNumber.HIDDEN_0_0 );
  +                    destinationBackupDescriptorMap.put(destinationUri, backupNrd);
                   }
                   catch (RevisionDescriptorNotFoundException e) {
                   }
  -                destinationDescriptorMap.put(targetUri, revisionDescriptor);
  +                destinationDescriptorMap.put(destinationUri, destinationNrd);
               }
           }
       }
  -
  +    
       /**
        * This method is called after deleting the resource associated by
        * the given <code>targetUri</code>.
  @@ -627,12 +695,11 @@
        *                     targetUricroDeleteException.
        */
       public void afterDelete(String targetUri) throws SlideException {
  -
       }
  -
  -
  -
  -
  +    
  +    
  +    
  +    
   }
   
   
  
  
  
  1.58      +30 -5     
jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MoveMethod.java
  
  Index: MoveMethod.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MoveMethod.java,v
  retrieving revision 1.57
  retrieving revision 1.58
  diff -u -r1.57 -r1.58
  --- MoveMethod.java   21 May 2003 15:49:46 -0000      1.57
  +++ MoveMethod.java   18 Aug 2003 06:57:37 -0000      1.58
  @@ -85,6 +85,7 @@
   import org.apache.slide.search.Search;
   import org.apache.slide.search.SearchQuery;
   import org.apache.slide.search.SearchQueryResult;
  +import org.apache.slide.structure.ObjectNode;
   import org.apache.slide.structure.ObjectNotFoundException;
   import org.apache.slide.util.Configuration;
   import org.apache.slide.webdav.WebdavException;
  @@ -148,6 +149,8 @@
        */
       protected Element literal = null;
       
  +    private boolean destinationExistsBefore = false;
  +    
       // ----------------------------------------------------------- Constructors
       
       
  @@ -208,11 +211,22 @@
               // check preconditions
               ViolatedPrecondition violatedPrecondition = 
getPreconditionViolation(sourceUri, destinationUri);
               if (violatedPrecondition != null) {
  -                throw new PreconditionViolationException(violatedPrecondition, 
sourceUri);
  +                PreconditionViolationException e =
  +                    new PreconditionViolationException(violatedPrecondition, 
sourceUri);
  +                sendPreconditionViolation(e);
  +                throw e;
  +            }
  +            
  +            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.move(slideToken, sourceUri, destinationUri, macroParameters, 
null, this, null, this);
  -            if (overwrite) {
  +            
  +            if (overwrite && destinationExistsBefore) {
                   resp.setStatus(WebdavStatus.SC_NO_CONTENT);
               } else {
                   resp.setStatus(WebdavStatus.SC_CREATED);
  @@ -322,6 +336,17 @@
                   }
               }
           }
  +        if (isCollection(sourceUri)) {
  +            UriHandler destinationUriHandler = 
UriHandler.getUriHandler(destinationUri);
  +            ObjectNode destinationParentNode =
  +                structure.retrieve(slideToken, 
destinationUriHandler.getParentUriHandler().toString());
  +            ObjectNode sourceNode =
  +                structure.retrieve(slideToken, sourceUri);
  +            if (isDescendant(destinationParentNode, sourceNode)) {
  +                return new ViolatedPrecondition(C_CYCLE_ALLOWED, 
WebdavStatus.SC_FORBIDDEN);
  +            }
  +        }
  +        
           return violatedPrecondition;
       }
       
  
  
  

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

Reply via email to