package javax.wvcm;

/**
 * The location of a resource.
 * All methods in this interface are client-side only,
 * i.e. no communication with the server is required.
 */
public interface Location {
    
    public static final Location
        ALL = new GenericLocationImpl("all"),
        SELF = new GenericLocationImpl("self"),
        OWNER = new GenericLocationImpl("owner"),
        AUTHENTICATED = new GenericLocationImpl("authenticated"),
        UNAUTHENTICATED = new GenericLocationImpl("unauthenticated");
    
    /**
     * Return the string value for this Location.
     */
    public String string();
    
    /**
     * Return the Location of the child with the specified
     * binding name in the folder at this Location.
     * The string value of the Location of the child
     * is commonly created by appending a "/" and the name
     * of the child to the string value of this Location.
     */
    public Location child(String bindingName) throws WvcmException;
    
    /**
     * Return the Location of the parent folder of the resource
     * at this Location.  If this Location
     * is the root of the namespace, <code>null</code> is returned.
     * The string value of the Location of the parent folder
     * is commonly created by stripping off the last segment
     * beginning with a "/" character of this Location.
     */
    public Location parent();
    
    /**
     * Return a proxy for the activity at this Location.
     */
    public Activity activity();
    
    /**
     * Return a proxy for the folder at this Location.
     */
    public Folder folder();
    
    /**
     * Return a proxy for the resource at this Location.
     */
    public Resource resource();
    
    /**
     * Return a proxy for the controllable resource at this Location.
     */
    public ControllableResource controllableResource();
    
    /**
     * Return a proxy for the workspace at this location.
     */
    public Workspace workspace();
    
    /**
     * NOT YET STANDARD
     * Return a proxy for the principal at this location.
     */
    public Principal principal();
    
    /**
     * NOT YET STANDARD
     * Return a proxy for the group principal at this location.
     */
    public Principal.Group group();
    
    /**
     * NOT YET STANDARD
     * Return a proxy for the role principal at this location.
     */
    public Principal.Role role();
    
    /**
     * NOT YET STANDARD
     * Return a proxy for the privilege at this location.
     */
    public AccessControlElement.Privilege privilege();
    
    /**
     * NOT YET STANDARD
     * Return the last (or right-most) segment of the location path.
     */
    public String lastSegment();
    
    
    
    /**
     * Implementation of a generic Location.
     *
     * @author <a href="mailto:peter.nevermann@softwareag.com">Peter Nevermann</a>
     * @version $Revision: 1.8 $
     */
    
    public class GenericLocationImpl implements Location {
        
        private String string;
        
        /**
         * Private Constructor
         *
         * @param    string              a  String
         */
        private GenericLocationImpl(String string) {
            this.string = string;
        }
        
        /**
         * Return a proxy for the resource at this Location.
         */
        public Resource resource() {
            throw new UnsupportedOperationException("Not supported for generic locations");
        }
        
        /**
         * Return the Location of the child with the specified
         * binding name in the folder at this Location.
         * The string value of the Location of the child
         * is commonly created by appending a "/" and the name
         * of the child to the string value of this Location.
         */
        public Location child(String bindingName) throws WvcmException {
            throw new UnsupportedOperationException("Not supported for generic locations");
        }
        
        /**
         * Return a proxy for the activity at this Location.
         */
        public Activity activity() {
            throw new UnsupportedOperationException("Not supported for generic locations");
        }
        
        /**
         * Return a proxy for the controllable resource at this Location.
         */
        public ControllableResource controllableResource() {
            throw new UnsupportedOperationException("Not supported for generic locations");
        }
        
        /**
         * Return the Location of the parent folder of the resource
         * at this Location.  If this Location
         * is the root of the namespace, <code>null</code> is returned.
         * The string value of the Location of the parent folder
         * is commonly created by stripping off the last segment
         * beginning with a "/" character of this Location.
         */
        public Location parent() {
            throw new UnsupportedOperationException("Not supported for generic locations");
        }
        
        /**
         * Return a proxy for the folder at this Location.
         */
        public Folder folder() {
            throw new UnsupportedOperationException("Not supported for generic locations");
        }
        
        /**
         * Return a proxy for the workspace at this location.
         */
        public Workspace workspace() {
            throw new UnsupportedOperationException("Not supported for generic locations");
        }
        
        /**
         * NOT YET STANDARD
         * Return the last (or right-most) segment of the location path.
         */
        public String lastSegment() {
            return string;
        }
        
        /**
         * NOT YET STANDARD
         * Return a proxy for the principal at this location.
         */
        public Principal principal() {
            if (this == ALL) {
                return Principal.ALL;
            }
            else if (this == SELF) {
                return Principal.SELF;
            }
            else if (this == OWNER) {
                return Principal.OWNER;
            }
            else if (this == AUTHENTICATED) {
                return Principal.AUTHENTICATED;
            }
            else if (this == UNAUTHENTICATED) {
                return Principal.UNAUTHENTICATED;
            }
            else {
                throw new IllegalStateException("Unknown generic location "+this);
            }
        }
        
        /**
         * NOT YET STANDARD
         * Return a proxy for the group principal at this location.
         */
        public javax.wvcm.Principal.Group group() {
            throw new UnsupportedOperationException("Not supported for generic locations");
        }
        
        /**
         * NOT YET STANDARD
         * Return a proxy for the role principal at this location.
         */
        public javax.wvcm.Principal.Role role() {
            throw new UnsupportedOperationException("Not supported for generic locations");
        }
        
        /**
         * NOT YET STANDARD
         * Return a proxy for the privilege at this location.
         */
        public javax.wvcm.AccessControlElement.Privilege privilege() {
            if (this == ALL) {
                return AccessControlElement.Privilege.ALL;
            }
            else {
                throw new IllegalStateException("Unknown generic location "+this);
            }
        }
        
        /**
         * Return the string value for this Location.
         */
        public String string() {
            return string;
        }
    }
}
