/*
 * $Header: /home/cvspublic/jakarta-slide/src/share/org/apache/slide/structure/Structure.java,v 1.18 2004/07/28 09:34:35 ib Exp $
 * $Revision: 1.18 $
 * $Date: 2004/07/28 09:34:35 $
 *
 * ====================================================================
 *
 * Copyright 1999-2002 The Apache Software Foundation 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */ 

package org.apache.slide.structure;

import java.util.Enumeration;
import java.util.List;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.SlideToken;
import org.apache.slide.lock.ObjectLockedException;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.event.VetoException;

/**
 * Structure helper.
 * Provides methods to manage and navigate the hierarchy of nodes in a 
 * namespace.
 * 
 * @version $Revision: 1.18 $
 */
public interface Structure {
    
    
    // ------------------------------------------------------ Interface Methods
    
    /**
     * Generates an URI that is guranteed to be unqiue globally. 
     * If this is not possible <code>null</code> will be returned. 
     * 
     * @param token the slide token
     * @param parentUri the parent of the unique URI that shall be created 
     * 
     * @return a globally unique URI or <code>null</code> if not possible
     * 
     * @exception ServiceAccessException low level service access exception
     */
    String generateUniqueUri(SlideToken token, String parentUri) throws ServiceAccessException;
    
    /**
     * Returns the children of a node.
     * 
     * @param token the slide token
     * @param object the node
     * 
     * @return Enumeration of ObjectNode objects
     * 
     * @exception ServiceAccessException low level service access exception
     * @exception ObjectNotFoundException one of the children specified 
     *            by the object was not found
     * @exception LinkedObjectNotFoundException cannot happen
     *
     * @see org.apache.slide.structure.ObjectNode#enumerateChildren()
     */
    Enumeration getChildren(SlideToken token, ObjectNode object) 
        throws ServiceAccessException, ObjectNotFoundException, 
        LinkedObjectNotFoundException, VetoException;
    
    
    /**
     * Returns the parent of a node.
     * 
     * @param token the slide token
     * @param object the node
     * 
     * @return the node's parent, or <code>null</code> if the object specified 
     *         is the root node of the namespace
     * 
     * @exception ServiceAccessException low level service access exception
     * @exception ObjectNotFoundException the parent object specified 
     *            by the object was not found
     * @exception LinkedObjectNotFoundException cannot happen (a link 
     *            cannot have children)
     * @exception AccessDeniedException credentials token does not 
     *            have permission to perform the action
     *
     * @see org.apache.slide.structure.ObjectNode#enumerateChildren()
     */
    ObjectNode getParent(SlideToken token, ObjectNode object) 
        throws ServiceAccessException, ObjectNotFoundException, 
        LinkedObjectNotFoundException, AccessDeniedException, VetoException;
    
    /**
     * 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
     *
     */
    List getParents(SlideToken token, ObjectNode object, boolean pathOnly, boolean storeOnly, boolean includeSelf)
        throws ServiceAccessException, ObjectNotFoundException,
        LinkedObjectNotFoundException, AccessDeniedException, VetoException;
    
