KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > slide > structure > StructureImpl


1 /*
2  * $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/structure/StructureImpl.java,v 1.49.2.3 2004/10/27 15:43:11 ozeigermann Exp $
3  * $Revision: 1.49.2.3 $
4  * $Date: 2004/10/27 15:43:11 $
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.structure;
25
26 import java.util.ArrayList;
27 import java.util.Date;
28 import java.util.Enumeration;
29 import java.util.List;
30 import java.util.Vector;
31
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.common.UriTokenizer;
39 import org.apache.slide.content.NodeRevisionDescriptor;
40 import org.apache.slide.content.NodeRevisionNumber;
41 import org.apache.slide.content.RevisionDescriptorNotFoundException;
42 import org.apache.slide.event.EventDispatcher;
43 import org.apache.slide.event.StructureEvent;
44 import org.apache.slide.event.VetoException;
45 import org.apache.slide.lock.Lock;
46 import org.apache.slide.lock.ObjectLockedException;
47 import org.apache.slide.security.AccessDeniedException;
48 import org.apache.slide.security.Security;
49 import org.apache.slide.store.Store;
50 import org.apache.slide.util.Configuration;
51
52 /**
53  * Default implementation of the Structure interface.
54  *
55  * @version $Revision: 1.49.2.3 $
56  */

