You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by df...@apache.org on 2005/12/12 15:22:08 UTC

svn commit: r356256 - /jakarta/slide/trunk/src/share/org/apache/slide/structure/StructureImpl.java

Author: dflorey
Date: Mon Dec 12 06:22:02 2005
New Revision: 356256

URL: http://svn.apache.org/viewcvs?rev=356256&view=rev
Log:
Minor modifications to enable DASL with binding store

Modified:
    jakarta/slide/trunk/src/share/org/apache/slide/structure/StructureImpl.java

Modified: jakarta/slide/trunk/src/share/org/apache/slide/structure/StructureImpl.java
URL: http://svn.apache.org/viewcvs/jakarta/slide/trunk/src/share/org/apache/slide/structure/StructureImpl.java?rev=356256&r1=356255&r2=356256&view=diff
==============================================================================
--- jakarta/slide/trunk/src/share/org/apache/slide/structure/StructureImpl.java (original)
+++ jakarta/slide/trunk/src/share/org/apache/slide/structure/StructureImpl.java Mon Dec 12 06:22:02 2005
@@ -47,652 +47,701 @@
 import org.apache.slide.lock.ObjectLockedException;
 import org.apache.slide.security.AccessDeniedException;
 import org.apache.slide.security.Security;
+import org.apache.slide.store.ResourceId;
 import org.apache.slide.store.Store;
 import org.apache.slide.util.Configuration;
 
 /**
  * Default implementation of the Structure interface.
- *
+ * 
  * @version $Revision$
  */
 public class StructureImpl implements Structure {
-    
-    
-    // ----------------------------------------------------------- Constructors
-    
-    
-    /**
-     * Constructor.
-     *
-     * @param namespace the namespace associated with the helper object
-     * @param namespaceConfig configuration of the namespace
-     * @param securityHelper the associated security helper
-     * @param lockHelper the associated lock helper
-     */
-    public StructureImpl(Namespace namespace, NamespaceConfig namespaceConfig,
-                         Security securityHelper, Lock lockHelper) {
-        this.namespace = namespace;
-        this.namespaceConfig = namespaceConfig;
-        this.securityHelper = securityHelper;
-        this.lockHelper = lockHelper;
-    }
-    
-    
-    // ----------------------------------------------------- Instance Variables
-    
-    
-    /**
-     * Namespace.
-     */
-    private Namespace namespace;
-    
-    
-    /**
-     * Namespace configuration.
-     */
-    private NamespaceConfig namespaceConfig;
-    
-    
-    /**
-     * Security helper.
-     */
-    private Security securityHelper;
-    
-    
-    /**
-     * Lock helper.
-     */
-    private Lock lockHelper;
-    
-    
-    // ------------------------------------------------------ Structure Methods
-    
-    public String generateUniqueUri(SlideToken token, String parentUri) throws ServiceAccessException {
-        String sequenceName = parentUri.replace('/', '-');
-
-        Uri uri = namespace.getUri(token, parentUri);
-        Store store = uri.getStore();
-        if (!store.isSequenceSupported()) {
-            return null;
-        } else {
-            if (!store.sequenceExists(sequenceName)) {
-                store.createSequence(sequenceName);
-            }
-            long next = store.nextSequenceValue(sequenceName);
-            String uniqueUri = parentUri + "/" + next;
-            return uniqueUri;
-        }
-    }
-        
-    public Enumeration getChildren(SlideToken token, ObjectNode object)
-        throws ServiceAccessException, ObjectNotFoundException,
-        LinkedObjectNotFoundException, VetoException {
-        Enumeration childrenUri = object.enumerateChildren();
-        Vector result = new Vector();
-        while (childrenUri.hasMoreElements()) {
-            String childUri = (String) childrenUri.nextElement();
-            try {
-                ObjectNode child = retrieve(token, childUri, false);
-                result.addElement(child);
-            } catch (AccessDeniedException e) {
-            }
-        }
-        return result.elements();
-    }
-    
-    
-    public ObjectNode getParent(SlideToken token, ObjectNode object)
-        throws ServiceAccessException, ObjectNotFoundException,
-        LinkedObjectNotFoundException, AccessDeniedException, VetoException {
-        String objectUriStr = object.getUri();
-        Uri parentUri = namespace.getUri(token, objectUriStr).getParentUri();
-        if (parentUri == null) {
-            return null;
-        }
-        String parentUriStr = parentUri.toString();
-        ObjectNode parent = retrieve(token, parentUriStr);
-        return parent;
-    }
-    
-    
-    public ObjectNode retrieve(SlideToken token, String strUri)
-        throws ServiceAccessException, ObjectNotFoundException,
-        LinkedObjectNotFoundException, AccessDeniedException, VetoException {
-        return retrieve(token, strUri, true);
-    }
-    
-    
-    public ObjectNode retrieve(SlideToken token, String strUri,
-                               boolean translateLastUriElement)
-        throws ServiceAccessException, ObjectNotFoundException,
-        LinkedObjectNotFoundException, AccessDeniedException, VetoException {
-        
-        Uri uri = namespace.getUri(token, strUri);
-        
-        ObjectNode result = null;
-        
-        // Fire event
-        if ( StructureEvent.RETRIEVE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.RETRIEVE, new StructureEvent(this, token, namespace, strUri));
-
-        // First of all, we try to load the object directly from the given Uri.
-        try {
-            result = uri.getStore().retrieveObject(uri);
-            securityHelper.checkCredentials(token, result, 
-                    namespaceConfig.getReadObjectAction());
-            if ((translateLastUriElement) && (result instanceof LinkNode)) {
-                LinkNode link = (LinkNode) result;
-                Uri linkedUri = namespace.getUri(token, link.getLinkedUri());
-                result = linkedUri.getStore().retrieveObject(linkedUri);
-                securityHelper.checkCredentials(token, result, 
-                        namespaceConfig.getReadObjectAction());
-            }
-        } catch (ObjectNotFoundException e) {
-        }
-        
-        // If the attempt to load the uri failed, it means there is at least
-        // one link in the uri (or that the uri doe'sn't have any associated
-        // object).
-        if (result == null) {
-            
-            String resolvedUri = uri.toString();
-            
-            // 1 - Tokemization of the Uri
-            UriTokenizer uriTokenizer = new UriTokenizer(token, uri.getNamespace(),
-                                                         resolvedUri);
-            
-            // 2 - For each element of the Uri
-            Uri courUri = null;
-            ObjectNode courObject = null;
-            while (uriTokenizer.hasMoreElements()) {
-                
-                // 3 - Load object's class from the uri. If the object
-                // does not exist, a DataException is thrown.
-                courUri = uriTokenizer.nextUri();
-                courObject = courUri.getStore().retrieveObject(courUri);
-                
-                // We check to see if the credentials gives access to
-                //the current object
-                if (Domain.getParameter("ancestors-read-permissions-required", "true").equals("true")) {
-                    securityHelper.checkCredentials(token, courObject, 
-                            namespaceConfig.getReadObjectAction());
-                }
-                
-                // 4 - Test if object is a link, ie if it is an instance
-                // of LinkNode or one of its subclasses
-                if (((translateLastUriElement)
-                         && (courObject instanceof LinkNode)) ||
-                        ((!translateLastUriElement)
-                             && (uriTokenizer.hasMoreElements())
-                             && (courObject instanceof LinkNode))
-                   ) {
-                    
-                    // 5 - If the object is a link, we get the uri of
-                    // the linked object
-                    // Note : courUri still IS the Uri of the link, and so,
-                    // in a way courUri is the parent of linkedUri.
-                    Uri linkedUri = namespace.getUri(token, 
-                            ((LinkNode) courObject).getLinkedUri());
-                    
-                    // 6 - We replace the courUri scope in the original uri
-                    String courStrUri = courUri.toString();
-                    resolvedUri = linkedUri.toString()
-                        + resolvedUri.substring(courStrUri.length());
-                    
-                    // 7 - We tokenize again the uri
-                    uriTokenizer = new UriTokenizer(token, uri.getNamespace(),
-                                                    resolvedUri);
-                    
-                    // 8 - We parse it till we get back to the point
-                    // where we stopped
-                    boolean isUriFound = false;
-                    while ((!isUriFound) && (uriTokenizer.hasMoreElements())) {
-                        if (linkedUri.equals(uriTokenizer.nextUri())) {
-                            isUriFound = true;
-                        }
-                    }
-                    if (!isUriFound) {
-                        throw new LinkedObjectNotFoundException(courUri,
-                                                                resolvedUri);
-                    }
-                    
-                }
-                
-                // 9 - We continue to go down in the Uri tree
-            }
-            
-            // 10 - We return the last object which has been found
-            
-            result = courObject;
-        }
-        
-        return result;
-        
-    }
-    
-    
-    public void create(SlideToken token, ObjectNode object, String strUri)
-        throws ServiceAccessException, ObjectAlreadyExistsException,
-        ObjectNotFoundException, LinkedObjectNotFoundException,
-        AccessDeniedException, ObjectLockedException, VetoException {
-
-        // Fire event
-        if ( StructureEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.CREATE, new StructureEvent(this, token, namespace, strUri));
-        
-        // Checking roles
-        Enumeration roles = securityHelper.getRoles(object);
-        while (roles.hasMoreElements()) {
-            if (!securityHelper.hasRole(token, (String)roles.nextElement())) {
-                // Allow only the namespace admin to create roles
-                // he doesn't have
-                Uri rootUri = namespace.getUri(token, "/");
-                ObjectNode rootObject = rootUri.getStore().retrieveObject(rootUri);
-                securityHelper.checkCredentials(token, rootObject,
-                     namespaceConfig.getGrantPermissionAction());
-                break;
-            }
-        }
-        
-        String resolvedUri = strUri;
-        
-        // 1 - Tokenization of the Uri
-        UriTokenizer uriTokenizer = new UriTokenizer(token, namespace, resolvedUri);
-        
-        // 2 - For each element of the Uri
-        Uri courUri = null;
-        ObjectNode courObject = null;
-        ObjectNode parentObject = null;
-        
-        boolean alreadyExists = false;
-        
-        while (uriTokenizer.hasMoreElements()) {
-            
-            parentObject = courObject;
-            
-            // 3 - Load object's class from the uri. If the object does
-            // not exist, a DataException is thrown.
-            courUri = uriTokenizer.nextUri();
-            try {
-                courObject = courUri.getStore().retrieveObject(courUri);
-                if (Domain.getParameter("ancestors-read-permissions-required", "true").equals("true")) {
-                    securityHelper.checkCredentials(token, courObject, 
-                            namespaceConfig.getReadObjectAction());
-                }
-                if (!uriTokenizer.hasMoreElements()) {
-                    // The object already exists
-                    alreadyExists = true;
-                }
-            } catch (ObjectNotFoundException e) {
-                // Load failed, probably because object was not found
-                // We try to create a new one.
-                // We have to test if the uri is the last in the list,
-                // we must create the requested element.
-                // By default, we create a SubjectNode.
-                ObjectNode newObject = null;
-                if (uriTokenizer.hasMoreElements()) {
-                    throw new ObjectNotFoundException(courUri);
-                } else {
-                    newObject = object;
-                }
-                if (parentObject != null) {
-
-                    securityHelper.checkCredentials(token, courObject, 
-                            namespaceConfig.getBindMemberAction());
-                    
-                    // Now creating the new object
-                    newObject.setUri(courUri.toString());
-                    courUri.getStore().createObject(courUri, newObject);
-                    
-                    // re-read to obtain UURI
-                    //                    newObject = courUri.getStore().retrieveObject(courUri);
-                    
-                    // re-read the parent taking the forceEnlistment flag into account
-                    Uri parentUri = namespace.getUri(token, parentObject.getUri());
-                    parentObject = parentUri.getStore().retrieveObject(parentUri);
-                    // Add the newly created object to its parent's
-                    // children list
-                    ObjectNode oldChild = null;
-                    // we can check the parentUri, it's in the same store as newObject
-                    if (Configuration.useBinding(parentUri.getStore())) {
-                        String bindingName = newObject.getPath().lastSegment();
-                        if (parentObject.hasBinding(bindingName)) {
-                            oldChild = retrieve(token, parentObject.getUri()+"/"+bindingName, false);
-                            parentObject.removeChild(oldChild);
-                            store(token, oldChild);
-                        }
-                    }
-                    lockHelper.checkLock
-                        (token, parentObject, namespaceConfig.getCreateObjectAction());
-                    parentObject.addChild(newObject);
-                    //namespace.getUri(token, parentObject.getUri())
-                    //.getDataSource().storeObject(parentObject, false);
-                    store(token, parentObject, true);
-                    store(token, newObject);
-                    
-                } else {
-                    throw new ObjectNotFoundException(courUri);
-                }
-                courObject = newObject;
-            }
-            
-            // 4 - Test if object is a link, ie if it is an instance of
-            // LinkNode or one of its subclasses
-            if ((uriTokenizer.hasMoreElements())
-                && (courObject instanceof LinkNode)) {
-                
-                // 5 - If the object is a link, we get the uri of the
-                // linked object
-                // Note : courUri still IS the Uri of the link, and so,
-                // in a way courUri is the parent of linkedUri.
-                Uri linkedUri = namespace
-                    .getUri(token, ((LinkNode) courObject).getLinkedUri());
-                
-                // 6 - We replace the courUri scope in the original uri
-                String courStrUri = courUri.toString();
-                resolvedUri = linkedUri.toString()
-                    + resolvedUri.substring(courStrUri.length());
-                
-                // 7 - We tokenize again the uri
-                uriTokenizer = new UriTokenizer(token, namespace, resolvedUri);
-                
-                // 8 - We parse it till we get back to the point
-                // where we stopped
-                boolean isUriFound = false;
-                while ((!isUriFound) && (uriTokenizer.hasMoreElements())) {
-                    if (linkedUri.equals(uriTokenizer.nextUri())) {
-                        isUriFound = true;
-                    }
-                }
-                if (!isUriFound) {
-                    throw new LinkedObjectNotFoundException
-                        (courUri, resolvedUri);
-                }
-                
-            }
-            
-            // 9 - We continue to go down in the Uri tree
-        }
-        
-        if (alreadyExists) {
-            if (courUri.isStoreRoot()) {
-                // if the object already exists map it anyway into
-                // the node hierarchy, to prevent loose of nodes
-                // during start up
-                if (parentObject != null && !parentObject.hasChild(courObject)) {
-                    parentObject.addChild(courObject);
-                    store(token, parentObject, true);
-                }
-            }
-            throw new ObjectAlreadyExistsException(strUri);
-        }
-    }
-    
-    public void createLink(SlideToken token, LinkNode link,
-                           String linkUri, ObjectNode linkedObject)
-        throws ServiceAccessException, ObjectAlreadyExistsException,
-        ObjectNotFoundException, LinkedObjectNotFoundException,
-        AccessDeniedException, ObjectLockedException, VetoException {
-        link.setLinkedUri(linkedObject.getUri());
-
-        // Fire event
-        if ( StructureEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.CREATE_LINK, new StructureEvent(this, token, link, linkUri));
-
-        create(token, link, linkUri);
-    }
-    
-    
-    public void store(SlideToken token, ObjectNode object)
-        throws ServiceAccessException, ObjectNotFoundException,
-        AccessDeniedException, LinkedObjectNotFoundException, VetoException {
-        
-        store(token, object, false);
-    }
-    
-    
-    protected void store(SlideToken token, ObjectNode object, boolean setModificationDate)
-        throws ServiceAccessException, ObjectNotFoundException,
-        AccessDeniedException, LinkedObjectNotFoundException, VetoException {
-
-        // Fire event
-        if ( StructureEvent.STORE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.STORE, new StructureEvent(this, token, namespace, object));
-        
-        // Checking roles
-        Enumeration roles = securityHelper.getRoles(object);
-        while (roles.hasMoreElements()) {
-            if (!securityHelper.hasRole(token, (String)roles.nextElement())) {
-                // Allow only the namespace admin to create roles
-                // he doesn't have
-                Uri rootUri = namespace.getUri(token, "/");
-                ObjectNode rootObject = rootUri.getStore().retrieveObject(rootUri);
-                securityHelper.checkCredentials(token, rootObject, 
-                        namespaceConfig.getGrantPermissionAction());
-                break;
-            }
-        }
-        
-        // working on realObject, we will lose changes immediatly done before call of store
-        // i observerd this with some BIND testcases
-        //ObjectNode realObject = retrieve(token, object.getUri(), false);
-        securityHelper.checkCredentials(token, object,
-                namespaceConfig.getCreateObjectAction());
-        Uri uri = namespace.getUri(token, object.getUri());
-        Store store = uri.getStore();
-        store.storeObject(uri, object);
-        
-        if (setModificationDate) {
-            try {
-                NodeRevisionDescriptor revisionDescriptor = store.retrieveRevisionDescriptor(uri, new NodeRevisionNumber());
-                revisionDescriptor.setModificationDate(new Date());
-                revisionDescriptor.setModificationUser(
-                    securityHelper.getPrincipal(token).getPath().lastSegment());
-                store.storeRevisionDescriptor(uri, revisionDescriptor );
-            }
-            catch (RevisionDescriptorNotFoundException e) {
-                // ignore silently
-            }
-        }
-    }
-    
-    
-    /**
-     * Method remove
-     *
-     * @param    token               a  SlideToken
-     * @param    object              an ObjectNode
-     *
-     * @throws   ServiceAccessException
-     * @throws   ObjectNotFoundException
-     * @throws   ObjectHasChildrenException
-     * @throws   AccessDeniedException
-     * @throws   LinkedObjectNotFoundException
-     * @throws   ObjectLockedException
-     *
-     */
-    public void remove(SlideToken token, ObjectNode object)
-        throws ServiceAccessException, ObjectNotFoundException,
-        ObjectHasChildrenException, AccessDeniedException,
-        LinkedObjectNotFoundException, ObjectLockedException, VetoException {
-        
-        ObjectNode nodeToDelete = retrieve(token, object.getUri(), false);
-        Uri uri = namespace.getUri(token, nodeToDelete.getUri());
-        
-        // Fire event
-        if ( StructureEvent.REMOVE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.REMOVE, new StructureEvent(this, token, object, uri.toString()));
-
-        if (!object.getUri().equals("/")) {
-            Uri curUri = namespace.getUri(token, nodeToDelete.getUri());
-            Uri parentUri = curUri.getParentUri();
-            
-            ObjectNode parentNode = parentUri.getStore().retrieveObject(parentUri);
-            
-            securityHelper.checkCredentials(token, nodeToDelete, 
-                    namespaceConfig.getRemoveObjectAction());
-            securityHelper.checkCredentials(token, parentNode, 
-                    namespaceConfig.getUnbindMemberAction());
-            lockHelper.checkLock(token, nodeToDelete, 
-                    namespaceConfig.getRemoveObjectAction());
-            lockHelper.checkLock(token, parentNode, 
-                    namespaceConfig.getUnbindMemberAction());
-
-            parentNode.removeChild(nodeToDelete);
-            store(token, parentNode, true);
-            
-            if (Configuration.useBinding(curUri.getStore()) && nodeToDelete.numberOfParentBindings() > 0) {
-                store(token, nodeToDelete);
-            }
-            else {
-                Enumeration children = nodeToDelete.enumerateChildren();
-                if (children.hasMoreElements()) {
-                    throw new ObjectHasChildrenException(uri);
-                }
-                uri.getStore().removeObject(uri, nodeToDelete);
-            }
-        }
-    }
-    
-    
-    /**
-     * Modifies the collection identified by <b>collectionNode</b>, by adding a new binding
-     * from the specified segment to the resource identified by <b>sourceNode</b>.
-     *
-     * @param    token               a  SlideToken
-     * @param    collectionNode      an ObjectNode
-     * @param    segment             a  String
-     * @param    sourceNode          an ObjectNode
-     *
-     * @throws   ServiceAccessException
-     * @throws   ObjectNotFoundException
-     * @throws   AccessDeniedException
-     * @throws   LinkedObjectNotFoundException
-     * @throws   ObjectLockedException
-     *
-     */
-    public void addBinding(SlideToken token, ObjectNode collectionNode, String segment, ObjectNode sourceNode) throws ServiceAccessException, ObjectNotFoundException, AccessDeniedException, LinkedObjectNotFoundException, ObjectLockedException, CrossServerBindingException, VetoException {
-        if (Configuration.useBinding(namespace.getUri(token, collectionNode.getUri()).getStore())) {
-            collectionNode = retrieve(token, collectionNode.getUri(), false);
-            sourceNode = retrieve(token, sourceNode.getUri(), false);
-            Uri collectionUri = namespace.getUri(token, collectionNode.getUri());
-//            Uri sourceUri = namespace.getUri(token, sourceNode.getUri());
-            
-            // Fire event
-            if ( StructureEvent.ADD_BINDING.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.ADD_BINDING, new StructureEvent(this, token, sourceNode, collectionUri.toString()));
-
-//            if (collectionUri.getStore() != sourceUri.getStore()) {
-//                throw new CrossServerBindingException(collectionNode.getUri(), sourceNode.getUri());
-//            }
-            
-            lockHelper.checkLock
-                (token, collectionNode, namespaceConfig.getCreateObjectAction());
-            
-            ObjectNode oldChild = null;
-            if (collectionNode.hasBinding(segment)) {
-                oldChild = retrieve(token, collectionNode.getUri()+"/"+segment, false);
-                lockHelper.checkLock
-                    (token, oldChild, namespaceConfig.getCreateObjectAction());
-                collectionNode.removeChild(oldChild);
-                store( token, oldChild );
-            }
-            collectionNode.addBinding( segment, sourceNode );
-            
-            store( token, collectionNode, true );
-            store( token, sourceNode );
-        }
-    }
-    
-    
-    /**
-     * Modifies the collection identified by <b>collectionNode</b>, by removing the binding
-     * for the specified segment.
-     *
-     * @param    token               a  SlideToken
-     * @param    collectionNode      an ObjectNode
-     * @param    segment             a  String
-     *
-     * @throws   ServiceAccessException
-     * @throws   ObjectNotFoundException
-     * @throws   AccessDeniedException
-     * @throws   LinkedObjectNotFoundException
-     * @throws   ObjectLockedException
-     *
-     */
-    public void removeBinding(SlideToken token, ObjectNode collectionNode, String segment) throws ServiceAccessException, ObjectNotFoundException, AccessDeniedException, LinkedObjectNotFoundException, ObjectLockedException, VetoException {
-        if (Configuration.useBinding(namespace.getUri(token, collectionNode.getUri()).getStore())) {
-            collectionNode = retrieve(token, collectionNode.getUri(), false);
-            ObjectNode childNode = retrieve(token, collectionNode.getUri()+"/"+segment, false);
-            
-            // Fire event
-            if ( StructureEvent.REMOVE_BINDING.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.REMOVE_BINDING, new StructureEvent(this, token, childNode, collectionNode.getUri()));
-
-            lockHelper.checkLock
-                (token, collectionNode, namespaceConfig.getCreateObjectAction());
-            lockHelper.checkLock
-                (token, childNode, namespaceConfig.getCreateObjectAction());
-            
-            collectionNode.removeChild( childNode );
-            
-            store( token, childNode );
-            store( token, collectionNode, true );
-        }
-    }
-    
-    
-    /**
-     * Return all parents of this object node. If pathOnly=true, only parents
-     * on the path of the specified ObjectNode are returned, all parents (binding!)
-     * otherwise. If storeOnly=true, only parents within the scope of the store
-     * in charge of the specified ObjectNode are returned, parents up to the root
-     * ObjectNode (uri="/") otherwise.
-     *
-     * @param    token               a  SlideToken
-     * @param    object              an ObjectNode
-     * @param    pathOnly            if true, only parents on the path of the specified
-     *                               ObjectNode are returned, all parents (binding!)
-     *                               otherwise
-     * @param    storeOnly           if true, only parents within the scope of the store
-     *                               in charge of the specified ObjectNode are returned,
-     *                               parents up to the root ObjectNode (uri="/") otherwise
-     * @param    includeSelf         if true, the ObjectNode specified by object is included,
-     *                               otherwise, it is excluded
-     *
-     * @return   a List of ObjectNode instances
-     *
-     * @throws   ServiceAccessException
-     * @throws   ObjectNotFoundException
-     * @throws   LinkedObjectNotFoundException
-     * @throws   AccessDeniedException
-     *
-     */
-    public List getParents(SlideToken token, ObjectNode object,
-            boolean pathOnly, boolean storeOnly, boolean includeSelf)
-            throws ServiceAccessException, ObjectNotFoundException,
-            LinkedObjectNotFoundException, AccessDeniedException, VetoException
-    {
-        List result = new ArrayList();
-
-        if (pathOnly) {
-            String[] uriTokens = object.getPath().tokens();
-            UriPath path = new UriPath("/");
-            Uri currentUri = namespace.getUri(token, path.toString());
-            Uri objectUri = namespace.getUri(token, object.getUri());
-            if (!storeOnly || currentUri.getStore() == objectUri.getStore()) {
-                result.add( retrieve(token, path.toString()) );
-            }
-            
-            for (int i = 0; i < uriTokens.length; i++) {
-                path = path.child( uriTokens[i] );
-                currentUri = namespace.getUri(token, path.toString());
-                if (i == uriTokens.length - 1 && !includeSelf) {
-                    break;
-                }
-                if (!storeOnly || currentUri.getStore() == objectUri.getStore()) {
-                    result.add( retrieve(token, path.toString()) );
-                }
-            }
-        }
-        else {
-            // TODO
-        }
-        
-        return result;
-    }
-}
 