    /**
     * Retrieves a node by URI, following any links.
     * 
     * @param token the slide token
     * @param strUri the URI of the object to retrieve
     * 
     * @return the node specified by the URI or the node linked to by the node
     *         at the URI.
     * 
     * @exception ServiceAccessException low level service access exception
     * @exception ObjectNotFoundException if no node exists at the URI
     * @exception LinkedObjectNotFoundException A link object encountered 
     *            during URI resolution doesn't have a valid target
     * @exception AccessDeniedException credentials token does not have 
     *            permission to perform the action
     */
    ObjectNode retrieve(SlideToken token, String strUri) 
        throws ServiceAccessException, ObjectNotFoundException, 
        LinkedObjectNotFoundException, AccessDeniedException, VetoException;
    
    
    /**
     * Retrieves a node by URI.
     * 
     * @param token the slide token
     * @param strUri the URI of the object to retrieve
     * @param translateLastUriElement if set to true and the URI is 
     *        associated with a link, this method will return the target of 
     *        the link, otherwise the link itself is returned
     * 
     * @return the node specified by the URI, or the node linked to by the
     *         node at the URI, if <code>translateLastUriElement</code> is true
     * 
     * @exception ServiceAccessException low level service access exception
     * @exception ObjectNotFoundException if no node exists at the URI
     * @exception LinkedObjectNotFoundException A link object encountered 
     *            during URI resolution doesn't have a valid target
     * @exception AccessDeniedException credentials token does not have 
     *            permission to perform the action
     */
    ObjectNode retrieve(SlideToken token, String strUri, 
                        boolean translateLastUriElement) 
        throws ServiceAccessException, ObjectNotFoundException, 
        LinkedObjectNotFoundException, AccessDeniedException, VetoException;
    
    
    /**
     * Creates a new node in the namespace.
     * 
     * @param token the slide token
     * @param object the object that should be created
     * @param strUri location in the namespace where we the object should be 
     *        created
     * 
     * @exception ServiceAccessException low level service access exception
     * @exception ObjectAlreadyExistException an object already exists 
     *            at the specified URI
     * @exception ObjectNotFoundException Update of the parent object 
     *            failed because the parent object does no longer exist. 
     *            Should not happen, and indicates a critical error if it does
     * @exception LinkedObjectNotFoundException retrieval of a link target 
     *            failed during URI resolution
     * @exception AccessDeniedException credentials token does not have 
     *            permission to perform the action
     */
    void create(SlideToken token, ObjectNode object, String strUri)
        throws ServiceAccessException, ObjectAlreadyExistsException, 
        ObjectNotFoundException, LinkedObjectNotFoundException, 
        AccessDeniedException, ObjectLockedException, VetoException;
    
    
    /**
     * Creates a link to another node in the namespace.
     * 
     * @param token the slide token
     * @param link the link object that should be created
     * @param linkUri location in the namespace where the link object should 
     *        be created
     * @param linkedObject target object of the link
     * 
     * @exception ServiceAccessException Low level service access exception
     * @exception ObjectAlreadyExistException An object already exist 
     *            at the specified URI
     * @exception ObjectNotFoundException Update of the parent object 
     *            failed because the parent object does no longer exist. 
     *            Should not happen, and indicate a critical error if it does
     * @exception LinkedObjectNotFoundException Retrieval of a link target 
     *            failed during Uri resolution
     * @exception AccessDeniedException credentials token does not have 
     *            permission to perform the action
     */
    void createLink(SlideToken token, LinkNode link, String linkUri, 
                    ObjectNode linkedObject)
        throws ServiceAccessException, ObjectAlreadyExistsException, 
        ObjectNotFoundException, LinkedObjectNotFoundException, 
        AccessDeniedException, ObjectLockedException, VetoException;
    
    
    /**
     * Stores/updates an object.
     * 
     * @param token the slide token
     * @param object the object to update
     * 
     * @exception ServiceAccessException low level service access exception
     * @exception ObjectNotFoundException the update failed because one 
     *            object was not found during URI resolution
     * @exception LinkedObjectNotFoundException retrieval of a link target 
     *            failed during URI resolution
     * @exception AccessDeniedException credentials token does not have 
     *            permission to perform the action
     */
    void store(SlideToken token, ObjectNode object)
        throws ServiceAccessException, ObjectNotFoundException, 
        AccessDeniedException, LinkedObjectNotFoundException, VetoException;
    
    
    /**
     * Removes a node from the namespace.
     * 
     * @param token the slide token
     * @param object the node to remove
     * 
     * @exception ServiceAccessException low level service access exception
     * @exception ObjectNotFoundException the update failed because an 
     *            object was not found during URI resolution
     * @exception ObjectHasChildrenException removal failed because object 
     *            has children
     * @exception LinkedObjectNotFoundException retrieval of a link target 
     *            failed during URI resolution
     * @exception AccessDeniedException credentials token does not have 
     *            permission to perform the action
     */
    void remove(SlideToken token, ObjectNode object)
        throws ServiceAccessException, ObjectNotFoundException, 
        ObjectHasChildrenException, AccessDeniedException, 
        LinkedObjectNotFoundException, ObjectLockedException, VetoException;
    
    
    /**
     * 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
     */
    void addBinding( SlideToken token, ObjectNode collectionNode, String segment, ObjectNode sourceNode )
        throws ServiceAccessException, ObjectNotFoundException,
        AccessDeniedException, LinkedObjectNotFoundException, ObjectLockedException, CrossServerBindingException, VetoException;

    /**
     * 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
     *
     */
    void removeBinding( SlideToken token, ObjectNode collectionNode, String segment )
        throws ServiceAccessException, ObjectNotFoundException,
        AccessDeniedException, LinkedObjectNotFoundException, ObjectLockedException, VetoException;
}

