KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PutMethod.java,v 1.81.2.5 2004/10/30 18:51:13 unico Exp $
3  * $Revision: 1.81.2.5 $
4  * $Date: 2004/10/30 18:51:13 $
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.io.IOException JavaDoc;
27 import java.util.Date JavaDoc;
28
29 import org.apache.slide.common.NamespaceAccessToken;
30 import org.apache.slide.common.ServiceAccessException;
31 import org.apache.slide.common.SlideException;
32 import org.apache.slide.content.NodeProperty;
33 import org.apache.slide.content.NodeRevisionContent;
34 import org.apache.slide.content.NodeRevisionDescriptor;
35 import org.apache.slide.content.NodeRevisionDescriptors;
36 import org.apache.slide.content.NodeRevisionNumber;
37 import org.apache.slide.content.RevisionAlreadyExistException;
38 import org.apache.slide.content.RevisionDescriptorNotFoundException;
39 import org.apache.slide.event.EventDispatcher;
40 import org.apache.slide.structure.LinkedObjectNotFoundException;
41 import org.apache.slide.structure.ObjectAlreadyExistsException;
42 import org.apache.slide.structure.ObjectNotFoundException;
43 import org.apache.slide.structure.SubjectNode;
44 import org.apache.slide.util.Configuration;
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.DeltavConstants;
49 import org.apache.slide.webdav.util.PreconditionViolationException;
50 import org.apache.slide.webdav.util.PropertyHelper;
51 import org.apache.slide.webdav.util.UriHandler;
52 import org.apache.slide.webdav.util.VersioningHelper;
53 import org.apache.slide.webdav.util.ViolatedPrecondition;
54 import org.apache.slide.webdav.util.WebdavStatus;
55 import org.apache.slide.webdav.util.WebdavUtils;
56 import org.apache.slide.webdav.util.resourcekind.AbstractResourceKind;
57 import org.apache.slide.webdav.util.resourcekind.CheckedInVersionControlled;
58 import org.apache.slide.webdav.util.resourcekind.ResourceKind;
59
60 /**
61  * PUT method.
62  *
63  */

