/*
* $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 {
}
}