+	// ----------------------------------------------------------- Constructors
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param namespace
+	 *            the namespace associated with the helper object
+	 * @param namespaceConfig
+	 *            configuration of the namespace
+	 * @param securityHelper
+	 *            the associated security helper
+	 * @param lockHelper
+	 *            the associated lock helper
+	 */
+	public StructureImpl(Namespace namespace, NamespaceConfig namespaceConfig,
+			Security securityHelper, Lock lockHelper) {
+		this.namespace = namespace;
+		this.namespaceConfig = namespaceConfig;
+		this.securityHelper = securityHelper;
+		this.lockHelper = lockHelper;
+	}
+
+	// ----------------------------------------------------- Instance Variables
+
+	/**
+	 * Namespace.
+	 */
+	private Namespace namespace;
+
+	/**
+	 * Namespace configuration.
+	 */
+	private NamespaceConfig namespaceConfig;
+
+	/**
+	 * Security helper.
+	 */
+	private Security securityHelper;
+
+	/**
+	 * Lock helper.
+	 */
+	private Lock lockHelper;
+
+	// ------------------------------------------------------ Structure Methods
+
+	public String generateUniqueUri(SlideToken token, String parentUri)
+			throws ServiceAccessException {
+		String sequenceName = parentUri.replace('/', '-');
+
+		Uri uri = namespace.getUri(token, parentUri);
+		Store store = uri.getStore();
+		if (!store.isSequenceSupported()) {
+			return null;
+		} else {
+			if (!store.sequenceExists(sequenceName)) {
+				store.createSequence(sequenceName);
+			}
+			long next = store.nextSequenceValue(sequenceName);
+			String uniqueUri = parentUri + "/" + next;
+			return uniqueUri;
+		}
+	}
+
+	public Enumeration getChildren(SlideToken token, ObjectNode object)
+			throws ServiceAccessException, ObjectNotFoundException,
+			LinkedObjectNotFoundException, VetoException {
+		Enumeration childrenUri = object.enumerateChildren();
+		Vector result = new Vector();
+		while (childrenUri.hasMoreElements()) {
+			String childUri = (String) childrenUri.nextElement();
+			try {
+				ObjectNode child = retrieve(token, childUri, false);
+				result.addElement(child);
+			} catch (AccessDeniedException e) {
+			}
+		}
+		return result.elements();
+	}
+
+	public ObjectNode getParent(SlideToken token, ObjectNode object)
+			throws ServiceAccessException, ObjectNotFoundException,
+			LinkedObjectNotFoundException, AccessDeniedException, VetoException {
+		String objectUriStr = object.getUri();
+		Uri parentUri = namespace.getUri(token, objectUriStr).getParentUri();
+		if (parentUri == null) {
+			return null;
+		}
+		String parentUriStr = parentUri.toString();
+		ObjectNode parent = retrieve(token, parentUriStr);
+		return parent;
+	}
+
+	public ObjectNode retrieve(SlideToken token, String strUri)
+			throws ServiceAccessException, ObjectNotFoundException,
+			LinkedObjectNotFoundException, AccessDeniedException, VetoException {
+		return retrieve(token, strUri, true);
+	}
+
+	public ObjectNode retrieve(SlideToken token, String strUri,
+			boolean translateLastUriElement) throws ServiceAccessException,
+			ObjectNotFoundException, LinkedObjectNotFoundException,
+			AccessDeniedException, VetoException {
+		Uri uri = namespace.getUri(token, strUri);
+		/*
+		 * if (strUri.startsWith("UURI:")) { String uuri = strUri.substring(6);
+		 * uri = ResourceId.create(uri, uuri); } else { uri =
+		 * namespace.getUri(token, strUri); }
+		 */
+		ObjectNode result = null;
+
+		// Fire event
+		if (StructureEvent.RETRIEVE.isEnabled())
+			EventDispatcher.getInstance().fireVetoableEvent(
+					StructureEvent.RETRIEVE,
+					new StructureEvent(this, token, namespace, strUri));
+
+		// First of all, we try to load the object directly from the given Uri.
+		try {
+			result = uri.getStore().retrieveObject(uri);
+			securityHelper.checkCredentials(token, result, namespaceConfig
+					.getReadObjectAction());
+			if ((translateLastUriElement) && (result instanceof LinkNode)) {
+				LinkNode link = (LinkNode) result;
+				Uri linkedUri = namespace.getUri(token, link.getLinkedUri());
+				result = linkedUri.getStore().retrieveObject(linkedUri);
+				securityHelper.checkCredentials(token, result, namespaceConfig
+						.getReadObjectAction());
+			}
+		} catch (ObjectNotFoundException e) {
+		}
+
+		// If the attempt to load the uri failed, it means there is at least
+		// one link in the uri (or that the uri doe'sn't have any associated
+		// object).
+		if (result == null) {
+
+			String resolvedUri = uri.toString();
+
+			// 1 - Tokemization of the Uri
+			UriTokenizer uriTokenizer = new UriTokenizer(token, uri
+					.getNamespace(), resolvedUri);
+
+			// 2 - For each element of the Uri
+			Uri courUri = null;
+			ObjectNode courObject = null;
+			while (uriTokenizer.hasMoreElements()) {
+
+				// 3 - Load object's class from the uri. If the object
+				// does not exist, a DataException is thrown.
+				courUri = uriTokenizer.nextUri();
+				courObject = courUri.getStore().retrieveObject(courUri);
+
+				// We check to see if the credentials gives access to
+				// the current object
+				if (Domain.getParameter("ancestors-read-permissions-required",
+						"true").equals("true")) {
+					securityHelper.checkCredentials(token, courObject,
+							namespaceConfig.getReadObjectAction());
+				}
+
+				// 4 - Test if object is a link, ie if it is an instance
+				// of LinkNode or one of its subclasses
+				if (((translateLastUriElement) && (courObject instanceof LinkNode))
+						|| ((!translateLastUriElement)
+								&& (uriTokenizer.hasMoreElements()) && (courObject instanceof LinkNode))) {
+
+					// 5 - If the object is a link, we get the uri of
+					// the linked object
+					// Note : courUri still IS the Uri of the link, and so,
+					// in a way courUri is the parent of linkedUri.
+					Uri linkedUri = namespace.getUri(token,
+							((LinkNode) courObject).getLinkedUri());
+
+					// 6 - We replace the courUri scope in the original uri
+					String courStrUri = courUri.toString();
+					resolvedUri = linkedUri.toString()
+							+ resolvedUri.substring(courStrUri.length());
+
+					// 7 - We tokenize again the uri
+					uriTokenizer = new UriTokenizer(token, uri.getNamespace(),
+							resolvedUri);
+
+					// 8 - We parse it till we get back to the point
+					// where we stopped
+					boolean isUriFound = false;
+					while ((!isUriFound) && (uriTokenizer.hasMoreElements())) {
+						if (linkedUri.equals(uriTokenizer.nextUri())) {
+							isUriFound = true;
+						}
+					}
+					if (!isUriFound) {
+						throw new LinkedObjectNotFoundException(courUri,
+								resolvedUri);
+					}
+
+				}
+
+				// 9 - We continue to go down in the Uri tree
+			}
+
+			// 10 - We return the last object which has been found
+
+			result = courObject;
+		}
+
+		return result;
+
+	}
+
+	public void create(SlideToken token, ObjectNode object, String strUri)
+			throws ServiceAccessException, ObjectAlreadyExistsException,
+			ObjectNotFoundException, LinkedObjectNotFoundException,
+			AccessDeniedException, ObjectLockedException, VetoException {
+
+		// Fire event
+		if (StructureEvent.CREATE.isEnabled())
+			EventDispatcher.getInstance().fireVetoableEvent(
+					StructureEvent.CREATE,
+					new StructureEvent(this, token, namespace, strUri));
+
+		// Checking roles
+		Enumeration roles = securityHelper.getRoles(object);
+		while (roles.hasMoreElements()) {
+			if (!securityHelper.hasRole(token, (String) roles.nextElement())) {
+				// Allow only the namespace admin to create roles
+				// he doesn't have
+				Uri rootUri = namespace.getUri(token, "/");
+				ObjectNode rootObject = rootUri.getStore().retrieveObject(
+						rootUri);
+				securityHelper.checkCredentials(token, rootObject,
+						namespaceConfig.getGrantPermissionAction());
+				break;
+			}
+		}
+
+		String resolvedUri = strUri;
+
+		// 1 - Tokenization of the Uri
+		UriTokenizer uriTokenizer = new UriTokenizer(token, namespace,
+				resolvedUri);
+
+		// 2 - For each element of the Uri
+		Uri courUri = null;
+		ObjectNode courObject = null;
+		ObjectNode parentObject = null;
+
+		boolean alreadyExists = false;
+
+		while (uriTokenizer.hasMoreElements()) {
+
+			parentObject = courObject;
+
+			// 3 - Load object's class from the uri. If the object does
+			// not exist, a DataException is thrown.
+			courUri = uriTokenizer.nextUri();
+			try {
+				courObject = courUri.getStore().retrieveObject(courUri);
+				if (Domain.getParameter("ancestors-read-permissions-required",
+						"true").equals("true")) {
+					securityHelper.checkCredentials(token, courObject,
+							namespaceConfig.getReadObjectAction());
+				}
+				if (!uriTokenizer.hasMoreElements()) {
+					// The object already exists
+					alreadyExists = true;
+				}
+			} catch (ObjectNotFoundException e) {
+				// Load failed, probably because object was not found
+				// We try to create a new one.
+				// We have to test if the uri is the last in the list,
+				// we must create the requested element.
+				// By default, we create a SubjectNode.
+				ObjectNode newObject = null;
+				if (uriTokenizer.hasMoreElements()) {
+					throw new ObjectNotFoundException(courUri);
+				} else {
+					newObject = object;
+				}
+				if (parentObject != null) {
+
+					securityHelper.checkCredentials(token, courObject,
+							namespaceConfig.getBindMemberAction());
+
+					// Now creating the new object
+					newObject.setUri(courUri.toString());
+					courUri.getStore().createObject(courUri, newObject);
+
+					// re-read to obtain UURI
+					// newObject = courUri.getStore().retrieveObject(courUri);
+
+					// re-read the parent taking the forceEnlistment flag into
+					// account
+					Uri parentUri = namespace.getUri(token, parentObject
+							.getUri());
+					parentObject = parentUri.getStore().retrieveObject(
+							parentUri);
+					// Add the newly created object to its parent's
+					// children list
+					ObjectNode oldChild = null;
+					// we can check the parentUri, it's in the same store as
+					// newObject
+					if (Configuration.useBinding(parentUri.getStore())) {
+						String bindingName = newObject.getPath().lastSegment();
+						if (parentObject.hasBinding(bindingName)) {
+							oldChild = retrieve(token, parentObject.getUri()
+									+ "/" + bindingName, false);
+							parentObject.removeChild(oldChild);
+							store(token, oldChild);
+						}
+					}
+					lockHelper.checkLock(token, parentObject, namespaceConfig
+							.getCreateObjectAction());
+					parentObject.addChild(newObject);
+					// namespace.getUri(token, parentObject.getUri())
+					// .getDataSource().storeObject(parentObject, false);
+					store(token, parentObject, true);
+					store(token, newObject);
+
+				} else {
+					throw new ObjectNotFoundException(courUri);
+				}
+				courObject = newObject;
+			}
+
+			// 4 - Test if object is a link, ie if it is an instance of
+			// LinkNode or one of its subclasses
+			if ((uriTokenizer.hasMoreElements())
+					&& (courObject instanceof LinkNode)) {
+
+				// 5 - If the object is a link, we get the uri of the
+				// linked object
+				// Note : courUri still IS the Uri of the link, and so,
+				// in a way courUri is the parent of linkedUri.
+				Uri linkedUri = namespace.getUri(token, ((LinkNode) courObject)
+						.getLinkedUri());
+
+				// 6 - We replace the courUri scope in the original uri
+				String courStrUri = courUri.toString();
+				resolvedUri = linkedUri.toString()
+						+ resolvedUri.substring(courStrUri.length());
+
+				// 7 - We tokenize again the uri
+				uriTokenizer = new UriTokenizer(token, namespace, resolvedUri);
+
+				// 8 - We parse it till we get back to the point
+				// where we stopped
+				boolean isUriFound = false;
+				while ((!isUriFound) && (uriTokenizer.hasMoreElements())) {
+					if (linkedUri.equals(uriTokenizer.nextUri())) {
+						isUriFound = true;
+					}
+				}
+				if (!isUriFound) {
+					throw new LinkedObjectNotFoundException(courUri,
+							resolvedUri);
+				}
+
+			}
+
+			// 9 - We continue to go down in the Uri tree
+		}
+
+		if (alreadyExists) {
+			if (courUri.isStoreRoot()) {
+				// if the object already exists map it anyway into
+				// the node hierarchy, to prevent loose of nodes
+				// during start up
+				if (parentObject != null && !parentObject.hasChild(courObject)) {
+					parentObject.addChild(courObject);
+					store(token, parentObject, true);
+				}
+			}
+			throw new ObjectAlreadyExistsException(strUri);
+		}
+	}
+
+	public void createLink(SlideToken token, LinkNode link, String linkUri,
+			ObjectNode linkedObject) throws ServiceAccessException,
+			ObjectAlreadyExistsException, ObjectNotFoundException,
+			LinkedObjectNotFoundException, AccessDeniedException,
+			ObjectLockedException, VetoException {
+		link.setLinkedUri(linkedObject.getUri());
+
+		// Fire event
+		if (StructureEvent.CREATE.isEnabled())
+			EventDispatcher.getInstance().fireVetoableEvent(
+					StructureEvent.CREATE_LINK,
+					new StructureEvent(this, token, link, linkUri));
+
+		create(token, link, linkUri);
+	}
+
+	public void store(SlideToken token, ObjectNode object)
+			throws ServiceAccessException, ObjectNotFoundException,
+			AccessDeniedException, LinkedObjectNotFoundException, VetoException {
+
+		store(token, object, false);
+	}
+
+	protected void store(SlideToken token, ObjectNode object,
+			boolean setModificationDate) throws ServiceAccessException,
+			ObjectNotFoundException, AccessDeniedException,
+			LinkedObjectNotFoundException, VetoException {
+
+		// Fire event
+		if (StructureEvent.STORE.isEnabled())
+			EventDispatcher.getInstance().fireVetoableEvent(
+					StructureEvent.STORE,
+					new StructureEvent(this, token, namespace, object));
+
+		// Checking roles
+		Enumeration roles = securityHelper.getRoles(object);
+		while (roles.hasMoreElements()) {
+			if (!securityHelper.hasRole(token, (String) roles.nextElement())) {
+				// Allow only the namespace admin to create roles
+				// he doesn't have
+				Uri rootUri = namespace.getUri(token, "/");
+				ObjectNode rootObject = rootUri.getStore().retrieveObject(
+						rootUri);
+				securityHelper.checkCredentials(token, rootObject,
+						namespaceConfig.getGrantPermissionAction());
+				break;
+			}
+		}
+
+		// working on realObject, we will lose changes immediatly done before
+		// call of store
+		// i observerd this with some BIND testcases
+		// ObjectNode realObject = retrieve(token, object.getUri(), false);
+		securityHelper.checkCredentials(token, object, namespaceConfig
+				.getCreateObjectAction());
+		Uri uri = namespace.getUri(token, object.getUri());
+		Store store = uri.getStore();
+		store.storeObject(uri, object);
+
+		if (setModificationDate) {
+			try {
+				NodeRevisionDescriptor revisionDescriptor = store
+						.retrieveRevisionDescriptor(uri,
+								new NodeRevisionNumber());
+				revisionDescriptor.setModificationDate(new Date());
+				revisionDescriptor.setModificationUser(securityHelper
+						.getPrincipal(token).getPath().lastSegment());
+				store.storeRevisionDescriptor(uri, revisionDescriptor);
+			} catch (RevisionDescriptorNotFoundException e) {
+				// ignore silently
+			}
+		}
+	}
+
+	/**
+	 * Method remove
+	 * 
+	 * @param token
+	 *            a SlideToken
+	 * @param object
+	 *            an ObjectNode
+	 * 
+	 * @throws ServiceAccessException
+	 * @throws ObjectNotFoundException
+	 * @throws ObjectHasChildrenException
+	 * @throws AccessDeniedException
+	 * @throws LinkedObjectNotFoundException
+	 * @throws ObjectLockedException
+	 * 
+	 */
+	public void remove(SlideToken token, ObjectNode object)
+			throws ServiceAccessException, ObjectNotFoundException,
+			ObjectHasChildrenException, AccessDeniedException,
+			LinkedObjectNotFoundException, ObjectLockedException, VetoException {
+
+		ObjectNode nodeToDelete = retrieve(token, object.getUri(), false);
+		Uri uri = namespace.getUri(token, nodeToDelete.getUri());
+
+		// Fire event
+		if (StructureEvent.REMOVE.isEnabled())
+			EventDispatcher.getInstance().fireVetoableEvent(
+					StructureEvent.REMOVE,
+					new StructureEvent(this, token, object, uri.toString()));
+
+		if (!object.getUri().equals("/")) {
+			Uri curUri = namespace.getUri(token, nodeToDelete.getUri());
+			Uri parentUri = curUri.getParentUri();
+
+			ObjectNode parentNode = parentUri.getStore().retrieveObject(
+					parentUri);
+
+			securityHelper.checkCredentials(token, nodeToDelete,
+					namespaceConfig.getRemoveObjectAction());
+			securityHelper.checkCredentials(token, parentNode, namespaceConfig
+					.getUnbindMemberAction());
+			lockHelper.checkLock(token, nodeToDelete, namespaceConfig
+					.getRemoveObjectAction());
+			lockHelper.checkLock(token, parentNode, namespaceConfig
+					.getUnbindMemberAction());
+
+			parentNode.removeChild(nodeToDelete);
+			store(token, parentNode, true);
+
+			if (Configuration.useBinding(curUri.getStore())
+					&& nodeToDelete.numberOfParentBindings() > 0) {
+				store(token, nodeToDelete);
+			} else {
+				Enumeration children = nodeToDelete.enumerateChildren();
+				if (children.hasMoreElements()) {
+					throw new ObjectHasChildrenException(uri);
+				}
+				uri.getStore().removeObject(uri, nodeToDelete);
+			}
+		}
+	}
+
+	/**
+	 * Modifies the collection identified by <b>collectionNode</b>, by adding a
+	 * new binding from the specified segment to the resource identified by
+	 * <b>sourceNode</b>.
+	 * 
+	 * @param token
+	 *            a SlideToken
+	 * @param collectionNode
+	 *            an ObjectNode
+	 * @param segment
+	 *            a String
+	 * @param sourceNode
+	 *            an ObjectNode
+	 * 
+	 * @throws ServiceAccessException
+	 * @throws ObjectNotFoundException
+	 * @throws AccessDeniedException
+	 * @throws LinkedObjectNotFoundException
+	 * @throws ObjectLockedException
+	 * 
+	 */
+	public void addBinding(SlideToken token, ObjectNode collectionNode,
+			String segment, ObjectNode sourceNode)
+			throws ServiceAccessException, ObjectNotFoundException,
+			AccessDeniedException, LinkedObjectNotFoundException,
+			ObjectLockedException, CrossServerBindingException, VetoException {
+		if (Configuration.useBinding(namespace.getUri(token,
+				collectionNode.getUri()).getStore())) {
+			collectionNode = retrieve(token, collectionNode.getUri(), false);
+			sourceNode = retrieve(token, sourceNode.getUri(), false);
+			Uri collectionUri = namespace
+					.getUri(token, collectionNode.getUri());
+			// Uri sourceUri = namespace.getUri(token, sourceNode.getUri());
+
+			// Fire event
+			if (StructureEvent.ADD_BINDING.isEnabled())
+				EventDispatcher.getInstance().fireVetoableEvent(
+						StructureEvent.ADD_BINDING,
+						new StructureEvent(this, token, sourceNode,
+								collectionUri.toString()));
+
+			// if (collectionUri.getStore() != sourceUri.getStore()) {
+			// throw new CrossServerBindingException(collectionNode.getUri(),
+			// sourceNode.getUri());
+			// }
+
+			lockHelper.checkLock(token, collectionNode, namespaceConfig
+					.getCreateObjectAction());
+
+			ObjectNode oldChild = null;
+			if (collectionNode.hasBinding(segment)) {
+				oldChild = retrieve(token, collectionNode.getUri() + "/"
+						+ segment, false);
+				lockHelper.checkLock(token, oldChild, namespaceConfig
+						.getCreateObjectAction());
+				collectionNode.removeChild(oldChild);
+				store(token, oldChild);
+			}
+			collectionNode.addBinding(segment, sourceNode);
+
+			store(token, collectionNode, true);
+			store(token, sourceNode);
+		}
+	}
+
+	/**
+	 * Modifies the collection identified by <b>collectionNode</b>, by removing
+	 * the binding for the specified segment.
+	 * 
+	 * @param token
+	 *            a SlideToken
+	 * @param collectionNode
+	 *            an ObjectNode
+	 * @param segment
+	 *            a String
+	 * 
+	 * @throws ServiceAccessException
+	 * @throws ObjectNotFoundException
+	 * @throws AccessDeniedException
+	 * @throws LinkedObjectNotFoundException
+	 * @throws ObjectLockedException
+	 * 
+	 */
+	public void removeBinding(SlideToken token, ObjectNode collectionNode,
+			String segment) throws ServiceAccessException,
+			ObjectNotFoundException, AccessDeniedException,
+			LinkedObjectNotFoundException, ObjectLockedException, VetoException {
+		if (Configuration.useBinding(namespace.getUri(token,
+				collectionNode.getUri()).getStore())) {
+			collectionNode = retrieve(token, collectionNode.getUri(), false);
+			ObjectNode childNode = retrieve(token, collectionNode.getUri()
+					+ "/" + segment, false);
+
+			// Fire event
+			if (StructureEvent.REMOVE_BINDING.isEnabled())
+				EventDispatcher.getInstance().fireVetoableEvent(
+						StructureEvent.REMOVE_BINDING,
+						new StructureEvent(this, token, childNode,
+								collectionNode.getUri()));
+
+			lockHelper.checkLock(token, collectionNode, namespaceConfig
+					.getCreateObjectAction());
+			lockHelper.checkLock(token, childNode, namespaceConfig
+					.getCreateObjectAction());
+
+			collectionNode.removeChild(childNode);
+
+			store(token, childNode);
+			store(token, collectionNode, true);
+		}
+	}
+
+	/**
+	 * Return all parents of this object node. If pathOnly=true, only parents on
+	 * the path of the specified ObjectNode are returned, all parents (binding!)
+	 * otherwise. If storeOnly=true, only parents within the scope of the store
+	 * in charge of the specified ObjectNode are returned, parents up to the
+	 * root ObjectNode (uri="/") otherwise.
+	 * 
+	 * @param token
+	 *            a SlideToken
+	 * @param object
+	 *            an ObjectNode
+	 * @param pathOnly
+	 *            if true, only parents on the path of the specified ObjectNode
+	 *            are returned, all parents (binding!) otherwise
+	 * @param storeOnly
+	 *            if true, only parents within the scope of the store in charge
+	 *            of the specified ObjectNode are returned, parents up to the
+	 *            root ObjectNode (uri="/") otherwise
+	 * @param includeSelf
+	 *            if true, the ObjectNode specified by object is included,
+	 *            otherwise, it is excluded
+	 * 
+	 * @return a List of ObjectNode instances
+	 * 
+	 * @throws ServiceAccessException
+	 * @throws ObjectNotFoundException
+	 * @throws LinkedObjectNotFoundException
+	 * @throws AccessDeniedException
+	 * 
+	 */
+	public List getParents(SlideToken token, ObjectNode object,
+			boolean pathOnly, boolean storeOnly, boolean includeSelf)
+			throws ServiceAccessException, ObjectNotFoundException,
+			LinkedObjectNotFoundException, AccessDeniedException, VetoException {
+		List result = new ArrayList();
+
+		if (pathOnly) {
+			String[] uriTokens = object.getPath().tokens();
+			UriPath path = new UriPath("/");
+			Uri currentUri = namespace.getUri(token, path.toString());
+			Uri objectUri = namespace.getUri(token, object.getUri());
+			if (!storeOnly || currentUri.getStore() == objectUri.getStore()) {
+				result.add(retrieve(token, path.toString()));
+			}
+
+			for (int i = 0; i < uriTokens.length; i++) {
+				path = path.child(uriTokens[i]);
+				currentUri = namespace.getUri(token, path.toString());
+				if (i == uriTokens.length - 1 && !includeSelf) {
+					break;
+				}
+				if (!storeOnly || currentUri.getStore() == objectUri.getStore()) {
+					result.add(retrieve(token, path.toString()));
+				}
+			}
+		} else {
+			// TODO
+		}
+
+		return result;
+	}
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org