/*
 * $Header: /esup-portail/injac/applications/SlideServer/Packages/esup-serveur-WebDav-3/update/slide/add-ons/stores/uPortalStore/src/stores/org/apache/slide/common/ScopeTokenizer.java,v 1.1 2005/02/08 09:23:40 tbellemb Exp $
 * $Revision: 1.1 $
 * $Date: 2005/02/08 09:23:40 $
 *
 * ====================================================================
 *
 * 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.common;

import java.util.StringTokenizer;
import java.util.Vector;
import java.util.Enumeration;
import java.util.NoSuchElementException;

/**
 * Tokenizes a scope.
 * <p/>
 * This tokenizer derives from StringTokenizer and tokenizes a scope in sub scopes.
 * This object is used for Scope matching in the registry. The API of this object
 * is the same as the StringTokenizer API.
 * <p/>
 * Ex : the scope /foo/bar/bar.txt will be tokenized in the following tokens :
 * <li>/foo/bar/bar.txt
 * <li>/foo/bar
 * <li>/foo
 * <li>/
 *
 * @see StringTokenizer
 * @version $Revision: 1.1 $
 */
public final class ScopeTokenizer extends StringTokenizer {
    
    
    // ----------------------------------------------------------- Constructors
    
    
    /**
     * Constructor.
     *
     * @param uri Uri which needs to be tokenized in Scopes.
     */
    public ScopeTokenizer(SlideToken slideToken, Namespace namespace, String uri) {
        super(uri, "/");
        
        // We then build the scopes.
        scopes = new Vector();
        
        // Initializing namespace
        this.slideToken = slideToken;
        this.namespace = namespace;
        
        String courScope = new String();
        
        scopes.insertElementAt("/", 0);
        
        // We parse the token list and build the scope String objects.
        while(super.hasMoreTokens()) {
            courScope = courScope + "/" + super.nextToken();
            scopes.insertElementAt(courScope, 0);
        }
        
        pos = 0;
    }
    
    
    /**
     * Constructor.
     *
     * @param namespace
     * @param uri
     */
    public ScopeTokenizer(Namespace namespace, String uri) {
        this(null, namespace, uri);
    }
    
    
    /**
     * Constructor.
     *
     * @param namespace
     * @param scope
     */
    public ScopeTokenizer(Namespace namespace, Scope scope) {
        this(null, namespace, scope.toString());
    }
    
    
    // ----------------------------------------------------- Instance Variables
    
    
    /**
     * Tokens container.
     */
    Vector scopes;
    
    
    /**
     * Cursor position in the token container.
     */
    int pos;
    
    
    /**
     * Namespace.
     */
    Namespace namespace;
    SlideToken slideToken;
    
    
    // --------------------------------------------------------- Public Methods
    
    
    /**
     * Get the parent Uri of the top level scope.
     *
     * @return Uri Parent Uri
     */
    public Uri getParentUri() {
        if (scopes.size() <= 1) {
            return null;
        } else {
            return namespace.getUri(slideToken, (String) scopes.elementAt(1));
        }
    }
    
    
    /**
     * True if the ScopeTokenizer contains additional scopes.
     *
     * @return boolean
     */
    public boolean hasMoreElements() {
        return scopes.size() > pos;
    }
    
    
    /**
     * True if the ScopeTokenizer contains additional scopes.
     *
     * @return boolean
     */
    public boolean hasMoreTokens() {
        return hasMoreElements();
    }
    
    
    /**
     * Returns the next Scope as an Object.
     *
     * @return Object
     * @exception NoSuchElementException
     */
    public Object nextElement()
    throws NoSuchElementException {
    Object obj = null;
    try {
        if (!hasMoreElements()) {
        throw new NoSuchElementException();
        }
        obj = scopes.elementAt(pos);
        pos = pos + 1;
    } catch (ArrayIndexOutOfBoundsException e) {
        // Should NEVER happen.
        e.printStackTrace();
    }
    return obj;
    }
    
    
    /**
     * Returns the next Scope as a String object.
     *
     * @return String
     * @exception NoSuchElementException
     */
    public String nextToken()
    throws NoSuchElementException {
    return (String) nextElement();
    }
    
    
    /**
     * Returns the next Scope as a Scope object.
     *
     * @return Scope
     * @exception NoSuchElementException
     */
    public Scope nextScope()
    throws NoSuchElementException {
    return new Scope(nextToken());
    }
    
    
    /**
     * Returns the next Scope as a String object.
     *
     * @param delim
     * @exception NoSuchElementException
     */
    public String nextToken(String delim)
    throws NoSuchElementException {
    return nextToken();
    }
    
    
    /**
     * Returns the scopes.
     *
     * @return Enumeration
     */
    public Enumeration elements() {
    return scopes.elements();
    }
    
    
    // -------------------------------------------------------- Package Methods
    
    
    /**
     * Get the parsed uri.
     *
     * @return String Uri
     */
    String getUri() {
        if (scopes.size() < 1) {
            return null;
        } else {
            return (String) scopes.elementAt(0);
        }
    }
    
}
