KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > slide > webdav > method > CopyMethod


1 /*
2  * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/CopyMethod.java,v 1.67.2.2 2004/11/08 08:35:46 luetzkendorf Exp $
3  * $Revision: 1.67.2.2 $
4  * $Date: 2004/11/08 08:35:46 $
5  *
6  * ====================================================================
7  *
8  * Copyright 1999-2002 The Apache Software Foundation
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */

23
24 package org.apache.slide.webdav.method;
25
26 import java.util.*;
27 import org.apache.slide.content.*;
28 import org.apache.slide.macro.*;
29 import org.apache.slide.webdav.util.*;
30
31 import java.io.IOException JavaDoc;
32 import org.apache.slide.common.NamespaceAccessToken;
33 import org.apache.slide.common.ServiceAccessException;
34 import org.apache.slide.common.SlideException;
35 import org.apache.slide.event.EventDispatcher;
36 import org.apache.slide.event.VetoException;
37 import org.apache.slide.lock.ObjectLockedException;
38 import org.apache.slide.security.AccessDeniedException;
39 import org.apache.slide.structure.LinkedObjectNotFoundException;
40 import org.apache.slide.structure.ObjectNode;
41 import org.apache.slide.structure.ObjectNotFoundException;
42 import org.apache.slide.structure.SubjectNode;
43 import org.apache.slide.util.Configuration;
44 import org.apache.slide.util.XMLValue;
45 import org.apache.slide.webdav.WebdavException;
46 import org.apache.slide.webdav.WebdavServletConfig;
47 import org.apache.slide.webdav.event.WebdavEvent;
48 import org.apache.slide.webdav.util.resourcekind.AbstractResourceKind;
49 import org.apache.slide.webdav.util.resourcekind.CheckedInVersionControlled;
50 import org.apache.slide.webdav.util.resourcekind.ResourceKind;
51 import org.apache.slide.webdav.util.resourcekind.VersionableImpl;
52 import org.jdom.Element;
53 import org.jdom.JDOMException;
54 import org.jdom.Namespace;
55
56 /**
57  * COPY Method.
58  *
59  */

