KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > slide > content > ContentImpl


1 /*
2  * $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/content/ContentImpl.java,v 1.60 2004/08/05 15:44:57 unico Exp $
3  * $Revision: 1.60 $
4  * $Date: 2004/08/05 15:44:57 $
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.content;
25
26 import java.lang.reflect.Method JavaDoc;
27 import java.util.Date JavaDoc;
28 import java.util.Enumeration JavaDoc;
29 import java.util.Vector JavaDoc;
30
31 import org.apache.slide.common.Domain;
32 import org.apache.slide.common.Namespace;
33 import org.apache.slide.common.NamespaceConfig;
34 import org.apache.slide.common.ServiceAccessException;
35 import org.apache.slide.common.SlideToken;
36 import org.apache.slide.common.Uri;
37 import org.apache.slide.common.UriPath;
38 import org.apache.slide.lock.Lock;
39 import org.apache.slide.lock.ObjectLockedException;
40 import org.apache.slide.security.AccessDeniedException;
41 import org.apache.slide.security.Security;
42 import org.apache.slide.structure.ActionNode;
43 import org.apache.slide.structure.LinkedObjectNotFoundException;
44 import org.apache.slide.structure.ObjectNode;
45 import org.apache.slide.structure.ObjectNotFoundException;
46 import org.apache.slide.structure.Structure;
47 import org.apache.slide.structure.SubjectNode;
48 import org.apache.slide.util.Configuration;
49 import org.apache.slide.event.EventDispatcher;
50 import org.apache.slide.event.ContentEvent;
51 import org.apache.slide.event.VetoException;
52
53 /**
54  * Implementation of the content interface.
55  *
56  * @version $Revision: 1.60 $
57  */