57 public final class StructureImpl implements Structure {
58     
59     
60     // ----------------------------------------------------------- Constructors
61

62     
63     /**
64      * Constructor.
65      *
66      * @param namespace the namespace associated with the helper object
67      * @param namespaceConfig configuration of the namespace
68      * @param securityHelper the associated security helper
69      * @param lockHelper the associated lock helper
70      */

71     public StructureImpl(Namespace namespace, NamespaceConfig namespaceConfig,
72                          Security securityHelper, Lock lockHelper) {
73         this.namespace = namespace;
74         this.namespaceConfig = namespaceConfig;
75         this.securityHelper = securityHelper;
76         this.lockHelper = lockHelper;
77     }
78     
79     
80     // ----------------------------------------------------- Instance Variables
81

82     
83     /**
84      * Namespace.
85      */

86     private Namespace namespace;
87     
88     
89     /**
90      * Namespace configuration.
91      */

92     private NamespaceConfig namespaceConfig;
93     
94     
95     /**
96      * Security helper.
97      */

98     private Security securityHelper;
99     
100     
101     /**
102      * Lock helper.
103      */

104     private Lock lockHelper;
105     
106     
107     // ------------------------------------------------------ Structure Methods
108

109     public String generateUniqueUri(SlideToken token, String parentUri) throws ServiceAccessException {
110         String sequenceName = parentUri.replace('/', '-');
111
112         Uri uri = namespace.getUri(token, parentUri);
113         Store store = uri.getStore();
114         if (!store.isSequenceSupported()) {
115             return null;
116         } else {
117             if (!store.sequenceExists(sequenceName)) {
118                 store.createSequence(sequenceName);
119             }
120             long next = store.nextSequenceValue(sequenceName);
121             String uniqueUri = parentUri + "/" + next;
122             return uniqueUri;
123         }
124     }
125         
126     public Enumeration getChildren(SlideToken token, ObjectNode object)
127         throws ServiceAccessException, ObjectNotFoundException,
128         LinkedObjectNotFoundException, VetoException {
129         Enumeration childrenUri = object.enumerateChildren();
130         Vector result = new Vector();
131         while (childrenUri.hasMoreElements()) {
132             String childUri = (String) childrenUri.nextElement();
133             try {
134                 ObjectNode child = retrieve(token, childUri, false);
135                 result.addElement(child);
136             } catch (AccessDeniedException e) {
137             }
138         }
139         return result.elements();
140     }
141     
142     
143     public ObjectNode getParent(SlideToken token, ObjectNode object)
144         throws ServiceAccessException, ObjectNotFoundException,
145         LinkedObjectNotFoundException, AccessDeniedException, VetoException {
146         String objectUriStr = object.getUri();
147         Uri parentUri = namespace.getUri(token, objectUriStr).getParentUri();
148         if (parentUri == null) {
149             return null;
150         }
151         String parentUriStr = parentUri.toString();
152         ObjectNode parent = retrieve(token, parentUriStr);
153         return parent;
154     }
155     
156     
157     public ObjectNode retrieve(SlideToken token, String strUri)
158         throws ServiceAccessException, ObjectNotFoundException,
159         LinkedObjectNotFoundException, AccessDeniedException, VetoException {
160         return retrieve(token, strUri, true);
161     }
162     
163     
164     public ObjectNode retrieve(SlideToken token, String strUri,
165                                boolean translateLastUriElement)
166         throws ServiceAccessException, ObjectNotFoundException,
167         LinkedObjectNotFoundException, AccessDeniedException, VetoException {
168         
169         Uri uri = namespace.getUri(token, strUri);
170         
171         ObjectNode result = null;
172         
173         // Fire event
174
if ( StructureEvent.RETRIEVE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.RETRIEVE, new StructureEvent(this, token, namespace, strUri));
175
176         // First of all, we try to load the object directly from the given Uri.
177
try {
178             result = uri.getStore().retrieveObject(uri);
179             securityHelper.checkCredentials
180                 (token, result, namespaceConfig.getReadObjectAction());
181             if ((translateLastUriElement) && (result instanceof LinkNode)) {
182                 LinkNode link = (LinkNode) result;
183                 Uri linkedUri = namespace.getUri(token, link.getLinkedUri());
184                 result = linkedUri.getStore()
185                     .retrieveObject(linkedUri);
186                 securityHelper.checkCredentials
187                     (token, result, namespaceConfig.getReadObjectAction());
188             }
189         } catch (ObjectNotFoundException e) {
190         }
191         
192         // If the attempt to load the uri failed, it means there is at least
193
// one link in the uri (or that the uri doe'sn't have any associated
194
// object).
195
if (result == null) {
196             
197             String resolvedUri = uri.toString();
198             
199             // 1 - Tokemization of the Uri
200
UriTokenizer uriTokenizer = new UriTokenizer(token, uri.getNamespace(),
201                                                          resolvedUri);
202             
203             // 2 - For each element of the Uri
204
Uri courUri = null;
205             ObjectNode courObject = null;
206             while (uriTokenizer.hasMoreElements()) {
207                 
208                 // 3 - Load object's class from the uri. If the object
209
// does not exist, a DataException is thrown.
210
courUri = uriTokenizer.nextUri();
211                 courObject = courUri.getStore()
212                     .retrieveObject(courUri);
213                 
214                 // We check to see if the credentials gives access to
215
//the current object
216
securityHelper.checkCredentials
217                     (token, courObject, namespaceConfig.getReadObjectAction());
218                 
219                 // 4 - Test if object is a link, ie if it is an instance
220
// of LinkNode or one of its subclasses
221
if (((translateLastUriElement)
222                          && (courObject instanceof LinkNode)) ||
223                         ((!translateLastUriElement)
224                              && (uriTokenizer.hasMoreElements())
225                              && (courObject instanceof LinkNode))
226                    ) {
227                     
228                     // 5 - If the object is a link, we get the uri of
229
// the linked object
230
// Note : courUri still IS the Uri of the link, and so,
231
// in a way courUri is the parent of linkedUri.
232
Uri linkedUri = namespace
233                         .getUri(token, ((LinkNode) courObject).getLinkedUri());
234                     
235                     // 6 - We replace the courUri scope in the original uri
236
String courStrUri = courUri.toString();
237                     resolvedUri = linkedUri.toString()
238                         + resolvedUri.substring(courStrUri.length());
239                     
240                     // 7 - We tokenize again the uri
241
uriTokenizer = new UriTokenizer(token, uri.getNamespace(),
242                                                     resolvedUri);
243                     
244                     // 8 - We parse it till we get back to the point
245
// where we stopped
246
boolean isUriFound = false;
247                     while ((!isUriFound) && (uriTokenizer.hasMoreElements())) {
248                         if (linkedUri.equals(uriTokenizer.nextUri())) {
249                             isUriFound = true;
250                         }
251                     }
252                     if (!isUriFound) {
253                         throw new LinkedObjectNotFoundException(courUri,
254                                                                 resolvedUri);
255                     }
256                     
257                 }
258                 
259                 // 9 - We continue to go down in the Uri tree
260
}
261             
262             // 10 - We return the last object which has been found
263

264             result = courObject;
265         }
266         
267         return result;
268         
269     }
270     
271     
272     public void create(SlideToken token, ObjectNode object,
273                        String strUri)
274         throws ServiceAccessException, ObjectAlreadyExistsException,
275         ObjectNotFoundException, LinkedObjectNotFoundException,
276         AccessDeniedException, ObjectLockedException, VetoException {
277
278         // Fire event
279
if ( StructureEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.CREATE, new StructureEvent(this, token, namespace, strUri));
280         
281         // Checking roles
282
Enumeration roles = securityHelper.getRoles(object);
283         while (roles.hasMoreElements()) {
284             if (!securityHelper.hasRole(token, (String)roles.nextElement())) {
285                 // Allow only the namespace admin to create roles
286
// he doesn't have
287
Uri rootUri = namespace.getUri(token, "/");
288                 ObjectNode rootObject =
289                     rootUri.getStore().retrieveObject(rootUri);
290                 securityHelper.checkCredentials
291                     (token, rootObject,
292                      namespaceConfig.getGrantPermissionAction());
293                 break;
294             }
295         }
296         
297         String resolvedUri = strUri;
298         
299         // 1 - Tokenization of the Uri
300
UriTokenizer uriTokenizer = new UriTokenizer(token, namespace, resolvedUri);
301         
302         // 2 - For each element of the Uri
303
Uri courUri = null;
304         ObjectNode courObject = null;
305         ObjectNode parentObject = null;
306         
307         boolean alreadyExists = false;
308         
309         while (uriTokenizer.hasMoreElements()) {
310             
311             parentObject = courObject;
312             
313             // 3 - Load object's class from the uri. If the object does
314
// not exist, a DataException is thrown.
315
courUri = uriTokenizer.nextUri();
316             try {
317                 courObject = courUri.getStore()
318                     .retrieveObject(courUri);
319                 securityHelper
320                     .checkCredentials(token, courObject,
321                                       namespaceConfig.getReadObjectAction());
322                 if (!uriTokenizer.hasMoreElements()) {
323                     // The object already exists
324
alreadyExists = true;
325                 }
326             } catch (ObjectNotFoundException e) {
327                 // Load failed, probably because object was not found
328
// We try to create a new one.
329
// We have to test if the uri is the last in the list,
330
// we must create the requested element.
331
// By default, we create a SubjectNode.
332
ObjectNode newObject = null;
333                 if (uriTokenizer.hasMoreElements()) {
334                     throw new ObjectNotFoundException(courUri);
335                 } else {
336                     newObject = object;
337                 }
338                 if (parentObject != null) {
339
340                     // lock exclusively before anyone can get a read lock
341
// do not lock in external transaction because this might lead to distributed deadlocks
342
// between Slide and store
343
if (!token.isExternalTransaction()) {
344                         namespace.getUri(token, parentObject.getUri()).getStore().exclusiveTransientLock(
345                             parentObject.getUri().toString());
346                     }
347                     
348                     securityHelper
349                         .checkCredentials(token, courObject, namespaceConfig
350                                               .getBindMemberAction());
351                     
352                     // Now creating the new object
353
newObject.setUri(courUri.toString());
354                     courUri.getStore().createObject(courUri, newObject);
355                     
356                     // re-read to obtain UURI
357
// newObject = courUri.getStore().retrieveObject(courUri);
358

359                     // re-read the parent taking the forceEnlistment flag into account
360
Uri parentUri = namespace.getUri(token, parentObject.getUri());
361                     parentObject = parentUri.getStore().retrieveObject(parentUri);
362                     // Add the newly created object to its parent's
363
// children list
364
ObjectNode oldChild = null;
365                     // we can check the parentUri, it's in the same store as newObject
366
if (Configuration.useBinding(parentUri.getStore())) {
367                         String bindingName = newObject.getPath().lastSegment();
368                         if (parentObject.hasBinding(bindingName)) {
369                             oldChild = retrieve(token, parentObject.getUri()+"/"+bindingName, false);
370                             parentObject.removeChild(oldChild);
371                             store(token, oldChild);
372                         }
373                     }
374                     lockHelper.checkLock
375                         (token, parentObject, namespaceConfig.getCreateObjectAction());
376                     parentObject.addChild(newObject);
377                     //namespace.getUri(token, parentObject.getUri())
378
//.getDataSource().storeObject(parentObject, false);
379
store(token, parentObject, true);
380                     store(token, newObject);
381                     
382                 } else {
383                     throw new ObjectNotFoundException(courUri);
384                 }
385                 courObject = newObject;
386             }
387             
388             // 4 - Test if object is a link, ie if it is an instance of
389
// LinkNode or one of its subclasses
390
if ((uriTokenizer.hasMoreElements())
391                 && (courObject instanceof LinkNode)) {
392                 
393                 // 5 - If the object is a link, we get the uri of the
394
// linked object
395
// Note : courUri still IS the Uri of the link, and so,
396
// in a way courUri is the parent of linkedUri.
397
Uri linkedUri = namespace
398                     .getUri(token, ((LinkNode) courObject).getLinkedUri());
399                 
400                 // 6 - We replace the courUri scope in the original uri
401
String courStrUri = courUri.toString();
402                 resolvedUri = linkedUri.toString()
403                     + resolvedUri.substring(courStrUri.length());
404                 
405                 // 7 - We tokenize again the uri
406
uriTokenizer = new UriTokenizer(token, namespace, resolvedUri);
407                 
408                 // 8 - We parse it till we get back to the point
409
// where we stopped
410
boolean isUriFound = false;
411                 while ((!isUriFound) && (uriTokenizer.hasMoreElements())) {
412                     if (linkedUri.equals(uriTokenizer.nextUri())) {
413                         isUriFound = true;
414                     }
415                 }
416                 if (!isUriFound) {
417                     throw new LinkedObjectNotFoundException
418                         (courUri, resolvedUri);
419                 }
420                 
421             }
422             
423             // 9 - We continue to go down in the Uri tree
424
}
425         
426         if (alreadyExists) {
427             if (courUri.isStoreRoot()) {
428                 // if the object already exists map it anyway into
429
// the node hierarchy, to prevent loose of nodes
430
// during start up
431
if (parentObject != null && !parentObject.hasChild(courObject)) {
432                     parentObject.addChild(courObject);
433                     store(token, parentObject, true);
434                 }
435             }
436             throw new ObjectAlreadyExistsException(strUri);
437         }
438     }
439     
440     public void createLink(SlideToken token, LinkNode link,
441                            String linkUri, ObjectNode linkedObject)
442         throws ServiceAccessException, ObjectAlreadyExistsException,
443         ObjectNotFoundException, LinkedObjectNotFoundException,
444         AccessDeniedException, ObjectLockedException, VetoException {
445         link.setLinkedUri(linkedObject.getUri());
446
447         // Fire event
448
if ( StructureEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.CREATE_LINK, new StructureEvent(this, token, link, linkUri));
449
450         create(token, link, linkUri);
451     }
452     
453     
454     public void store(SlideToken token, ObjectNode object)
455         throws ServiceAccessException, ObjectNotFoundException,
456         AccessDeniedException, LinkedObjectNotFoundException, VetoException {
457         
458         store(token, object, false);
459     }
460     
461     
462     protected void store(SlideToken token, ObjectNode object, boolean setModificationDate)
463         throws ServiceAccessException, ObjectNotFoundException,
464         AccessDeniedException, LinkedObjectNotFoundException, VetoException {
465
466         // Fire event
467
if ( StructureEvent.STORE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.STORE, new StructureEvent(this, token, namespace, object));
468         
469         // Checking roles
470
Enumeration roles = securityHelper.getRoles(object);
471         while (roles.hasMoreElements()) {
472             if (!securityHelper.hasRole(token, (String)roles.nextElement())) {
473                 // Allow only the namespace admin to create roles
474
// he doesn't have
475
Uri rootUri = namespace.getUri(token, "/");
476                 ObjectNode rootObject =
477                     rootUri.getStore().retrieveObject(rootUri);
478                 securityHelper.checkCredentials
479                     (token, rootObject,
480                      namespaceConfig.getGrantPermissionAction());
481                 break;
482             }
483         }
484         
485         // working on realObject, we will lose changes immediatly done before call of store
486
// i observerd this with some BIND testcases
487
//ObjectNode realObject = retrieve(token, object.getUri(), false);
488
securityHelper
489             .checkCredentials(token, object,
490                               namespaceConfig.getCreateObjectAction());
491         Uri uri = namespace.getUri(token, object.getUri());
492         Store store = uri.getStore();
493         store.storeObject(uri, object);
494         
495         if (setModificationDate) {
496             try {
497                 NodeRevisionDescriptor revisionDescriptor = store.retrieveRevisionDescriptor(uri, new NodeRevisionNumber());
498                 revisionDescriptor.setModificationDate(new Date());
499                 revisionDescriptor.setModificationUser(
500                     securityHelper.getPrincipal(token).getPath().lastSegment());
501                 store.storeRevisionDescriptor(uri, revisionDescriptor );
502             }
503             catch (RevisionDescriptorNotFoundException e) {
504                 // ignore silently
505
}
506         }
507     }
508     
509     
510     /**
511      * Method remove
512      *
513      * @param token a SlideToken
514      * @param object an ObjectNode
515      *
516      * @throws ServiceAccessException
517      * @throws ObjectNotFoundException
518      * @throws ObjectHasChildrenException
519      * @throws AccessDeniedException
520      * @throws LinkedObjectNotFoundException
521      * @throws ObjectLockedException
522      *
523      */

524     public void remove(SlideToken token, ObjectNode object)
525         throws ServiceAccessException, ObjectNotFoundException,
526         ObjectHasChildrenException, AccessDeniedException,
527         LinkedObjectNotFoundException, ObjectLockedException, VetoException {
528         
529         ObjectNode nodeToDelete = retrieve(token, object.getUri(), false);
530         Uri uri = namespace.getUri(token, nodeToDelete.getUri());
531         
532         // Fire event
533
if ( StructureEvent.REMOVE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.REMOVE, new StructureEvent(this, token, object, uri.toString()));
534
535         if (!object.getUri().equals("/")) {
536             Uri curUri = namespace.getUri(token, nodeToDelete.getUri());
537             Uri parentUri = curUri.getParentUri();
538             
539             // lock exclusively before anyone can get a read lock
540
// do not lock in external transaction because this might lead to distributed deadlocks
541
// between Slide and store
542
if (!token.isExternalTransaction()) {
543                 parentUri.getStore().exclusiveTransientLock(parentUri.toString());
544             }
545             
546             ObjectNode parentNode = parentUri.getStore().retrieveObject(parentUri);
547             
548             securityHelper.checkCredentials
549                 (token, nodeToDelete, namespaceConfig.getRemoveObjectAction());
550             securityHelper.checkCredentials
551                 (token, parentNode, namespaceConfig.getUnbindMemberAction());
552             lockHelper.checkLock
553                 (token, nodeToDelete, namespaceConfig.getRemoveObjectAction());
554             lockHelper.checkLock
555                 (token, parentNode, namespaceConfig.getUnbindMemberAction());
556
557             parentNode.removeChild(nodeToDelete);
558             store(token, parentNode, true);
559             
560             if (Configuration.useBinding(curUri.getStore()) && nodeToDelete.numberOfParentBindings() > 0) {
561                 store(token, nodeToDelete);
562             }
563             else {
564                 Enumeration enum = nodeToDelete.enumerateChildren();
565                 if (enum.hasMoreElements()) {
566                     throw new ObjectHasChildrenException(uri);
567                 }
568                 uri.getStore().removeObject(uri, nodeToDelete);
569             }
570         }
571     }
572     
573     
574     /**
575      * Modifies the collection identified by <b>collectionNode</b>, by adding a new binding
576      * from the specified segment to the resource identified by <b>sourceNode</b>.
577      *
578      * @param token a SlideToken
579      * @param collectionNode an ObjectNode
580      * @param segment a String
581      * @param sourceNode an ObjectNode
582      *
583      * @throws ServiceAccessException
584      * @throws ObjectNotFoundException
585      * @throws AccessDeniedException
586      * @throws LinkedObjectNotFoundException
587      * @throws ObjectLockedException
588      *
589      */

590     public void addBinding(SlideToken token, ObjectNode collectionNode, String segment, ObjectNode sourceNode) throws ServiceAccessException, ObjectNotFoundException, AccessDeniedException, LinkedObjectNotFoundException, ObjectLockedException, CrossServerBindingException, VetoException {
591         if (Configuration.useBinding(namespace.getUri(token, collectionNode.getUri()).getStore())) {
592             collectionNode = retrieve(token, collectionNode.getUri(), false);
593             sourceNode = retrieve(token, sourceNode.getUri(), false);
594             Uri collectionUri = namespace.getUri(token, collectionNode.getUri());
595 // Uri sourceUri = namespace.getUri(token, sourceNode.getUri());
596

597             // Fire event
598
if ( StructureEvent.ADD_BINDING.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.ADD_BINDING, new StructureEvent(this, token, sourceNode, collectionUri.toString()));
599
600 // if (collectionUri.getStore() != sourceUri.getStore()) {
601
// throw new CrossServerBindingException(collectionNode.getUri(), sourceNode.getUri());
602
// }
603

604             lockHelper.checkLock
605                 (token, collectionNode, namespaceConfig.getCreateObjectAction());
606             
607             ObjectNode oldChild = null;
608             if (collectionNode.hasBinding(segment)) {
609                 oldChild = retrieve(token, collectionNode.getUri()+"/"+segment, false);
610                 lockHelper.checkLock
611                     (token, oldChild, namespaceConfig.getCreateObjectAction());
612                 collectionNode.removeChild(oldChild);
613                 store( token, oldChild );
614             }
615             collectionNode.addBinding( segment, sourceNode );
616             
617             store( token, collectionNode, true );
618             store( token, sourceNode );
619         }
620     }
621     
622     
623     /**
624      * Modifies the collection identified by <b>collectionNode</b>, by removing the binding
625      * for the specified segment.
626      *
627      * @param token a SlideToken
628      * @param collectionNode an ObjectNode
629      * @param segment a String
630      *
631      * @throws ServiceAccessException
632      * @throws ObjectNotFoundException
633      * @throws AccessDeniedException
634      * @throws LinkedObjectNotFoundException
635      * @throws ObjectLockedException
636      *
637      */

638     public void removeBinding(SlideToken token, ObjectNode collectionNode, String segment) throws ServiceAccessException, ObjectNotFoundException, AccessDeniedException, LinkedObjectNotFoundException, ObjectLockedException, VetoException {
639         if (Configuration.useBinding(namespace.getUri(token, collectionNode.getUri()).getStore())) {
640             collectionNode = retrieve(token, collectionNode.getUri(), false);
641             ObjectNode childNode = retrieve(token, collectionNode.getUri()+"/"+segment, false);
642             
643             // Fire event
644
if ( StructureEvent.REMOVE_BINDING.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.REMOVE_BINDING, new StructureEvent(this, token, childNode, collectionNode.getUri()));
645
646             lockHelper.checkLock
647                 (token, collectionNode, namespaceConfig.getCreateObjectAction());
648             lockHelper.checkLock
649                 (token, childNode, namespaceConfig.getCreateObjectAction());
650             
651             collectionNode.removeChild( childNode );
652             
653             store( token, childNode );
654             store( token, collectionNode, true );
655         }
656     }
657     
658     
659     /**
660      * Return all parents of this object node. If pathOnly=true, only parents
661      * on the path of the specified ObjectNode are returned, all parents (binding!)
662      * otherwise. If storeOnly=true, only parents within the scope of the store
663      * in charge of the specified ObjectNode are returned, parents up to the root
664      * ObjectNode (uri="/") otherwise.
665      *
666      * @param token a SlideToken
667      * @param object an ObjectNode
668      * @param pathOnly if true, only parents on the path of the specified
669      * ObjectNode are returned, all parents (binding!)
670      * otherwise
671      * @param storeOnly if true, only parents within the scope of the store
672      * in charge of the specified ObjectNode are returned,
673      * parents up to the root ObjectNode (uri="/") otherwise
674      * @param includeSelf if true, the ObjectNode specified by object is included,
675      * otherwise, it is excluded
676      *
677      * @return a List of ObjectNode instances
678      *
679      * @throws ServiceAccessException
680      * @throws ObjectNotFoundException
681      * @throws LinkedObjectNotFoundException
682      * @throws AccessDeniedException
683      *
684      */

685     public List getParents(SlideToken token, ObjectNode object, boolean pathOnly, boolean storeOnly, boolean includeSelf) throws ServiceAccessException, ObjectNotFoundException, LinkedObjectNotFoundException, AccessDeniedException, VetoException {
686         List result = new ArrayList();
687
688         if (pathOnly) {
689             String[] uriTokens = object.getPath().tokens();
690             UriPath path = new UriPath("/");
691             Uri currentUri = namespace.getUri(token, path.toString());
692             Uri objectUri = namespace.getUri(token, object.getUri());
693             if (!storeOnly || currentUri.getStore() == objectUri.getStore()) {
694                 result.add( retrieve(token, path.toString()) );
695             }
696             
697             for (int i = 0; i < uriTokens.length; i++) {
698                 path = path.child( uriTokens[i] );
699                 currentUri = namespace.getUri(token, path.toString());
700                 if (i == uriTokens.length - 1 && !includeSelf) {
701                     break;
702                 }
703                 if (!storeOnly || currentUri.getStore() == objectUri.getStore()) {
704                     result.add( retrieve(token, path.toString()) );
705                 }
706             }
707 }
708         else {
709             // TODO
710
}
711         
712         return result;
713     }
714 }
715
716
Popular Tags