60 public class CopyMethod extends AbstractMultistatusResponseMethod implements DeltavConstants, AclConstants, BindConstants, CopyListener, DeleteListener, CopyRouteRedirector, WriteMethod {
61     
62     
63     
64     /**
65      * The VersioningHelper used by this instance.
66      */

67     protected VersioningHelper versioningHelper = null;
68     
69     /**
70      * Maps the URI of a destination to its descriptor.
71      * Used by {@link #beforeCopy beforeCopy()} and {@link #afterCopy afterCopy()}.
72      */

73     protected Map destinationDescriptorMap = new HashMap();
74     
75     /**
76      * Maps the URI of a destination to its backup descriptor.
77      * Used by {@link #beforeCopy beforeCopy()} and {@link #afterCopy afterCopy()}.
78      */

79     protected Map destinationBackupDescriptorMap = new HashMap();
80     
81     /**
82      * The value of the <code>Label</code> header.
83      */

84     protected String JavaDoc labelHeader = null;
85     
86     private MacroParameters macroParameters = null;
87     
88     
89     // ----------------------------------------------------------- Constructors
90

91     
92     /**
93      * Constructor.
94      *
95      * @param token the token for accessing the namespace
96      * @param config configuration of the WebDAV servlet
97      */

98     public CopyMethod(NamespaceAccessToken token, WebdavServletConfig config) {
99         super(token, config);
100     }
101     
102     
103     // ------------------------------------------------------ Protected Methods
104

105     /**
106      * Parse request.
107      *
108      * @exception WebdavException Does not happen
109      */

110     protected void parseRequest() throws WebdavException {
111         super.parseRequest();
112         
113         versioningHelper =
114             VersioningHelper.getVersioningHelper(slideToken, token, req, resp, config);
115         labelHeader = WebdavUtils.fixTomcatHeader(requestHeaders.getLabel(), "UTF-8");
116     }
117     
118     /**
119      * Execute request.
120      *
121      * @exception WebdavException Unrecoverable error occured while copying
122      */

123     protected void executeRequest()
124         throws WebdavException, IOException JavaDoc {
125         
126         // Prevent dirty reads
127
slideToken.setForceStoreEnlistment(true);
128         
129         boolean isCollection = isCollection(sourceUri);
130         
131         // check lock-null resources
132
try {
133             if (isLockNull(sourceUri)) {
134                 int statusCode = WebdavStatus.SC_NOT_FOUND;
135                 sendError( statusCode, "lock-null resource", new Object JavaDoc[]{sourceUri} );
136                 throw new WebdavException( statusCode );
137             }
138         }
139         catch (ServiceAccessException e) {
140             int statusCode = getErrorCode((Exception JavaDoc)e);
141             sendError( statusCode, e );
142             throw new WebdavException( statusCode );
143         }
144         
145         // check destination URI
146
UriHandler destUh = UriHandler.getUriHandler(destinationUri);
147         
148         if (destUh.isRestrictedUri()) {
149             boolean sendError = true;
150             if( destUh.isWorkspaceUri() ||
151                destUh.isWorkingresourceUri()
152               ) {
153                 // COPY on existing WSs or WRs is *not* restricted !!!
154
try {
155                     if ( WebdavEvent.COPY.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(WebdavEvent.COPY, new WebdavEvent(this));
156                     
157                     content.retrieve(slideToken, destinationUri);
158                     sendError = false;
159                 }
160                 catch( SlideException x ) {
161                     int statusCode = getErrorCode((SlideException)x);
162                     sendError( statusCode, x );
163                     throw new WebdavException( statusCode );
164                 }
165             }
166             if( sendError ) {
167                 int statusCode = WebdavStatus.SC_FORBIDDEN;
168                 sendError( statusCode, getClass().getName()+".restrictedDestinationUri", new Object JavaDoc[]{destinationUri} );
169                 throw new WebdavException( statusCode );
170             }
171         }
172         
173         try {
174             // compare resource types of source and destination
175
int depth = requestHeaders.getDepth(INFINITY);
176             if (depth != 0 && depth != INFINITY) {
177                 int sc = WebdavStatus.SC_PRECONDITION_FAILED;
178                 sendError( sc, "Invalid header Depth: "+depth );
179                 throw new WebdavException( sc );
180             }
181             
182             boolean recursive = (depth == INFINITY);
183             
184             if (overwrite) {
185                 macroParameters = new MacroParameters(recursive, true, true);
186             } else {
187                 macroParameters = new MacroParameters(recursive, false, false);
188             }
189             
190             boolean destinationExistsBefore = exists( destinationUri );
191             
192             if (!overwrite && destinationExistsBefore) {
193                 int statusCode = WebdavStatus.SC_PRECONDITION_FAILED;
194                 sendError( statusCode, getClass().getName()+".noOverwrite", new Object JavaDoc[]{destinationUri} );
195                 throw new WebdavException( statusCode );
196             }
197             
198             macro.copy(slideToken, sourceUri, destinationUri, macroParameters, this, this, null, this);
199             
200             if (overwrite && destinationExistsBefore) {
201                 resp.setStatus(WebdavStatus.SC_NO_CONTENT);
202             } else {
203                 resp.setStatus(WebdavStatus.SC_CREATED);
204             }
205         } catch (MacroException e) {
206             if(generateMultiStatusResponse(isCollection, e, requestUri)) {
207                 String JavaDoc errorMessage = generateErrorMessage(e);
208                 // Write it on the servlet writer
209
resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
210                 try {
211                     resp.setContentType(TEXT_XML_UTF_8);
212                     resp.getWriter().write(errorMessage);
213                 } catch(IOException JavaDoc ex) {
214                     // Critical error ... Servlet container is dead or something
215
int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR;
216                     sendError( statusCode, e );
217                     throw new WebdavException( statusCode );
218                 }
219             } else {
220                 // Returning 207 on non-collection requests is generally
221
// considered bad. So let's not do it, since this way
222
// makes clients generally behave better.
223
SlideException exception = (SlideException)e.enumerateExceptions().nextElement();
224                 if (exception instanceof PreconditionViolationException) {
225                     try {
226                         sendPreconditionViolation((PreconditionViolationException)exception);
227                     } catch(IOException JavaDoc ex) {
228                         // Critical error ... Servlet container is dead or something
229
int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR;
230                         sendError( statusCode, e );
231                         throw new WebdavException( statusCode );
232                     }
233                 }
234                 else {
235                     int statusCode = getErrorCode( exception );
236                     sendError( statusCode, exception );
237                     throw new WebdavException( statusCode );
238                 }
239             }
240             //
241
// make sure the transaction is aborted
242
// throw any WebDAV exception to indicate the transaction wants to be aborted
243
//
244
throw new WebdavException(WebdavStatus.SC_ACCEPTED, false);
245         }
246         catch (WebdavException e) {
247             throw e;
248         }
249         catch (SlideException e) {
250             int statusCode = getErrorCode( e );
251             sendError( statusCode, e );
252             throw new WebdavException( statusCode );
253         }
254     }
255     
256     /**
257      * Get return status based on exception type.
258      */

259     protected int getErrorCode(SlideException ex) {
260         try {
261             throw ex;
262         } catch(RevisionNotFoundException e) {
263             return WebdavStatus.SC_NOT_FOUND;
264         } catch (SlideException e) {
265             return super.getErrorCode(e);
266         }
267     }
268     
269     /**
270      * Restores all live properties that should not be copied.
271      *
272      * @param destinationRevisionDescriptor the descriptor to restore.
273      * @param existingDestinationRevisionDescriptor the descriptor that has been overwritten.
274      */

275     private void restoreLiveProperties(String JavaDoc destinationUri, NodeRevisionDescriptor destinationNrd, NodeRevisionDescriptor existingNrd) {
276         
277         // remove all live properties
278
Enumeration propertyEnum = destinationNrd.enumerateProperties();
279         NodeProperty property = null;
280         while (propertyEnum.hasMoreElements()) {
281             property = (NodeProperty)propertyEnum.nextElement();
282             if (isLivePropertyToRestore(destinationUri, property)) {
283                 destinationNrd.removeProperty(property);
284             }
285         }
286         
287         // copy all live properties of the existing destination
288
propertyEnum = existingNrd.enumerateProperties();
289         property = null;
290         while (propertyEnum.hasMoreElements()) {
291             property = (NodeProperty)propertyEnum.nextElement();
292             if (isLivePropertyToRestore(destinationUri, property)) {
293                 destinationNrd.setProperty(property);
294             }
295         }
296     }
297     
298     /**
299      * Indicates if the given property is a live property to restore.
300      *
301      * @param property the NodeProperty to decide.
302      *
303      * @return <code>true</code> if this is a live property to restore.
304      */

305     private boolean isLivePropertyToRestore(String JavaDoc uri, NodeProperty property) {
306         boolean isLivePropertyToRestore = property.isLiveProperty() && (
307             DeltavConstants.DELTAV_PROPERTY_LIST.contains(property.getName()) ||
308                 AclConstants.ACL_PROPERTY_LIST.contains(property.getName()) ||
309                 BindConstants.BIND_PROPERTY_LIST.contains(property.getName()) ||
310                 P_CREATIONDATE.equals(property.getName()) ||
311             ( P_DISPLAYNAME.equals(property.getName()) &&
312                  Configuration.useBinding(token.getUri(slideToken, uri).getStore()) )
313         );
314         return isLivePropertyToRestore;
315     }
316     
317     /**
318      * Sets all DeltaV specific properties of the given NodeRevisionDescriptor
319      * to their initial value.
320      *
321      * @param revisionDescriptor the NodeRevisionDescriptor whose DeltaV
322      * properties should be reset.
323      */

324     private void resetDeltavProperties(NodeRevisionDescriptor revisionDescriptor, String JavaDoc resourcePath) {
325         
326         // use initial values for DeltaV properties
327
PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(slideToken, token, getConfig());
328         ResourceKind resourceKind = VersionableImpl.getInstance();
329         Iterator initialPropertyIterator =
330             propertyHelper.createInitialProperties(resourceKind, resourcePath).iterator();
331         NodeProperty property = null;
332         List initialDeltavProperties = new ArrayList();
333         while (initialPropertyIterator.hasNext()) {
334             property = (NodeProperty)initialPropertyIterator.next();
335             if (DeltavConstants.DELTAV_PROPERTY_LIST.contains(property.getName())) {
336                 initialDeltavProperties.add(property);
337             }
338         }
339         
340         Enumeration propertyEnum = revisionDescriptor.enumerateProperties();
341         property = null;
342         int index = 0;
343         while (propertyEnum.hasMoreElements()) {
344             property = (NodeProperty)propertyEnum.nextElement();
345             if (DeltavConstants.DELTAV_PROPERTY_LIST.contains(property.getName())) {
346                 index = initialDeltavProperties.indexOf(property);
347                 if (index >= 0) {
348                     revisionDescriptor.setProperty((NodeProperty)initialDeltavProperties.get(index));
349                 }
350                 else {
351                     revisionDescriptor.removeProperty(property);
352                 }
353             }
354         }
355     }
356     
357     /**
358      * Restores the "backup" NodeRevisionDescriptor which has been saved in
359      * method {@link #beforeDelete beforeDelete()}.
360      *
361      * @param destinationUri the Uri of the resource.
362      * @param destinationRevisionDescriptors the NodeRevisionDescriptors of
363      * the resource.
364      */

365     private void restoreBackupRevisionDescriptor(String JavaDoc destinationUri, NodeRevisionDescriptors destinationNrds) throws RevisionNotFoundException, ServiceAccessException, RevisionAlreadyExistException, ObjectNotFoundException, LinkedObjectNotFoundException, ObjectLockedException, AccessDeniedException, RevisionDescriptorNotFoundException, BranchNotFoundException, NodeNotVersionedException, VetoException {
366         
367         NodeRevisionDescriptor backupNrd =
368             (NodeRevisionDescriptor)destinationBackupDescriptorMap.get(destinationUri);
369         if (backupNrd != null) {
370             try {
371                 content.retrieve( slideToken,
372                                  destinationNrds,
373                                  NodeRevisionNumber.HIDDEN_0_0 );
374                 content.store( slideToken,
375                               destinationNrds.getUri(),
376                               backupNrd,
377                               null );
378             }
379             catch (RevisionDescriptorNotFoundException e) {
380                 content.create( slideToken,
381                                destinationNrds.getUri(),
382                                null,
383                                backupNrd,
384                                null ); // branch=null, revisionContent=null
385
}
386         }
387     }
388     
389     
390     // ------------------------------------------------------ Interface CopyRouteRedirector
391

392     /**
393      * Returns the (redirected) CopyRoute to use. Must not be <code>null</code>.
394      *
395      * @param the original CopyRoute.
396      *
397      * @return the (redirected) CopyRoute to use.
398      *
399      * @throws SlideException this Exception will be passed to the caller
400      * of the Macro helper (contained in the
401      * MacroCopyException).
402      */

403     public CopyRoute getRedirectedCopyRoute(CopyRoute copyRoute) throws SlideException {
404         
405         if (Configuration.useVersionControl()) {
406             
407             String JavaDoc sourceUri = copyRoute.getSourceUri();
408             String JavaDoc destinationUri = copyRoute.getDestinationUri();
409             
410             try {
411                 sourceUri = versioningHelper.getLabeledResourceUri(sourceUri, labelHeader);
412                 copyRoute = new CopyRoute(sourceUri, destinationUri);
413             }
414             catch (LabeledRevisionNotFoundException e) {
415                 ViolatedPrecondition violatedPrecondition =
416                     new ViolatedPrecondition(DeltavConstants.C_MUST_SELECT_VERSION_IN_HISTORY,
417                                              WebdavStatus.SC_CONFLICT);
418                 throw new PreconditionViolationException(violatedPrecondition, sourceUri);
419             }
420         }
421         
422         return copyRoute;
423     }
424     
425     
426     // ------------------------------------------------------ Interface CopyListener
427

428     /**
429      * This method is called prior to copying the resource associated by
430      * the given <code>sourceUri</code>. The copy can be prohibited by
431      * throwing a SlideException.
432      *
433      * @param sourceUri the Uri of the resource that will be copied.
434      * @param destinationUri the Uri of the copy.
435      *
436      * @throws SlideException this Exception will be passed to the caller
437      * of the Macro helper (contained in the
438      * MacroDeleteException.
439      */

440     public void beforeCopy(String JavaDoc sourceUri, String JavaDoc destinationUri, boolean isRootOfCopy) throws SlideException {
441         if(Configuration.useVersionControl()) {
442             
443             UriHandler sourceUh = UriHandler.getUriHandler(sourceUri);
444             if (sourceUh.isHistoryUri()) {
445                 throw new PreconditionViolationException(
446                     new ViolatedPrecondition(DeltavConstants.C_CANNOT_COPY_HISTORY, WebdavStatus.SC_FORBIDDEN), sourceUri);
447             }
448             
449             if (!macroParameters.isDeleteCreate()) {
450                 beforeUpdateOrDelete( destinationUri );
451             }
452         }
453         if (isRootOfCopy && Configuration.useBinding(token.getUri(slideToken, destinationUri).getStore())) {
454             // collect the parent bindings of the destination node
455
Map parentBindings = new HashMap();
456             try {
457                 NodeRevisionDescriptor destinationNrd =
458                     content.retrieve( slideToken, content.retrieve(slideToken, destinationUri) );
459                 XMLValue v = new XMLValue( (String JavaDoc)destinationNrd.getProperty( P_PARENT_SET ).getValue() );
460                 Iterator i = v.iterator();
461                 while (i.hasNext()) {
462                     Namespace dnsp = Namespace.getNamespace(S_DAV);
463                     Element parentElm = (Element)i.next();
464                     String JavaDoc segment = parentElm.getChild(E_SEGMENT, dnsp).getTextTrim();
465                     String JavaDoc href = parentElm.getChild(E_HREF, dnsp).getTextTrim();
466                     parentBindings.put( href, segment );
467                 }
468             }
469             catch( ServiceAccessException x ) {
470                 throw x;
471             }
472             catch (SlideException e) {}
473             catch (JDOMException e) {}
474             macroParameters.setParameter( Macro.PARENT_BINDINGS, parentBindings );
475         }
476     }
477     
478     /**
479      * This method is called after copying the resource to
480      * the given <code>destinationUri</code>.
481      *
482      * @param sourceUri the Uri of the resource that has been copied.
483      * @param destinationUri the Uri of the copy.
484      *
485      * @throws SlideException this Exception will be passed to the caller
486      * of the Macro helper (contained in the
487      * MacroDeleteException.
488      */

489     public void afterCopy(String JavaDoc sourceUri, String JavaDoc destinationUri, boolean isRootOfCopy, boolean destinationExists) throws SlideException {
490         
491         if(Configuration.useVersionControl()) {
492             
493             NodeRevisionDescriptors destinationNrds = content.retrieve( slideToken, destinationUri);
494             NodeRevisionDescriptor destinationNrd = content.retrieve( slideToken, destinationNrds);
495             
496             // restore backup descriptor
497
restoreBackupRevisionDescriptor(destinationUri, destinationNrds);
498             
499             NodeRevisionDescriptor existingNrd =
500                 (NodeRevisionDescriptor)destinationDescriptorMap.get(destinationUri);
501             if (existingNrd != null) {
502                 
503                 // there has been an existing destination, so restore live properties
504
restoreLiveProperties(destinationUri, destinationNrd, existingNrd);
505             }
506             else {
507                 
508                 // DAV:must-not-copy-versioning-property
509
resetDeltavProperties(destinationNrd, destinationUri);
510             }
511             
512             // set <workspace> property
513
versioningHelper.setWorkspaceProperty(destinationUri, destinationNrd);
514             
515             // set some other properties
516
destinationNrd.setLastModified( new Date() ); // P_GETLASTMODIFIED
517
destinationNrd.setETag( PropertyHelper.computeEtag(destinationUri, destinationNrd) ); // P_GETETAG
518
if (!destinationExists) {
519                 // copy is creating a new resource
520
String JavaDoc creator = ((SubjectNode)security.getPrincipal(slideToken)).getPath().lastSegment();
521                 destinationNrd.setOwner(creator);
522             }
523             
524             content.store(slideToken, destinationNrds.getUri(), destinationNrd, null);
525             
526             // checkin if necessary
527
boolean mustCheckin = versioningHelper.mustCheckinAutoVersionedVCR(slideToken, destinationNrds, destinationNrd);
528             if (mustCheckin) {
529                 try {
530                     versioningHelper.checkin(destinationUri, false, false, true ); //forkOk=false, keepCheckedOut=false
531
}
532                 catch (IOException JavaDoc e) {
533                     throw new SlideException("Checkin failed: " + e.getMessage());
534                 }
535                 catch (JDOMException e) {
536                     throw new SlideException("Checkin failed: " + e.getMessage());
537                 }
538             }
539             
540             // check if the resource should be put under version-control
541
if( isAutoVersionControl(destinationUri) && !isCollection(destinationUri) && !isExcludedForVersionControl(destinationUri) ) {
542                 versioningHelper.versionControl(destinationUri);
543             }
544             
545         }
546         if (isRootOfCopy && Configuration.useBinding(token.getUri(slideToken, destinationUri).getStore())) {
547             // try to restore the parent bindings
548
if (macroParameters.getParameter(Macro.PARENT_BINDINGS) != null) {
549                 Map parentBindings = (Map)macroParameters.getParameter(Macro.PARENT_BINDINGS);
550                 Iterator i = parentBindings.entrySet().iterator();
551                 while (i.hasNext()) {
552                     Map.Entry me = (Map.Entry)i.next();
553                     ObjectNode parentNode = structure.retrieve( slideToken, (String JavaDoc)me.getKey() );
554                     ObjectNode destinationNode = structure.retrieve( slideToken, destinationUri );
555                     String JavaDoc segment = (String JavaDoc)me.getValue();
556                     structure.addBinding( slideToken, parentNode, segment, destinationNode );
557                 }
558             }
559         }
560     }
561     
562     
563     
564     // ------------------------------------------------------ Interface DeleteListener
565

566     /**
567      * This method is called prior to deleting the resource associated by
568      * the given <code>targetUri</code>. The deletion can be prohibited by
569      * throwing a SlideException.
570      *
571      * @param destinationUri the Uri of the resource that will be deleted.
572      *
573      * @throws SlideException this Exception will be passed to the caller
574      * of the Macro helper (contained in the
575      * MacroDeleteException.
576      */

577     public void beforeDelete(String JavaDoc destinationUri) throws SlideException {
578         beforeUpdateOrDelete( destinationUri );
579     }
580     
581     /**
582      * This method is called prior to deleting the resource associated by
583      * the given <code>targetUri</code>. The deletion can be prohibited by
584      * throwing a SlideException.
585      *
586      * @param destinationUri the Uri of the resource that will be deleted.
587      *
588      * @throws SlideException this Exception will be passed to the caller
589      * of the Macro helper (contained in the
590      * MacroDeleteException.
591      */

592     private void beforeUpdateOrDelete(String JavaDoc destinationUri) throws SlideException {
593         if( Configuration.useVersionControl() ) {
594             NodeRevisionDescriptors destinationNrds = null;
595             NodeRevisionDescriptor destinationNrd = null;
596             
597             try {
598                 destinationNrds = content.retrieve( slideToken, destinationUri);
599                 destinationNrd = content.retrieve( slideToken, destinationNrds);
600             }
601             catch (ObjectNotFoundException e) {}
602             
603             if (destinationNrds != null && destinationNrd != null) {
604                 
605                 ResourceKind resourceKind = AbstractResourceKind.determineResourceKind(token, destinationUri, destinationNrd);
606                 if (resourceKind instanceof CheckedInVersionControlled) {
607                     
608                     // check precondition DAV:cannot-modify-version-controlled-content
609
String JavaDoc autoVersion = versioningHelper.getAutoVersionElementName(destinationNrd);
610                     if (autoVersion == null) {
611                         autoVersion = "";
612                     }
613                     if ( !E_CHECKOUT_CHECKIN.equals(autoVersion) &&
614                         !E_CHECKOUT_UNLOCKED_CHECKIN.equals(autoVersion) &&
615                         !E_CHECKOUT.equals(autoVersion) &&
616                         !E_CHECKOUT_IGNORE_UNLOCK.equals(autoVersion) &&
617                         !E_LOCKED_CHECKOUT.equals(autoVersion) ) {
618                         throw new PreconditionViolationException(new ViolatedPrecondition(C_CANNOT_MODIFY_VERSION_CONTROLLED_CONTENT,
619                                                                                           WebdavStatus.SC_FORBIDDEN), destinationUri);
620                     }
621                     if ( E_LOCKED_CHECKOUT.equals(autoVersion) &&
622                             ( !versioningHelper.isWriteLocked(slideToken, destinationNrds) ) ) {
623                         throw new PreconditionViolationException(new ViolatedPrecondition(C_CANNOT_MODIFY_VERSION_CONTROLLED_CONTENT,
624                                                                                           WebdavStatus.SC_FORBIDDEN), destinationUri);
625                     }
626                 }
627                 
628                 // check precondition DAV:cannot-modify-version
629
UriHandler uriHandler = UriHandler.getUriHandler(destinationUri);
630                 if (uriHandler.isVersionUri()) {
631                     throw new PreconditionViolationException(new ViolatedPrecondition(C_CANNOT_MODIFY_VERSION,
632                                                                                       WebdavStatus.SC_FORBIDDEN), destinationUri);
633                 }
634                 
635                 // checkout if necessary
636
if( Configuration.useVersionControl() &&
637                        (resourceKind instanceof CheckedInVersionControlled) &&
638                    versioningHelper.mustCheckoutAutoVersionedVCR(destinationNrds, destinationNrd) ) {
639                     
640                     try {
641                         versioningHelper.checkout(destinationNrds, destinationNrd, false, false, true );
642                     }
643                     catch (IOException JavaDoc e) {
644                         throw new SlideException("Checkout failed: " + e.getMessage());
645                     }
646                     catch (JDOMException e) {
647                         throw new SlideException("Checkout failed: " + e.getMessage());
648                     }
649                 }
650                 
651                 // store the descriptor(s) in order to restore it in afterDelete()
652
// (the COPY specification for DeltaV says that an existing destination
653
// must not be deleted)
654
try {
655                     NodeRevisionDescriptor backupNrd =
656                         content.retrieve( slideToken, destinationNrds, NodeRevisionNumber.HIDDEN_0_0 );
657                     destinationBackupDescriptorMap.put(destinationUri, backupNrd);
658                 }
659                 catch (RevisionDescriptorNotFoundException e) {
660                 }
661                 destinationDescriptorMap.put(destinationUri, destinationNrd);
662             }
663         }
664     }
665     
666     /**
667      * This method is called after deleting the resource associated by
668      * the given <code>targetUri</code>.
669      *
670      * @param targetUri the Uri of the resource that has been deleted.
671      *
672      * @throws SlideException this Exception will be passed to the caller
673      * of the Macro helper (contained in the
674      * targetUricroDeleteException.
675      */

676     public void afterDelete(String JavaDoc targetUri) throws SlideException {
677     }
678     
679     
680     
681     
682 }
683
684
685
686
687
688
689
Popular Tags