64 public class PutMethod
65     extends AbstractWebdavMethod
66     implements DeltavConstants, WriteMethod {
67
68
69     // ----------------------------------------------------- Instance Variables
70

71     /**
72      * The VersioningHelper used by this instance.
73      */

74     protected VersioningHelper versioningHelper = null;
75     
76     /**
77      * Resource to be written.
78      */

79     protected String JavaDoc resourcePath;
80     
81     // ----------------------------------------------------------- Constructors
82

83     
84     /**
85      * Constructor.
86      *
87      * @param token the token for accessing the namespace
88      * @param config configuration of the WebDAV servlet
89      */

90     public PutMethod(NamespaceAccessToken token, WebdavServletConfig config) {
91         super(token, config);
92     }
93
94     // ------------------------------------------------------ Protected Methods
95

96     
97     /**
98      * Parse XML request.
99      *
100      * @exception WebdavException Does not happen
101      */

102     protected void parseRequest()
103         throws WebdavException {
104         versioningHelper = VersioningHelper.getVersioningHelper(slideToken,
105                                                                 token,
106                                                                 req,
107                                                                 resp,
108                                                                 config);
109         
110         resourcePath = requestUri;
111         if (resourcePath == null) {
112             resourcePath = "/";
113         }
114     }
115     
116     /**
117      * Execute request.
118      *
119      * @exception WebdavException Bad request
120      */

121     protected void executeRequest()
122         throws WebdavException, IOException JavaDoc {
123         
124         // Prevent dirty reads
125
slideToken.setForceStoreEnlistment(true);
126
127         // check destination URI
128
UriHandler destUh = UriHandler.getUriHandler(resourcePath);
129         
130         if (destUh.isRestrictedUri()) {
131             boolean sendError = true;
132             if( destUh.isWorkingresourceUri() ) {
133                 // PUT on existing WRs is *not* restricted !!!
134
try {
135                     content.retrieve(slideToken, resourcePath);
136                     sendError = false;
137                 }
138                 catch( Exception JavaDoc x ) {};
139             }
140             if( sendError ) {
141                 int statusCode = WebdavStatus.SC_FORBIDDEN;
142                 sendError( statusCode, getClass().getName()+".restrictedDestinationUri", new Object JavaDoc[]{resourcePath} );
143                 throw new WebdavException( statusCode );
144             }
145         }
146         
147         try {
148             // fire put event
149
if ( WebdavEvent.PUT.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(WebdavEvent.PUT, new WebdavEvent(this));
150
151             try {
152
153                 boolean isLockedNullResource = false;
154                 
155                 NodeRevisionDescriptors revisionDescriptors =
156                     content.retrieve(slideToken, resourcePath);
157                 
158                 NodeRevisionNumber revisionNumber =
159                     revisionDescriptors.getLatestRevision();
160                 NodeRevisionDescriptor oldRevisionDescriptor = null;
161                 if (revisionNumber != null) {
162                     try {
163                         oldRevisionDescriptor = content.retrieve
164                             (slideToken, revisionDescriptors);
165                     } catch (RevisionDescriptorNotFoundException e) {
166                     }
167                 }
168                 if (WebdavUtils.isCollection(oldRevisionDescriptor)) {
169                     int statusCode = WebdavStatus.SC_METHOD_NOT_ALLOWED;
170                     sendError( statusCode, getClass().getName()+".mustNotBeCollection" );
171                     throw new WebdavException( statusCode );
172                 }
173                 
174                 NodeRevisionDescriptor revisionDescriptor = null;
175                 if (oldRevisionDescriptor == null) {
176                     revisionDescriptor = new NodeRevisionDescriptor();
177                 } else {
178                     revisionDescriptor = oldRevisionDescriptor;
179                     revisionDescriptor.setContentLength(-1);
180                 }
181                 
182                 ResourceInfo resourceInfo =
183                     new ResourceInfo(resourcePath, revisionDescriptor);
184                 
185                 // Checking If headers
186
if (!checkIfHeaders(req, resp, resourceInfo)) {
187                     return;
188                 }
189                 
190                 ResourceKind resourceKind = AbstractResourceKind.determineResourceKind(token, resourcePath, revisionDescriptor);
191                 
192                 versioningHelper.isWriteLocked(slideToken, revisionDescriptors);
193                 
194                 // check preconditions
195
ViolatedPrecondition violatedPrecondition = getPreconditionViolation(revisionDescriptors, revisionDescriptor, resourceKind);
196                 if (violatedPrecondition != null) {
197                     throw new PreconditionViolationException(violatedPrecondition, resourcePath);
198                 }
199                 
200                 // Changed for DeltaV --start--
201
boolean mustCheckIn = false;
202                 if( Configuration.useVersionControl() &&
203                        (resourceKind instanceof CheckedInVersionControlled) &&
204                    versioningHelper.mustCheckoutAutoVersionedVCR(revisionDescriptors, revisionDescriptor) ) {
205                     
206                     versioningHelper.checkout(revisionDescriptors, revisionDescriptor, false, false, true );
207                     mustCheckIn = versioningHelper.mustCheckinAutoVersionedVCR(slideToken, revisionDescriptors, revisionDescriptor);
208                 }
209                 // Changed for DeltaV --end--
210

211                 NodeRevisionContent revisionContent =
212                     new NodeRevisionContent();
213                 //revisionContent.setContent(req.getReader());
214

215                 revisionContent.setContent(req.getInputStream());
216                 
217                 // Get content length
218
int contentLength = req.getContentLength();
219                 if (contentLength == (-1)) {
220                     contentLength = revisionContent.getContentBytes().length;
221                 }
222                 revisionDescriptor.setContentLength(contentLength);
223                 
224                 // Last modification date
225
revisionDescriptor.setLastModified(new Date JavaDoc());
226                 
227                 // Etag generation
228
revisionDescriptor.setETag(PropertyHelper.computeEtag(resourcePath, revisionDescriptor) );
229                 
230                 // Get content type (allow content-type to be updated here)
231
String JavaDoc contentType = req.getContentType();
232                 if (contentType == null) {
233                     contentType = getConfig().getServletContext()
234                         .getMimeType(resourcePath);
235                 }
236                 if (contentType == null) {
237                     contentType = getConfig().getDefaultMimeType();
238                 }
239                 revisionDescriptor.setContentType(contentType);
240                 
241                 // Normally assume the 'getcontentlanguage'
242
// is set, however, before we clear the
243
// 'resourcetype' need to check for the case when a
244
// 'lock-null' is created just before the initial PUT. In
245
// that case need to add the missing properties.
246
if (isLockNull(revisionDescriptor)) {
247                     // if (revisionDescriptor.getResourceType().equals("<lock-null/>")) {
248
isLockedNullResource = true;
249                     revisionDescriptor.setContentLanguage("en");
250                     
251                     // Changed for DeltaV --start--
252
if( Configuration.useVersionControl() ) {
253                         // Workspace
254
versioningHelper.setWorkspaceProperty( resourcePath, revisionDescriptor );
255                     }
256                     // Changed for DeltaV --end--
257
}
258                 
259                 // Resource type
260
revisionDescriptor.setResourceType("");
261                 
262                 // Owner
263
if ( isLockedNullResource ) {
264                     // set the owner when updating a lock-null resource
265
String JavaDoc creator = ((SubjectNode)security.getPrincipal(slideToken)).getPath().lastSegment();
266                     revisionDescriptor.setCreationUser(creator);
267                     revisionDescriptor.setOwner(creator);
268                 }
269                 
270                 content.store(slideToken, resourcePath, revisionDescriptor,
271                               revisionContent);
272                 
273                 // Changed for DeltaV --start--
274
// check if the resource should be put under version-control
275
if ( isLockedNullResource ) {
276                     if ( Configuration.useVersionControl() && isAutoVersionControl(resourcePath) && !isExcludedForVersionControl(resourcePath) ) {
277                         versioningHelper.versionControl(resourcePath);
278                     }
279                 }
280                 if( Configuration.useVersionControl() && mustCheckIn) {
281                     versioningHelper.checkin(revisionDescriptors, revisionDescriptor, false, false, true ); //forkOk=false, keepCheckedOut=false
282
}
283                 // Changed for DeltaV --end--
284

285                 
286                 // ETag header
287
resp.setHeader("ETag", revisionDescriptor.getETag() );
288                 
289                 resp.setStatus(WebdavStatus.SC_NO_CONTENT);
290                 
291             } catch (LinkedObjectNotFoundException e) {
292                 int statusCode = getErrorCode( e );
293                 sendError( statusCode, e );
294                 throw new WebdavException( statusCode );
295             } catch (ObjectNotFoundException e) {
296                 SubjectNode subject = new SubjectNode();
297                 // Creating an object
298
structure.create(slideToken, subject, resourcePath);
299                 
300                 NodeRevisionDescriptor revisionDescriptor =
301                     new NodeRevisionDescriptor(req.getContentLength());
302                 
303                 ResourceInfo resourceInfo =
304                     new ResourceInfo(resourcePath, revisionDescriptor);
305                 resourceInfo.exists = false;
306                 
307                 // Checking If headers
308
if (!checkIfHeaders(req, resp, resourceInfo)) {
309                     int statusCode = WebdavStatus.SC_PRECONDITION_FAILED;
310                     sendError( statusCode, "Check If Header failed" );
311                     throw new WebdavException( statusCode );
312                 }
313                 
314                 //NodeProperty property = null;
315

316                 // Creation date
317

318                 // Resource type
319
revisionDescriptor.setResourceType("");
320                 
321                 // Source
322
revisionDescriptor.setSource("");
323                 
324                 // Get content language
325
revisionDescriptor.setContentLanguage("en");
326                 
327                 // Get content type
328
String JavaDoc contentType = req.getContentType();
329                 if (contentType == null) {
330                     contentType = getConfig().getServletContext()
331                         .getMimeType(resourcePath);
332                 }
333                 if (contentType == null) {
334                     contentType = getConfig().getDefaultMimeType();
335                 }
336                 revisionDescriptor.setContentType(contentType);
337                 
338                 // Last modification date
339
revisionDescriptor.setLastModified(new Date JavaDoc());
340                 
341                 // Etag generation
342
revisionDescriptor.setETag(PropertyHelper.computeEtag(resourcePath, revisionDescriptor));
343                 
344                 // Creation date
345
revisionDescriptor.setCreationDate(new Date JavaDoc());
346                 
347                 // Owner
348
String JavaDoc creator = ((SubjectNode)security.getPrincipal(slideToken)).getPath().lastSegment();
349                 revisionDescriptor.setCreationUser(creator);
350                 revisionDescriptor.setOwner(creator);
351                 
352                 // Added for DeltaV --start--
353
if( Configuration.useVersionControl() ) {
354                     // Workspace
355
versioningHelper.setWorkspaceProperty( resourcePath, revisionDescriptor );
356                 }
357                 // Added for DeltaV --end--
358

359                 if (isMsProprietarySupport()) {
360                     NodeProperty property = null;
361                     // Is hidden
362
property = new NodeProperty("ishidden", "0", "MICROSOFT");
363                     revisionDescriptor.setProperty(property);
364                     
365                     // Is collection
366
property = new NodeProperty("iscollection", "0",
367                                                 "MICROSOFT");
368                     revisionDescriptor.setProperty(property);
369                     
370                     // Is read only
371
property = new NodeProperty("isreadonly", "0",
372                                                 "MICROSOFT");
373                     revisionDescriptor.setProperty(property);
374                     
375                     // Last accessed
376
property = new NodeProperty("lastaccessed",
377                                                     (new Date JavaDoc()).toString(),
378                                                 "MICROSOFT");
379                     revisionDescriptor.setProperty(property);
380                     
381                 }
382                 
383                 // Creating revisionDescriptor associated with the object
384
NodeRevisionContent revisionContent =
385                     new NodeRevisionContent();
386                 revisionContent.setContent(req.getInputStream());
387                 
388                 // Get content length
389
int contentLength = req.getContentLength();
390                 if (contentLength == -1) {
391                     contentLength = revisionContent.getContentBytes().length;
392                 }
393                 revisionDescriptor.setContentLength(contentLength);
394                 
395                 content.create(slideToken, resourcePath, revisionDescriptor,
396                                revisionContent);
397                 
398                 // check if the resource should be put under version-control
399
if ( Configuration.useVersionControl() && isAutoVersionControl(resourcePath) && !isExcludedForVersionControl(resourcePath) ) {
400                     versioningHelper.versionControl(resourcePath);
401                 }
402                 
403                 // ETag header
404
resp.setHeader("ETag", revisionDescriptor.getETag() );
405                 
406                 resp.setStatus(WebdavStatus.SC_CREATED);
407                 
408             }
409         }
410         catch (PreconditionViolationException e) {
411             sendPreconditionViolation(e);
412             throw e;
413         }
414         catch (SlideException e) {
415             int statusCode = getErrorCode( e );
416             sendError( statusCode, e );
417             throw new WebdavException( statusCode );
418         }
419         catch (Exception JavaDoc e) {
420             int statusCode = getErrorCode( e );
421             sendError( statusCode, e );
422             throw new WebdavException( statusCode );
423         }
424     }
425     
426     /**
427      * Checks the (DeltaV) preconditions
428      * <ul>
429      * <li>&lt;DAV:cannot-modify-version-controlled-content&gt;</li>
430      * <li>&lt;DAV:cannot-modify-version&gt;</li>
431      * </ul>
432      *
433      * @param revisionDescriptors the NodeRevisionDescriptors of the resource
434      * to perform the <code>PUT</code> on.
435      * @param revisionDescriptor the NodeRevisionDescriptor of the resource
436      * to perform the <code>PUT</code> on.
437      * @param resourceKind the ResourceKind of the resource.
438      *
439      * @return the precondition that has been violated (if any).
440      */

441     private ViolatedPrecondition getPreconditionViolation(NodeRevisionDescriptors revisionDescriptors, NodeRevisionDescriptor revisionDescriptor, ResourceKind resourceKind)
442         throws ServiceAccessException {
443         
444         if( Configuration.useVersionControl() ) {
445             
446             if (resourceKind instanceof CheckedInVersionControlled) {
447                 
448                 // check precondition DAV:cannot-modify-version-controlled-content
449
String JavaDoc autoVersion = versioningHelper.getAutoVersionElementName(revisionDescriptor);
450                 if (autoVersion == null) {
451                     autoVersion = "";
452                 }
453                 if ( !E_CHECKOUT_CHECKIN.equals(autoVersion) &&
454                     !E_CHECKOUT_UNLOCKED_CHECKIN.equals(autoVersion) &&
455                     !E_CHECKOUT.equals(autoVersion) &&
456                     !E_CHECKOUT_IGNORE_UNLOCK.equals(autoVersion) &&
457                     !E_LOCKED_CHECKOUT.equals(autoVersion) ) {
458                     return new ViolatedPrecondition(C_CANNOT_MODIFY_VERSION_CONTROLLED_CONTENT,
459                                                     WebdavStatus.SC_FORBIDDEN);
460                 }
461                 if ( E_LOCKED_CHECKOUT.equals(autoVersion) &&
462                         ( !versioningHelper.isWriteLocked(slideToken, revisionDescriptors) ) ) {
463                     return new ViolatedPrecondition(C_CANNOT_MODIFY_VERSION_CONTROLLED_CONTENT,
464                                                     WebdavStatus.SC_FORBIDDEN);
465                 }
466             }
467             
468             // check precondition DAV:cannot-modify-version
469
UriHandler uriHandler = UriHandler.getUriHandler(resourcePath);
470             if (uriHandler.isVersionUri()) {
471                 return new ViolatedPrecondition(C_CANNOT_MODIFY_VERSION,
472                                                 WebdavStatus.SC_FORBIDDEN);
473             }
474         }
475         return null;
476     }
477     
478     
479     
480     
481     
482     
483     /**
484      * Get return status based on exception type.
485      */

486     protected int getErrorCode(SlideException ex) {
487         try {
488             throw ex;
489         } catch (RevisionAlreadyExistException e) {
490             return WebdavStatus.SC_CONFLICT;
491         } catch (ObjectAlreadyExistsException e) {
492             return WebdavStatus.SC_CONFLICT;
493         } catch (ObjectNotFoundException e) {
494             return WebdavStatus.SC_CONFLICT;
495         } catch (LinkedObjectNotFoundException e) {
496             return WebdavStatus.SC_NOT_FOUND;
497         } catch (SlideException e) {
498             return super.getErrorCode(e);
499         } catch (Exception JavaDoc e) {
500             return super.getErrorCode(e);
501         }
502     }
503 }
504
505
506
507
508
Popular Tags