58 public final class ContentImpl implements Content {
59     
60     
61     // -------------------------------------------------------------- Constants
62
protected static final String JavaDoc I_URIREDIRECTORCLASS = "uriRedirectorClass";
63     protected static final String JavaDoc I_URIREDIRECTORCLASS_DEFAULT = "org.apache.slide.webdav.util.DeltavUriRedirector";
64     
65     
66     protected static final int PRE_STORE = 0;
67     protected static final int POST_STORE = 1;
68     protected static final int POST_RETRIEVE = 2;
69     protected static final int PRE_REMOVE = 3;
70     protected static final int POST_REMOVE = 4;
71     
72     protected static Class JavaDoc uriRedirectorClass;
73     static {
74         try {
75             String JavaDoc uriRedirectorClassName = Domain.getParameter(I_URIREDIRECTORCLASS, I_URIREDIRECTORCLASS_DEFAULT);
76             uriRedirectorClass = Class.forName( uriRedirectorClassName );
77         }
78         catch( Exception JavaDoc x ) {
79             Domain.warn( "Loading of redirector class failed: "+x.getMessage() );
80         }
81     }
82     
83     // ----------------------------------------------------------- Constructors
84

85     
86     /**
87      * Constructor.
88      *
89      * @param namespace Namespace
90      * @param namespaceConfig Namespace configuration
91      * @param securityHelper Security helper
92      * @param structureHelper Structure helper
93      * @param lockHelper lockHelper
94      */

95     public ContentImpl(Namespace namespace, NamespaceConfig namespaceConfig,
96                        Security securityHelper, Structure structureHelper,
97                        Lock lockHelper) {
98         this.namespace = namespace;
99         this.namespaceConfig = namespaceConfig;
100         this.securityHelper = securityHelper;
101         this.structureHelper = structureHelper;
102         this.lockHelper = lockHelper;
103     }
104     
105     
106     // ----------------------------------------------------- Instance Variables
107

108     
109     /**
110      * Namespace.
111      */

112     private Namespace namespace;
113     
114     
115     /**
116      * Namespace configuration.
117      */

118     private NamespaceConfig namespaceConfig;
119     
120     
121     /**
122      * Security helper.
123      */

124     private Security securityHelper;
125     
126     
127     /**
128      * Structure helper.
129      */

130     private Structure structureHelper;
131     
132     
133     /**
134      * Lock helper.
135      */

136     private Lock lockHelper;
137     
138     
139     // -------------------------------------------------------- Content Methods
140

141     
142     /**
143      * Retrieve revision descriptors.
144      *
145      * @param strUri Uri
146      * @return NodeRevisionDescriptors
147      */

148     public NodeRevisionDescriptors retrieve(SlideToken token, String JavaDoc strUri)
149         throws ObjectNotFoundException, AccessDeniedException,
150         LinkedObjectNotFoundException, ServiceAccessException, ObjectLockedException, VetoException {
151         
152         String JavaDoc originalUri = strUri;
153         strUri = redirectUri( originalUri ); // security token null - is ignored anyway
154

155         ObjectNode associatedObject =
156             structureHelper.retrieve(token, strUri, false);
157         
158         // Checking security and locking
159
securityHelper.checkCredentials
160             (token, associatedObject,
161              namespaceConfig.getReadRevisionMetadataAction());
162         lockHelper.checkLock(token, associatedObject,
163                              namespaceConfig.getReadRevisionMetadataAction());
164         
165         Uri objectUri = namespace.getUri(token, strUri);
166         NodeRevisionDescriptors revisionDescriptors = null;
167         try {
168             revisionDescriptors = objectUri.getStore()
169                 .retrieveRevisionDescriptors(objectUri);
170         } catch (RevisionDescriptorNotFoundException e) {
171             // No revision descriptors. We have to create some.
172
revisionDescriptors = new NodeRevisionDescriptors();
173             revisionDescriptors.setUri(objectUri.toString());
174             // FIXME: createRevisionDescriptors shouldn't be done in this read-only method
175
objectUri.getStore()
176                 .createRevisionDescriptors(objectUri, revisionDescriptors);
177         }
178         
179         revisionDescriptors.setOriginalUri( originalUri );
180
181         return revisionDescriptors;
182     }
183     
184     
185     /**
186      * Retrieve revision descriptor of the latest revision
187      * from a branch.
188      *
189      * @param revisionDescriptors Node revision descriptors
190      * @param branch String branch
191      */

192     public NodeRevisionDescriptor retrieve
193         (SlideToken token, NodeRevisionDescriptors revisionDescriptors,
194          String JavaDoc branch)
195         throws ObjectNotFoundException, AccessDeniedException,
196         LinkedObjectNotFoundException, ServiceAccessException,
197         RevisionDescriptorNotFoundException, ObjectLockedException,
198         BranchNotFoundException, NodeNotVersionedException, VetoException {
199         
200         NodeRevisionDescriptor result;
201         Uri objectUri = namespace.getUri(token, revisionDescriptors.getUri());
202         NodeRevisionNumber latestNrn =
203             redirectLatestRevisionNumber( revisionDescriptors.getOriginalUri() );
204         
205         NodeRevisionDescriptors realRevisionDescriptors = objectUri.getStore()
206             .retrieveRevisionDescriptors(objectUri);
207         
208         if (!realRevisionDescriptors.isVersioned()) {
209             // Invalid function call : we try to create a revision, but the
210
// descriptors won't allow it
211
throw new NodeNotVersionedException
212                 (realRevisionDescriptors.getUri().toString());
213         }
214         
215         if( latestNrn == null ) {
216             // Retrieving latest revision numbers
217
NodeRevisionNumber branchLatestRevisionNumber =
218                 realRevisionDescriptors.getLatestRevision(branch);
219             
220             if (branchLatestRevisionNumber == null) {
221                 throw new BranchNotFoundException
222                     (realRevisionDescriptors.getUri().toString(), branch);
223             }
224             result = retrieve(token, realRevisionDescriptors,
225                               branchLatestRevisionNumber);
226         }
227         else {
228             result = retrieve( token, revisionDescriptors,
229                               latestNrn );
230         }
231
232         return result;
233     }
234     
235     
236     /**
237      * Retrieve revision descriptor.
238      *
239      * @param revisionDescriptors Node revision descriptors
240      * @param revisionNumber Node revision number
241      */

242     public NodeRevisionDescriptor retrieve
243         (SlideToken token, NodeRevisionDescriptors revisionDescriptors,
244          NodeRevisionNumber revisionNumber)
245         throws ObjectNotFoundException, AccessDeniedException,
246         LinkedObjectNotFoundException, ServiceAccessException,
247         RevisionDescriptorNotFoundException, ObjectLockedException, VetoException {
248         
249         ObjectNode associatedObject = structureHelper.retrieve
250             (token, revisionDescriptors.getUri(), false);
251         
252         // Checking security and locking
253
securityHelper.checkCredentials
254             (token, associatedObject,
255              namespaceConfig.getReadRevisionMetadataAction());
256         lockHelper.checkLock(token, associatedObject,
257                              namespaceConfig.getReadRevisionMetadataAction());
258         
259         Uri objectUri = namespace.getUri(token, revisionDescriptors.getUri());
260         
261         NodeRevisionDescriptor revisionDescriptor =
262             objectUri.getStore().retrieveRevisionDescriptor
263             (objectUri, revisionNumber);
264         
265         // Invoke interceptors
266
invokeInterceptors(token, revisionDescriptors, revisionDescriptor,
267                            null, POST_RETRIEVE);
268         
269         // Fire event
270
if ( ContentEvent.RETRIEVE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.RETRIEVE, new ContentEvent(this, token, namespace, objectUri.toString(), revisionDescriptors, revisionDescriptor));
271
272         return revisionDescriptor;
273     }
274     
275     
276     /**
277      * Retrieve revision descriptor from the latest revision
278      * in the main branch.
279      *
280      * @param revisionDescriptors Node revision descriptors
281      */

282     public NodeRevisionDescriptor retrieve
283         (SlideToken token, NodeRevisionDescriptors revisionDescriptors)
284         throws ObjectNotFoundException, AccessDeniedException,
285         LinkedObjectNotFoundException, ServiceAccessException,
286         RevisionDescriptorNotFoundException, ObjectLockedException, VetoException {
287         
288         NodeRevisionDescriptor result;
289         Uri objectUri = namespace.getUri(token, revisionDescriptors.getUri());
290         NodeRevisionNumber latestNrn =
291             redirectLatestRevisionNumber( revisionDescriptors.getOriginalUri() );
292         
293         NodeRevisionDescriptors realRevisionDescriptors = objectUri.getStore()
294             .retrieveRevisionDescriptors(objectUri);
295         
296         if( latestNrn == null ) {
297             result = retrieve( token, revisionDescriptors,
298                               realRevisionDescriptors.getLatestRevision());
299         }
300         else {
301             result = retrieve( token, revisionDescriptors,
302                               latestNrn );
303         }
304
305         return result;
306     }
307     
308     
309     /**
310      * Retrieve revision content.
311      *
312      * @param revisionDescriptors Node revision descriptors
313      * @param revisionDescriptor Node revision descriptor
314      */

315     public NodeRevisionContent retrieve
316         (SlideToken token, NodeRevisionDescriptors revisionDescriptors,
317          NodeRevisionDescriptor revisionDescriptor)
318         throws ObjectNotFoundException, AccessDeniedException,
319         LinkedObjectNotFoundException, ServiceAccessException,
320         RevisionNotFoundException, RevisionContentNotFoundException,
321         ObjectLockedException, VetoException {
322         return retrieve(token, revisionDescriptors.getUri(),
323                         revisionDescriptor);
324     }
325     
326     
327     /**
328      * Retrieve revision content.
329      *
330      * @param strUri Uri
331      * @param revisionDescriptor Node revision descriptor
332      */

333     public NodeRevisionContent retrieve
334         (SlideToken token, String JavaDoc strUri,
335          NodeRevisionDescriptor revisionDescriptor)
336         throws ObjectNotFoundException, AccessDeniedException,
337         LinkedObjectNotFoundException, ServiceAccessException,
338         RevisionNotFoundException, RevisionContentNotFoundException,
339         ObjectLockedException, VetoException {
340         
341         ObjectNode associatedObject =
342             structureHelper.retrieve(token, strUri, false);
343         
344         // Checking security and locking
345
securityHelper.checkCredentials
346             (token, associatedObject,
347              namespaceConfig.getReadRevisionContentAction());
348         lockHelper.checkLock(token, associatedObject,
349                              namespaceConfig.getReadRevisionContentAction());
350         
351         Uri objectUri = namespace.getUri(token, strUri);
352         NodeRevisionContent revisionContent =
353             objectUri.getStore().retrieveRevisionContent(objectUri,
354                                                          revisionDescriptor);
355         
356         // Invoke interceptors
357
invokeInterceptors(token, null, revisionDescriptor,
358                            revisionContent, POST_RETRIEVE);
359         
360         // Fire event
361
if ( ContentEvent.RETRIEVE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.RETRIEVE, new ContentEvent(this, token, namespace, objectUri.toString(), revisionDescriptor, revisionContent));
362
363         return revisionContent;
364     }
365     
366     
367     /**
368      * Create new revision descriptors.
369      *
370      * @param strUri Uri
371      * @param isVersioned true is the resource is versioned
372      */

373     public void create(SlideToken token, String JavaDoc strUri,
374                        boolean isVersioned)
375         throws ObjectNotFoundException, AccessDeniedException,
376         LinkedObjectNotFoundException, ServiceAccessException,
377         ObjectLockedException, VetoException {
378         
379         // Check parent exists and is not lock-null
380
checkParentExists(strUri, token);
381         
382         // Retrieve the associated object
383
ObjectNode associatedObject =
384             structureHelper.retrieve(token, strUri, false);
385         
386         // Next we do a security check and a locking check for modifyRevisions
387
securityHelper.checkCredentials
388             (token, associatedObject,
389              namespaceConfig.getCreateRevisionMetadataAction());
390         lockHelper.checkLock
391             (token, associatedObject,
392              namespaceConfig.getCreateRevisionMetadataAction());
393         if (namespaceConfig.getCreateRevisionMetadataAction() !=
394             namespaceConfig.getCreateRevisionContentAction()) {
395             securityHelper.checkCredentials
396                 (token, associatedObject,
397                  namespaceConfig.getCreateRevisionContentAction());
398             lockHelper.checkLock
399                 (token, associatedObject,
400                  namespaceConfig.getCreateRevisionContentAction());
401         }
402         
403         Uri objectUri = namespace.getUri(token, strUri);
404         
405         NodeRevisionDescriptors revisionDescriptors =
406             new NodeRevisionDescriptors(isVersioned);
407         revisionDescriptors.setUri(strUri);
408
409         objectUri.getStore()
410             .createRevisionDescriptors(objectUri, revisionDescriptors);
411     }
412     
413     
414     /**
415      * Create new revision in main branch.
416      *
417      * @param strUri Uri
418      * @param revisionDescriptor New Node revision descriptor
419      * @param revisionContent New Node revision content
420      */

421     public void create(SlideToken token, String JavaDoc strUri,
422                        NodeRevisionDescriptor revisionDescriptor,
423                        NodeRevisionContent revisionContent)
424         throws ObjectNotFoundException, AccessDeniedException,
425         RevisionAlreadyExistException, LinkedObjectNotFoundException,
426         ServiceAccessException, ObjectLockedException, VetoException {
427         
428         // Check parent exists and is not lock-null
429
checkParentExists(strUri, token);
430         
431         // Retrieve the associated object
432
ObjectNode associatedObject =
433             structureHelper.retrieve(token, strUri, false);
434         
435         // Next we do a security check and a locking check for modifyRevisions
436
securityHelper.checkCredentials
437             (token, associatedObject,
438              namespaceConfig.getCreateRevisionMetadataAction());
439         lockHelper.checkLock
440             (token, associatedObject,
441              namespaceConfig.getCreateRevisionMetadataAction());
442         if (namespaceConfig.getCreateRevisionMetadataAction() !=
443             namespaceConfig.getCreateRevisionContentAction()) {
444             securityHelper.checkCredentials
445                 (token, associatedObject,
446                  namespaceConfig.getCreateRevisionContentAction());
447             lockHelper.checkLock
448                 (token, associatedObject,
449                  namespaceConfig.getCreateRevisionContentAction());
450         }
451         
452         setDefaultProperties(associatedObject, revisionDescriptor);
453         // set the creation date if not already set
454
if (revisionDescriptor.getCreationDate() == null) {
455             revisionDescriptor.setCreationDate(new Date JavaDoc());
456             
457             // Set the creation user
458
setCreationUser(token, revisionDescriptor);
459         }
460         // set the display name (in case of copy)
461
if (!Configuration.useBinding(namespace.getUri(token, strUri).getStore())) {
462             if (revisionDescriptor.getName() == null || revisionDescriptor.getName().length() == 0) {
463                 revisionDescriptor.setName(new UriPath(strUri).lastSegment());
464             }
465         }
466         
467         Uri objectUri = namespace.getUri(token, strUri);
468         
469         NodeRevisionDescriptors revisionDescriptors = null;
470         try {
471             revisionDescriptors = objectUri.getStore()
472                 .retrieveRevisionDescriptors(objectUri);
473         } catch (RevisionDescriptorNotFoundException e) {
474             // No revision descriptors. We have to create some.
475
revisionDescriptors = new NodeRevisionDescriptors();
476             revisionDescriptors.setUri(objectUri.toString());
477             objectUri.getStore()
478                 .createRevisionDescriptors(objectUri, revisionDescriptors);
479         }
480         
481         // Retrieve the latest revision from the descriptor,
482
// unless there is no revisions. We generate a new revision number,
483
// basing on an existing revision, if any.
484
NodeRevisionNumber newRevisionNumber = null;
485         if (revisionDescriptors.isVersioned()) {
486             
487             if (revisionDescriptors.hasRevisions()) {
488                 newRevisionNumber = new NodeRevisionNumber
489                     (revisionDescriptors.getLatestRevision());
490                 revisionDescriptors
491                     .addSuccessor(revisionDescriptors.getLatestRevision(),
492                                   newRevisionNumber);
493                 revisionDescriptors
494                     .setSuccessors(newRevisionNumber, new Vector JavaDoc());
495             } else {
496                 newRevisionNumber = new NodeRevisionNumber();
497                 revisionDescriptors
498                     .setSuccessors(newRevisionNumber, new Vector JavaDoc());
499             }
500             // We now set the newly created revision as the latest revison
501
revisionDescriptors.setLatestRevision(newRevisionNumber);
502             
503             // We update the descriptor
504
revisionDescriptor.setRevisionNumber(newRevisionNumber);
505
506             // Fire event
507
if ( ContentEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.CREATE, new ContentEvent(this, token, namespace, objectUri.toString(), revisionDescriptors, revisionDescriptor, revisionContent));
508
509             // Invoke interceptors
510
invokeInterceptors(token, revisionDescriptors, revisionDescriptor,
511                                revisionContent, PRE_STORE);
512             
513             if (revisionContent != null) {
514                 // Storing the new revision contents
515
objectUri.getStore()
516                     .createRevisionContent(objectUri, revisionDescriptor,
517                                            revisionContent);
518             }
519             // Now creating the revision desriptor in the store
520
revisionDescriptor.setModificationDate(revisionDescriptor.getCreationDate());
521             revisionDescriptor.setModificationUser(
522                 securityHelper.getPrincipal(token).getPath().lastSegment());
523             objectUri.getStore()
524                 .createRevisionDescriptor(objectUri, revisionDescriptor);
525             
526         } else {
527             // We don't use versioning for this object.
528
// Two options :
529
// - The object already has one (and only one) revision,
530
// so we update it
531
// - The object dooesn't have any revisions right now, so we create
532
// the initial revision
533
newRevisionNumber = new NodeRevisionNumber();
534             revisionDescriptor.setRevisionNumber(newRevisionNumber);
535             
536             if (!revisionDescriptors.hasRevisions()) {
537
538                 // Fire event
539
if ( ContentEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.CREATE, new ContentEvent(this, token, namespace, objectUri.toString(), revisionDescriptors, revisionDescriptor, revisionContent));
540
541                 // Invoke interceptors
542
invokeInterceptors(token, revisionDescriptors,
543                                    revisionDescriptor,
544                                    revisionContent, PRE_STORE);
545                 
546                 if (revisionContent != null) {
547                     // Storing the new revision contents
548
objectUri.getStore()
549                         .createRevisionContent(objectUri, revisionDescriptor,
550                                                revisionContent);
551                 }
552                 // Now creating the revision desriptor in the store
553
revisionDescriptor.setModificationDate(revisionDescriptor.getCreationDate());
554                 revisionDescriptor.setModificationUser(
555                     securityHelper.getPrincipal(token).getPath().lastSegment());
556                 objectUri.getStore()
557                     .createRevisionDescriptor(objectUri, revisionDescriptor);
558                 
559             } else {
560                 
561                 try { {
562                         // merge the new received properties into the
563
// revisionDescriptor
564

565                         // We update the descriptor's properties
566
NodeRevisionDescriptor oldRevisionDescriptor =
567                             objectUri.getStore()
568                             .retrieveRevisionDescriptor
569                             (objectUri, newRevisionNumber);
570                         Enumeration JavaDoc newPropertiesList =
571                             revisionDescriptor.enumerateProperties();
572                         while (newPropertiesList.hasMoreElements()) {
573                             oldRevisionDescriptor
574                                 .setProperty((NodeProperty) newPropertiesList
575                                                  .nextElement() );
576                         }
577                         
578                         // now use the merged revision descriptor
579
revisionDescriptor = oldRevisionDescriptor;
580                     } // end of merge
581

582                     // Fire event
583
if ( ContentEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.CREATE, new ContentEvent(this, token, namespace, objectUri.toString(), revisionDescriptors, revisionDescriptor, revisionContent));
584
585                     // Invoke interceptors
586
invokeInterceptors(token, revisionDescriptors,
587                                        revisionDescriptor,
588                                        revisionContent, PRE_STORE);
589                     
590                     if (revisionContent != null) {
591                         // Storing the new revision contents
592
try {
593                             objectUri.getStore()
594                                 .storeRevisionContent(objectUri,
595                                                       revisionDescriptor,
596                                                       revisionContent);
597                         } catch (RevisionNotFoundException e) {
598                             objectUri.getStore()
599                                 .createRevisionContent(objectUri,
600                                                        revisionDescriptor,
601                                                        revisionContent);
602                         }
603                     }
604                     
605                     revisionDescriptor.setModificationDate(revisionDescriptor.getCreationDate());
606                     revisionDescriptor.setModificationUser(
607                         securityHelper.getPrincipal(token).getPath().lastSegment());
608                     objectUri.getStore()
609                         .storeRevisionDescriptor
610                         (objectUri, revisionDescriptor);
611                     
612                 } catch (RevisionDescriptorNotFoundException e) {
613                     // Should NEVER happen.
614
// Basically, it would mean that there is no initial
615
// revision, which is incorrect since the object
616
// HAS revisions.
617

618                     // Fire event
619
if ( ContentEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.CREATE, new ContentEvent(this, token, namespace, objectUri.toString(), revisionDescriptors, revisionDescriptor, revisionContent));
620
621                     // Invoke interceptors
622
invokeInterceptors(token, revisionDescriptors,
623                                        revisionDescriptor,
624                                        revisionContent, PRE_STORE);
625                     
626                     revisionDescriptor.setModificationDate(revisionDescriptor.getCreationDate());
627                     revisionDescriptor.setModificationUser(
628                         securityHelper.getPrincipal(token).getPath().lastSegment());
629                     objectUri.getStore()
630                         .createRevisionDescriptor(objectUri,
631                                                   revisionDescriptor);
632                 }
633             }
634             // Updating the descriptors object
635
revisionDescriptors
636                 .setSuccessors(newRevisionNumber, new Vector JavaDoc());
637             revisionDescriptors.setLatestRevision(newRevisionNumber);
638         }
639         
640         // We now store the updated revision descriptors
641
try {
642             objectUri.getStore()
643                 .storeRevisionDescriptors(objectUri, revisionDescriptors);
644         } catch (RevisionDescriptorNotFoundException e) {
645             // Problem ...
646
e.printStackTrace();
647         }
648         
649         // Invoke interceptors
650
invokeInterceptors(token, revisionDescriptors, revisionDescriptor,
651                            revisionContent, POST_STORE);
652     }
653     
654     
655     /**
656      * Create new revision based on a previous revision.
657      *
658      * @param strUri Uri
659      * @param branch Branch in which to create the revision
660      * @param newRevisionDescriptor New revision descriptor
661      * @param revisionContent Node revision content
662      */

663     public void create(SlideToken token, String JavaDoc strUri, String JavaDoc branch,
664                        NodeRevisionDescriptor newRevisionDescriptor,
665                        NodeRevisionContent revisionContent)
666         throws ObjectNotFoundException, AccessDeniedException,
667         RevisionAlreadyExistException, LinkedObjectNotFoundException,
668         ServiceAccessException, RevisionDescriptorNotFoundException,
669         ObjectLockedException, NodeNotVersionedException,
670         BranchNotFoundException, VetoException {
671         
672         // Check parent exists and is not lock-null
673
checkParentExists(strUri, token);
674         
675         Uri objectUri = namespace.getUri(token, strUri);
676         
677         NodeRevisionDescriptors revisionDescriptors = objectUri.getStore()
678             .retrieveRevisionDescriptors(objectUri);
679         
680         if( branch != null ) {
681             // Retrieving latest revision numbers
682
NodeRevisionNumber branchLatestRevisionNumber =
683                 revisionDescriptors.getLatestRevision(branch);
684             
685             if (branchLatestRevisionNumber == null) {
686                 throw new BranchNotFoundException(strUri, branch);
687             }
688             
689             create(token, strUri, branchLatestRevisionNumber,
690                    newRevisionDescriptor, revisionContent);
691         }
692         else {
693             // special handling for DeltaV used for the creation of the
694
// branch-less VHR descriptor at version 0.0
695
create( token, strUri, newRevisionDescriptor );
696         }
697         
698         
699     }
700     
701     
702     /**
703      * Create a branch based on specified revision.
704      *
705      * @param strUri Uri
706      * @param branchName Name of the new branch
707      * @param basedOnRevisionDescriptor Node revision descriptor of
708      * the revision on which the new branch
709      * is based on.
710      *
711      * @return the NodeRevisionNumber of the created revision.
712      */

713     public NodeRevisionNumber fork(SlideToken token, String JavaDoc strUri, String JavaDoc branchName,
714                                    NodeRevisionDescriptor basedOnRevisionDescriptor)
715         throws ObjectNotFoundException, AccessDeniedException,
716         LinkedObjectNotFoundException, ServiceAccessException,
717         RevisionDescriptorNotFoundException, ObjectLockedException,
718         NodeNotVersionedException, RevisionAlreadyExistException, VetoException {
719         
720         return fork(token, strUri, branchName,
721                     basedOnRevisionDescriptor.getRevisionNumber());
722         
723     }
724     
725     
726     /**
727      * Create a branch based on specified revision.
728      *
729      * @param strUri Uri
730      * @param branchName Name of the new branch
731      * @param basedOnRevisionNumber NodeRevisionNumber revision descriptor of
732      * the revision on which the new branch
733      * is based on.
734      *
735      * @return the NodeRevisionNumber of the created revision.
736      */

737     public NodeRevisionNumber fork(SlideToken token, String JavaDoc strUri, String JavaDoc branchName,
738                                    NodeRevisionNumber basedOnRevisionNumber)
739         throws ObjectNotFoundException, AccessDeniedException,
740         LinkedObjectNotFoundException, ServiceAccessException,
741         RevisionDescriptorNotFoundException, ObjectLockedException,
742         NodeNotVersionedException, RevisionAlreadyExistException, VetoException {
743         
744         if (branchName.equals(NodeRevisionDescriptors.MAIN_BRANCH))
745             return null;
746         
747         // Retrieve the associated object
748
ObjectNode associatedObject =
749             structureHelper.retrieve(token, strUri, false);
750         
751         // Next we do a security check and a locking check for modifyRevisions
752
securityHelper.checkCredentials
753             (token, associatedObject,
754              namespaceConfig.getCreateRevisionMetadataAction());
755         lockHelper.checkLock
756             (token, associatedObject,
757              namespaceConfig.getCreateRevisionMetadataAction());
758         securityHelper.checkCredentials
759             (token, associatedObject,
760              namespaceConfig.getCreateRevisionContentAction());
761         lockHelper.checkLock(token, associatedObject,
762                              namespaceConfig.getCreateRevisionContentAction());
763         
764         Uri objectUri = namespace.getUri(token, strUri);
765         
766         // Retrieve the revision table
767
NodeRevisionDescriptors revisionDescriptors =
768             objectUri.getStore()
769             .retrieveRevisionDescriptors(objectUri);
770         
771         if (!revisionDescriptors.isVersioned()) {
772             // Invalid function call : we try to create a revision, but the
773
// descriptors won't allow it
774
throw new NodeNotVersionedException(strUri);
775         }
776         
777         // Retrieving the revision on which the new branch is based.
778
NodeRevisionDescriptor basedOnRevisionDescriptor =
779             objectUri.getStore().retrieveRevisionDescriptor
780             (objectUri, basedOnRevisionNumber);
781         NodeRevisionContent basedOnRevisionContent = null;
782         try {
783             basedOnRevisionContent =
784                 objectUri.getStore().retrieveRevisionContent
785                 (objectUri,
786                  basedOnRevisionDescriptor);
787         } catch (RevisionNotFoundException e) {
788         }
789         
790         // Create a revision number suited for the new branch
791
NodeRevisionNumber branchedRevisionNumber =
792             new NodeRevisionNumber(basedOnRevisionNumber, true);
793         
794         basedOnRevisionDescriptor.setRevisionNumber(branchedRevisionNumber);
795         basedOnRevisionDescriptor.setBranchName(branchName);
796         
797         revisionDescriptors.setUri(strUri);
798         revisionDescriptors.setLatestRevision
799             (branchName, branchedRevisionNumber);
800         revisionDescriptors.addSuccessor
801             (basedOnRevisionNumber, branchedRevisionNumber);
802         
803         // Fire event
804
if ( ContentEvent.FORK.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.FORK, new ContentEvent(this, token, namespace, strUri, revisionDescriptors));
805
806         // Invoke interceptors
807
invokeInterceptors(token, revisionDescriptors,
808                            basedOnRevisionDescriptor,
809                            basedOnRevisionContent, PRE_STORE);
810         
811         // Storing back everything
812
// TODO: setModificationDate
813
// clone of NRD required??
814
if (basedOnRevisionContent != null) {
815             objectUri.getStore().createRevisionContent
816                 (objectUri, basedOnRevisionDescriptor, basedOnRevisionContent);
817         }
818         objectUri.getStore().createRevisionDescriptor
819             (objectUri, basedOnRevisionDescriptor);
820         objectUri.getStore().storeRevisionDescriptors
821             (objectUri, revisionDescriptors);
822         
823         // Invoke interceptors
824
invokeInterceptors(token, revisionDescriptors,
825                            basedOnRevisionDescriptor,
826                            basedOnRevisionContent, POST_STORE);
827
828         return branchedRevisionNumber;
829     }
830     
831     
832     /**
833      * Merge specified branches into a single branch.
834      *
835      * @param strUri Uri
836      * @param mainBranch Branch into which the other branch will be merged
837      * @param branch Branch to merge into main branch
838      * @param newRevisionDescriptor New revision descriptor
839      * @param revisionContent Node revision content
840      */

841     public void merge(SlideToken token, String JavaDoc strUri,
842                       NodeRevisionDescriptor mainBranch,
843                       NodeRevisionDescriptor branch,
844                       NodeRevisionDescriptor newRevisionDescriptor,
845                       NodeRevisionContent revisionContent)
846         throws ObjectNotFoundException, AccessDeniedException,
847         LinkedObjectNotFoundException, ServiceAccessException,
848         RevisionDescriptorNotFoundException, ObjectLockedException,
849         NodeNotVersionedException, BranchNotFoundException,
850         RevisionAlreadyExistException, VetoException {
851         
852         merge(token, strUri, mainBranch.getBranchName(),
853               branch.getBranchName(), newRevisionDescriptor, revisionContent);
854         
855     }
856     
857     
858     /**
859      * Merge specified branches into a single branch.
860      *
861      * @param strUri Uri
862      * @param mainBranch Branch into which the other branch will be merged
863      * @param branch Branch to merge into main branch
864      * @param newRevisionDescriptor New revision descriptor
865      * @param revisionContent Node revision content
866      */

867     public void merge(SlideToken token, String JavaDoc strUri,
868                       String JavaDoc mainBranch, String JavaDoc branch,
869                       NodeRevisionDescriptor newRevisionDescriptor,
870                       NodeRevisionContent revisionContent)
871         throws ObjectNotFoundException, AccessDeniedException,
872         LinkedObjectNotFoundException, ServiceAccessException,
873         RevisionDescriptorNotFoundException, ObjectLockedException,
874         NodeNotVersionedException, BranchNotFoundException,
875         RevisionAlreadyExistException, VetoException {
876         
877         // Retrieve the associated object
878
ObjectNode associatedObject =
879             structureHelper.retrieve(token, strUri, false);
880         
881         // Next we do a security check and a locking check for modifyRevisions
882
securityHelper.checkCredentials
883             (token, associatedObject,
884              namespaceConfig.getCreateRevisionMetadataAction());
885         lockHelper.checkLock
886             (token, associatedObject,
887              namespaceConfig.getCreateRevisionMetadataAction());
888         securityHelper.checkCredentials
889             (token, associatedObject,
890              namespaceConfig.getCreateRevisionContentAction());
891         lockHelper.checkLock(token, associatedObject,
892                              namespaceConfig.getCreateRevisionContentAction());
893         
894         setDefaultProperties(associatedObject, newRevisionDescriptor);
895         
896         Uri objectUri = namespace.getUri(token, strUri);
897         
898         // Retrieve the revision table
899
NodeRevisionDescriptors revisionDescriptors =
900             objectUri.getStore().retrieveRevisionDescriptors(objectUri);
901         
902         if (!revisionDescriptors.isVersioned()) {
903             // Invalid function call : we try to create a revision, but the
904
// descriptors won't allow it
905
throw new NodeNotVersionedException(strUri);
906         }
907         
908         // Retrieving latest revision numbers
909
NodeRevisionNumber mainBranchLatestRevisionNumber =
910             revisionDescriptors.getLatestRevision(mainBranch);
911         NodeRevisionNumber branchLatestRevisionNumber =
912             revisionDescriptors.getLatestRevision(branch);
913         
914         if (mainBranchLatestRevisionNumber == null) {
915             throw new BranchNotFoundException(strUri, mainBranch);
916         }
917         if (branchLatestRevisionNumber == null) {
918             throw new BranchNotFoundException(strUri, branch);
919         }
920         
921         NodeRevisionNumber newRevisionNumber =
922             new NodeRevisionNumber(mainBranchLatestRevisionNumber);
923         
924         newRevisionDescriptor.setRevisionNumber(newRevisionNumber);
925         newRevisionDescriptor.setBranchName(branch);
926         
927         revisionDescriptors.addSuccessor
928             (mainBranchLatestRevisionNumber, newRevisionNumber);
929         revisionDescriptors.addSuccessor
930             (branchLatestRevisionNumber, newRevisionNumber);
931         revisionDescriptors.setLatestRevision(mainBranch, newRevisionNumber);
932         
933         // Fire event
934
if ( ContentEvent.MERGE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.MERGE, new ContentEvent(this, token, namespace, objectUri.toString(), revisionDescriptors, newRevisionDescriptor, revisionContent));
935
936         // Invoke interceptors
937
invokeInterceptors(token, revisionDescriptors, newRevisionDescriptor,
938                            revisionContent, PRE_STORE);
939         
940         // Storing back everything
941
if (revisionContent != null) {
942             objectUri.getStore().createRevisionContent
943                 (objectUri, newRevisionDescriptor, revisionContent);
944         }
945         newRevisionDescriptor.setModificationDate(newRevisionDescriptor.getCreationDate());
946         newRevisionDescriptor.setModificationUser(
947             securityHelper.getPrincipal(token).getPath().lastSegment());
948         objectUri.getStore().createRevisionDescriptor
949             (objectUri, newRevisionDescriptor);
950         objectUri.getStore().storeRevisionDescriptors
951             (objectUri, revisionDescriptors);
952         
953         // Invoke interceptors
954
invokeInterceptors(token, revisionDescriptors, newRevisionDescriptor,
955                            revisionContent, POST_STORE);
956     }
957     
958     
959     /**
960      * Update contents of an existing revision.
961      *
962      * @param strUri Uri
963      * @param revisionDescriptor Revision descriptor
964      * @param revisionContent Revision content
965      */

966     public void store(SlideToken token, String JavaDoc strUri,
967                       NodeRevisionDescriptor revisionDescriptor,
968                       NodeRevisionContent revisionContent)
969         throws ObjectNotFoundException, AccessDeniedException,
970         LinkedObjectNotFoundException, ServiceAccessException,
971         RevisionDescriptorNotFoundException, ObjectLockedException,
972         RevisionNotFoundException, VetoException {
973         
974         // Retrieve the associated object
975
ObjectNode associatedObject =
976             structureHelper.retrieve(token, strUri, false);
977         
978         // Next we do a security check and a locking check for modifyRevisions
979
securityHelper.checkCredentials
980             (token, associatedObject,
981              namespaceConfig.getModifyRevisionMetadataAction());
982         lockHelper.checkLock
983             (token, associatedObject,
984              namespaceConfig.getModifyRevisionMetadataAction());
985         securityHelper.checkCredentials
986             (token, associatedObject,
987              namespaceConfig.getModifyRevisionContentAction());
988         lockHelper.checkLock(token, associatedObject,
989                              namespaceConfig.getModifyRevisionContentAction());
990         
991         setDefaultProperties(associatedObject, revisionDescriptor);
992         
993         Uri objectUri = namespace.getUri(token, strUri);
994         
995         // Retrieve the revision table
996
NodeRevisionDescriptors revisionDescriptors =
997             objectUri.getStore().retrieveRevisionDescriptors(objectUri);
998
999         // Fire event
1000
if ( revisionDescriptor.getRevisionNumber() != NodeRevisionNumber.HIDDEN_0_0 && ContentEvent.STORE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.STORE, new ContentEvent(this, token, namespace, objectUri.toString(), revisionDescriptors, revisionDescriptor, revisionContent));
1001
1002        // Invoke interceptors
1003
invokeInterceptors(token, revisionDescriptors, revisionDescriptor,
1004                           revisionContent, PRE_STORE);
1005        
1006        if (revisionContent != null) {
1007            try {
1008                // Removed retrieveContent call [pnever, 25-APR-2003].
1009
// Reasons:
1010
// - it is not necessary to check existence because storeRevisionContent also throws RevisionNotFoundException
1011
// - it is harmful for filesystem-based stores, as the input streams created by retrieveRevisionContent never are closed
1012
// Simple scenario:
1013
// Use the FileContentStore, create a file, update it and then try to delete it.
1014
// It will not be deleted from the filesystem.
1015
//
1016
// objectUri.getStore().retrieveRevisionContent
1017
// (objectUri, revisionDescriptor);
1018
objectUri.getStore().storeRevisionContent
1019                    (objectUri, revisionDescriptor, revisionContent);
1020            } catch (RevisionNotFoundException e) {
1021                try {
1022                    objectUri.getStore().createRevisionContent
1023                        (objectUri, revisionDescriptor, revisionContent);
1024                } catch (RevisionAlreadyExistException ex) {
1025                    // Should never happen
1026
ex.printStackTrace();
1027                }
1028            }
1029        }
1030        revisionDescriptor.setModificationDate(new Date JavaDoc());
1031        revisionDescriptor.setModificationUser(
1032            securityHelper.getPrincipal(token).getPath().lastSegment());
1033        objectUri.getStore().storeRevisionDescriptor
1034            (objectUri, revisionDescriptor);
1035        
1036        // Invoke interceptors
1037
invokeInterceptors(token, revisionDescriptors, revisionDescriptor,
1038                           revisionContent, POST_STORE);
1039    }
1040    
1041    
1042    /**
1043     * Remove all revisions at this Uri.
1044     *
1045     * @param revisionDescriptors Node revision descriptors
1046     */

1047    public void remove(SlideToken token,
1048                       NodeRevisionDescriptors revisionDescriptors)
1049        throws ObjectNotFoundException, AccessDeniedException,
1050        LinkedObjectNotFoundException, ServiceAccessException,
1051        RevisionDescriptorNotFoundException, ObjectLockedException, VetoException {
1052        
1053        // Invoke interceptors
1054
invokeInterceptors(token, revisionDescriptors, null, null, PRE_REMOVE);
1055
1056        // Retrieve the associated object
1057
ObjectNode associatedObject = structureHelper.retrieve
1058            (token, revisionDescriptors.getUri(), false);
1059        
1060        // Next we do a security check and a locking check for modifyRevisions
1061
securityHelper.checkCredentials
1062            (token, associatedObject,
1063             namespaceConfig.getRemoveRevisionMetadataAction());
1064        lockHelper.checkLock
1065            (token, associatedObject,
1066             namespaceConfig.getRemoveRevisionMetadataAction());
1067        securityHelper.checkCredentials
1068            (token, associatedObject,
1069             namespaceConfig.getRemoveRevisionContentAction());
1070        lockHelper.checkLock(token, associatedObject,
1071                             namespaceConfig.getRemoveRevisionContentAction());
1072        
1073        Uri objectUri = namespace.getUri(token, revisionDescriptors.getUri());
1074
1075        // Fire event
1076
if ( ContentEvent.REMOVE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.REMOVE, new ContentEvent(this, token, namespace, objectUri.toString(), revisionDescriptors));
1077
1078        objectUri.getStore().removeRevisionDescriptors(objectUri);
1079        
1080        // Invoke interceptors
1081
invokeInterceptors(token, revisionDescriptors, null, null,
1082                           POST_REMOVE);
1083    }
1084    
1085    
1086    /**
1087     * Remove specified revision.
1088     *
1089     * @param strUri Uri
1090     * @param revisionDescriptor Node revision descriptor
1091     */

1092    public void remove(SlideToken token, String JavaDoc strUri,
1093                       NodeRevisionDescriptor revisionDescriptor)
1094        throws ObjectNotFoundException, AccessDeniedException,
1095        LinkedObjectNotFoundException, ServiceAccessException,
1096        RevisionDescriptorNotFoundException, ObjectLockedException, VetoException {
1097        
1098        remove(token, strUri, revisionDescriptor.getRevisionNumber());
1099        
1100    }
1101    
1102    
1103    /**
1104     * Remove specified revision.
1105     *
1106     * @param strUri Uri
1107     * @param revisionNumber Revision number
1108     */

1109    public void remove(SlideToken token, String JavaDoc strUri,
1110                       NodeRevisionNumber revisionNumber)
1111        throws ObjectNotFoundException, AccessDeniedException,
1112        LinkedObjectNotFoundException, ServiceAccessException,
1113        RevisionDescriptorNotFoundException, ObjectLockedException, VetoException {
1114        
1115        // Retrieve the associated object
1116
ObjectNode associatedObject =
1117            structureHelper.retrieve(token, strUri, false);
1118        
1119        // Next we do a security check and a locking check for modifyRevisions
1120
securityHelper.checkCredentials
1121            (token, associatedObject,
1122             namespaceConfig.getRemoveRevisionMetadataAction());
1123        lockHelper.checkLock
1124            (token, associatedObject,
1125             namespaceConfig.getRemoveRevisionMetadataAction());
1126        securityHelper.checkCredentials
1127            (token, associatedObject,
1128             namespaceConfig.getRemoveRevisionContentAction());
1129        lockHelper.checkLock(token, associatedObject,
1130                             namespaceConfig.getRemoveRevisionContentAction());
1131        
1132        Uri objectUri = namespace.getUri(token, strUri);
1133        
1134        NodeRevisionDescriptor revisionDescriptor =
1135            objectUri.getStore().retrieveRevisionDescriptor
1136            (objectUri, revisionNumber);
1137
1138        // Fire event
1139
if ( revisionNumber != NodeRevisionNumber.HIDDEN_0_0 && ContentEvent.REMOVE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.REMOVE, new ContentEvent(this, token, namespace, objectUri.toString(), revisionDescriptor));
1140
1141        // Invoke interceptors
1142
invokeInterceptors(token, null, revisionDescriptor, null, PRE_REMOVE);
1143        
1144        objectUri.getStore().removeRevisionContent
1145            (objectUri, revisionDescriptor);
1146        objectUri.getStore()
1147            .removeRevisionDescriptor(objectUri, revisionNumber);
1148        
1149        // Invoke interceptors
1150
invokeInterceptors(token, null, revisionDescriptor, null, POST_REMOVE);
1151    }
1152    
1153    
1154    // ------------------------------------------------------ Protected Methods
1155

1156    
1157    /**
1158     * Create new revision based on a previous revision.
1159     *
1160     * @param strUri Uri
1161     * @param basedOnRevisionNumber Number of revision on which the
1162     * new revision is based
1163     * @param newRevisionDescriptor New revision descriptor
1164     * @param revisionContent Node revision content
1165     */

1166    protected void create(SlideToken token, String JavaDoc strUri,
1167                          NodeRevisionNumber basedOnRevisionNumber,
1168                          NodeRevisionDescriptor newRevisionDescriptor,
1169                          NodeRevisionContent revisionContent)
1170        throws ObjectNotFoundException, AccessDeniedException,
1171        RevisionAlreadyExistException, LinkedObjectNotFoundException,
1172        ServiceAccessException, RevisionDescriptorNotFoundException,
1173        ObjectLockedException, NodeNotVersionedException, VetoException {
1174        
1175        // Retrieve the associated object
1176
ObjectNode associatedObject =
1177            structureHelper.retrieve(token, strUri, false);
1178        
1179        // Next we do a security check and a locking check for modifyRevisions
1180
securityHelper.checkCredentials
1181            (token, associatedObject,
1182             namespaceConfig.getCreateRevisionMetadataAction());
1183        lockHelper.checkLock
1184            (token, associatedObject,
1185             namespaceConfig.getCreateRevisionMetadataAction());
1186        securityHelper.checkCredentials
1187            (token, associatedObject,
1188             namespaceConfig.getCreateRevisionContentAction());
1189        lockHelper.checkLock(token, associatedObject,
1190                             namespaceConfig.getCreateRevisionContentAction());
1191        
1192        setDefaultProperties(associatedObject, newRevisionDescriptor);
1193        
1194        Uri objectUri = namespace.getUri(token, strUri);
1195        
1196        // Retrieve the revision table
1197
NodeRevisionDescriptors revisionDescriptors =
1198            objectUri.getStore()
1199            .retrieveRevisionDescriptors(objectUri);
1200        
1201        if (!revisionDescriptors.isVersioned()) {
1202            // Invalid function call : we try to create a revision, but the
1203
// descriptors won't allow it
1204
throw new NodeNotVersionedException(strUri);
1205        }
1206        
1207        // Retrieve the old revision descriptor, just to make sure that the old
1208
// revision we base the new one upon really exists
1209
NodeRevisionDescriptor realOldRevisionDescriptor =
1210            objectUri.getStore().retrieveRevisionDescriptor
1211            (objectUri, basedOnRevisionNumber);
1212        
1213        // We check that the old revision doesn't have successors, that is we :
1214
// - check to see if it's the latest revision in a branch
1215
// - store that information for later use
1216
NodeRevisionNumber latestNumberInBranch =
1217            revisionDescriptors.getLatestRevision
1218            (realOldRevisionDescriptor.getBranchName());
1219        if (!realOldRevisionDescriptor.getRevisionNumber()
1220            .equals(latestNumberInBranch)) {
1221            throw new RevisionAlreadyExistException
1222                (objectUri.toString(), new NodeRevisionNumber
1223                     (basedOnRevisionNumber));
1224        }
1225        
1226        // Next, generate the new revision's number
1227
newRevisionDescriptor.setRevisionNumber
1228            (new NodeRevisionNumber(basedOnRevisionNumber));
1229        // Set the creation date
1230
newRevisionDescriptor.setCreationDate(new Date JavaDoc());
1231        
1232        // Set the creation user
1233
setCreationUser(token, newRevisionDescriptor);
1234        
1235        // Initialize the branch name in the new descriptor
1236
newRevisionDescriptor.setBranchName
1237            (realOldRevisionDescriptor.getBranchName());
1238
1239        // Fire event
1240
if ( ContentEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.CREATE, new ContentEvent(this, token, namespace, objectUri.toString(), revisionDescriptors, newRevisionDescriptor, revisionContent));
1241
1242        // Invoke interceptors
1243
invokeInterceptors(token, revisionDescriptors, newRevisionDescriptor,
1244                           revisionContent, PRE_STORE);
1245        
1246        // Update the revision graph in the revision descriptors
1247
revisionDescriptors
1248            .addSuccessor(revisionDescriptors.getLatestRevision(newRevisionDescriptor.getBranchName()),
1249                          newRevisionDescriptor.getRevisionNumber());
1250        revisionDescriptors
1251            .setSuccessors(newRevisionDescriptor.getRevisionNumber(), new Vector JavaDoc());
1252        revisionDescriptors
1253            .setLatestRevision(newRevisionDescriptor.getBranchName(),
1254                               newRevisionDescriptor.getRevisionNumber());
1255        if (revisionContent != null) {
1256            // Storing the new revision contents
1257
objectUri.getStore()
1258                .createRevisionContent(objectUri, newRevisionDescriptor,
1259                                       revisionContent);
1260        }
1261        // Now creating the revision desriptor in the store
1262
newRevisionDescriptor.setModificationDate(newRevisionDescriptor.getCreationDate());
1263        newRevisionDescriptor.setModificationUser(
1264            securityHelper.getPrincipal(token).getPath().lastSegment());
1265        objectUri.getStore()
1266            .createRevisionDescriptor(objectUri, newRevisionDescriptor);
1267        
1268        // We now store the updated revision descriptors
1269
try {
1270            objectUri.getStore()
1271                .storeRevisionDescriptors(objectUri, revisionDescriptors);
1272        } catch (RevisionDescriptorNotFoundException e) {
1273            // Problem ...
1274
e.printStackTrace();
1275        }
1276        
1277        // Invoke interceptors
1278
invokeInterceptors(token, revisionDescriptors, newRevisionDescriptor,
1279                           revisionContent, POST_STORE);
1280    }
1281    
1282    
1283    /**
1284     * Create new branch-less revision descriptor.
1285     * This is used only by DeltaV to store the VHR-specific descriptor at
1286     * revision 0.0, or to backup the properties of a VCR for checkout/uncheckout
1287     * at revision 0.0.
1288     */

1289    protected void create( SlideToken token, String JavaDoc strUri,
1290                          NodeRevisionDescriptor revisionDescriptor )
1291        throws ObjectNotFoundException, AccessDeniedException,
1292        RevisionAlreadyExistException, LinkedObjectNotFoundException,
1293        ServiceAccessException, RevisionDescriptorNotFoundException,
1294        ObjectLockedException, NodeNotVersionedException, VetoException {
1295        
1296        // Retrieve the associated object
1297
ObjectNode associatedObject =
1298            structureHelper.retrieve(token, strUri, false);
1299        
1300        // Next we do a security check and a locking check for modifyRevisions
1301
securityHelper.checkCredentials
1302            (token, associatedObject,
1303             namespaceConfig.getCreateRevisionMetadataAction());
1304        lockHelper.checkLock
1305            (token, associatedObject,
1306             namespaceConfig.getCreateRevisionMetadataAction());
1307        securityHelper.checkCredentials
1308            (token, associatedObject,
1309             namespaceConfig.getCreateRevisionContentAction());
1310        lockHelper.checkLock(token, associatedObject,
1311                             namespaceConfig.getCreateRevisionContentAction());
1312        
1313        setDefaultProperties(associatedObject, revisionDescriptor);
1314        
1315        Uri objectUri = namespace.getUri(token, strUri);
1316        
1317        // Retrieve the revision table
1318
NodeRevisionDescriptors revisionDescriptors =
1319            objectUri.getStore()
1320            .retrieveRevisionDescriptors(objectUri);
1321        
1322        // Set the creation date
1323
revisionDescriptor.setCreationDate(new Date JavaDoc());
1324        
1325        // Set the creation user
1326
setCreationUser(token, revisionDescriptor);
1327        
1328        // Initialize the branch name in the new descriptor
1329
String JavaDoc branchName = "backup";
1330        NodeProperty rootVersionProperty = revisionDescriptor.getProperty("version-set");
1331        if (rootVersionProperty != null) {
1332            branchName = "version-history";
1333        }
1334        revisionDescriptor.setBranchName(branchName);
1335
1336        // Fire event
1337
if ( revisionDescriptor.getRevisionNumber() != NodeRevisionNumber.HIDDEN_0_0 && ContentEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(ContentEvent.CREATE, new ContentEvent(this, token, namespace, objectUri.toString(), revisionDescriptors, revisionDescriptor));
1338
1339        // Invoke interceptors
1340
invokeInterceptors(token, revisionDescriptors, revisionDescriptor,
1341                           null, PRE_STORE);
1342        
1343        // Now creating the revision desriptor in the store
1344
revisionDescriptor.setModificationDate(revisionDescriptor.getCreationDate());
1345        revisionDescriptor.setModificationUser(
1346            securityHelper.getPrincipal(token).getPath().lastSegment());
1347        objectUri.getStore()
1348            .createRevisionDescriptor(objectUri, revisionDescriptor);
1349        
1350        // We now store the updated revision descriptors
1351
try {
1352            objectUri.getStore()
1353                .storeRevisionDescriptors(objectUri, revisionDescriptors);
1354        } catch (RevisionDescriptorNotFoundException e) {
1355            // Problem ...
1356
e.printStackTrace();
1357        }
1358        
1359        // Invoke interceptors
1360
invokeInterceptors(token, revisionDescriptors, revisionDescriptor,
1361                           null, POST_STORE);
1362    }
1363    
1364    private void setCreationUser(SlideToken token, NodeRevisionDescriptor revisionDescriptor) throws ServiceAccessException, ObjectNotFoundException {
1365        String JavaDoc creationUser = ((SubjectNode)securityHelper.getPrincipal(token)).getPath().lastSegment();
1366        revisionDescriptor.setCreationUser(creationUser);
1367        revisionDescriptor.setOwner(creationUser);
1368    }
1369    
1370    
1371    /**
1372     * Set default properties for a revision descriptors.
1373     */

1374    protected void setDefaultProperties
1375        (ObjectNode associatedObject,
1376         NodeRevisionDescriptor revisionDescriptor) {
1377        // Retrieving the roles of the associated object
1378
Enumeration JavaDoc roles = securityHelper.getRoles(associatedObject);
1379        while (roles.hasMoreElements()) {
1380            String JavaDoc role = (String JavaDoc) roles.nextElement();
1381            Enumeration JavaDoc defaultProperties =
1382                namespaceConfig.getDefaultProperties(role);
1383            revisionDescriptor.setDefaultProperties(defaultProperties);
1384        }
1385        if (namespaceConfig.isPrincipal(associatedObject.getUri())) {
1386            // principals must have DAV:displayname
1387
if (revisionDescriptor.getName() == null || revisionDescriptor.getName().length() == 0) {
1388                UriPath uripath = new UriPath(associatedObject.getUri());
1389                revisionDescriptor.setName(uripath.lastSegment());
1390            }
1391            // principals must have DAV:principal in resourcetype
1392
String JavaDoc rt = revisionDescriptor.getResourceType();
1393            if (rt.indexOf("principal") < 0) {
1394                revisionDescriptor.setResourceType(rt+"<principal/>");
1395            }
1396        }
1397    }
1398    
1399    
1400    /**
1401     * Invoke content interceptors.
1402     */

1403    protected void invokeInterceptors
1404        (SlideToken token, NodeRevisionDescriptors revisionDescriptors,
1405         NodeRevisionDescriptor revisionDescriptor,
1406         NodeRevisionContent revisionContent, int type)
1407        throws AccessDeniedException, ObjectNotFoundException,
1408        LinkedObjectNotFoundException, ObjectLockedException,
1409        ServiceAccessException {
1410        ContentInterceptor[] contentInterceptors =
1411            namespace.getContentInterceptors();
1412        for (int i = 0; i < contentInterceptors.length; i++) {
1413            switch (type) {
1414                case PRE_STORE:
1415                    contentInterceptors[i].preStoreContent
1416                        (token, revisionDescriptors,
1417                         revisionDescriptor, revisionContent);
1418                    break;
1419                case POST_STORE:
1420                    contentInterceptors[i].postStoreContent
1421                        (token, revisionDescriptors,
1422                         revisionDescriptor, revisionContent);
1423                    break;
1424                case POST_RETRIEVE:
1425                    contentInterceptors[i].postRetrieveContent
1426                        (token, revisionDescriptors,
1427                         revisionDescriptor, revisionContent);
1428                    break;
1429                case PRE_REMOVE:
1430                    contentInterceptors[i].preRemoveContent
1431                        (token, revisionDescriptors, revisionDescriptor);
1432                    break;
1433                case POST_REMOVE:
1434                    contentInterceptors[i].postRemoveContent
1435                        (token, revisionDescriptors, revisionDescriptor);
1436                    break;
1437            }
1438        }
1439    }
1440    
1441    /**
1442     *
1443     */

1444    protected String JavaDoc redirectUri( String JavaDoc uri ) {
1445        String JavaDoc result = uri;
1446        
1447        if( uriRedirectorClass != null ) {
1448            try {
1449                Method JavaDoc ru = uriRedirectorClass.getMethod(
1450                    "redirectUri", new Class JavaDoc[]{String JavaDoc.class} );
1451                result = (String JavaDoc)ru.invoke( null, new Object JavaDoc[]{uri} ); // obj=null since method is static
1452
}
1453            catch( Exception JavaDoc x ) {
1454                Domain.warn( "Redirecting of URI "+uri+" failed: "+x.getMessage() );
1455            }
1456        }
1457        
1458        return result;
1459    }
1460    
1461    /**
1462     *
1463     */

1464    protected NodeRevisionNumber redirectLatestRevisionNumber( String JavaDoc uri ) {
1465        NodeRevisionNumber result = null;
1466        
1467        if( uriRedirectorClass != null ) {
1468            try {
1469                Method JavaDoc ru = uriRedirectorClass.getMethod(
1470                    "redirectLatestRevisionNumber", new Class JavaDoc[]{String JavaDoc.class} );
1471                result = (NodeRevisionNumber)ru.invoke( null, new Object JavaDoc[]{uri} ); // obj=null since method is static
1472
}
1473            catch( Exception JavaDoc x ) {
1474                Domain.warn( "Redirecting of latest revision number for "+uri+" failed: "+x.getMessage() );
1475            }
1476        }
1477        
1478        return result;
1479    }
1480    
1481    private boolean isLockNull( NodeRevisionDescriptor nrd ) {
1482        return nrd.propertyValueContains("resourcetype", "lock-null");
1483    }
1484    
1485    private void checkParentExists(String JavaDoc strUri, SlideToken token)
1486        throws ServiceAccessException, ObjectLockedException, AccessDeniedException,
1487        LinkedObjectNotFoundException, ObjectNotFoundException, VetoException {
1488        
1489        if (namespaceConfig.getCreateObjectAction().equals(ActionNode.DEFAULT)) {
1490            // do not check during start-up
1491
return;
1492        }
1493        
1494        String JavaDoc parentUri = String.valueOf(new UriPath(strUri).parent());
1495        try {
1496            NodeRevisionDescriptor parentNrd =
1497                retrieve(token, retrieve(token, parentUri));
1498            if (isLockNull(parentNrd)) {
1499                throw new ObjectNotFoundException(parentUri);
1500            }
1501        }
1502        catch (RevisionDescriptorNotFoundException e) {
1503            throw new ObjectNotFoundException(parentUri);
1504        }
1505    }
1506}
1507
1508
1509
Popular Tags