/*
 * $Header: /home/cvspublic/jakarta-slide/src/share/org/apache/slide/search/SlideUri.java,v 1.13 2004/10/18 09:19:59 luetzkendorf Exp $
 * $Revision: 1.13 $
 * $Date: 2004/10/18 09:19:59 $
 *
 * ====================================================================
 *
 * 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.search;

/**
 * A SlideUri contains two parts the <em>context path</em> and the <em>slide uri</em>. 
 * 
 * <p>The context path is determined by the path of the webapp and the path 
 * to which the WebDavServlet is mapped. Samples: <code>/slide</code>, 
 * <code>/webapp/webdav</code> and <code>/</code>.
 * 
 * <p>The slide uri is an URI as represented by {@link org.apache.slide.common.Uri}.  
 * 
 *
 */
public class SlideUri {
    
    private String context;
    private String path;
    
    /**
     * Creates a SlideUri.
     * @param slideContextPath the Context path of the WebDAVServlet
     * @param requestUri the URI from an WebDAV(HTTP) request
     * 
     * @return the created SlideUri
     */
    public static SlideUri createWithRequestUri(String slideContextPath, String requestUri) {
       if (slideContextPath.length() <= 1) {
           // this.slideContextPath == "" or this.slideContextPath = "/"
           return new SlideUri("/", requestUri);
       } else {
           return new SlideUri(slideContextPath, 
                requestUri.substring(slideContextPath.length()));
       }
    }
    
    /**
     * Constructs a SlideUri. 
     * 
     * @param slideContextPath Context and ServletPath
     * @param slideUri uri
     */
    private SlideUri (String slideContextPath, String slideUri) {
        if (slideContextPath == null || slideUri == null) {
            throw new NullPointerException();
        }
        if (slideUri.length() == 0) {
            slideUri = "/";
        }
        if (!slideContextPath.startsWith("/")) {
            throw new IllegalArgumentException("slideContextPath must be absolute");
        }
        if (!slideUri.startsWith("/")) {
            throw new IllegalArgumentException("slideUri must be absolute");
        }
        this.context = slideContextPath;
        this.path = slideUri;

        // normalize
        if (this.context.endsWith("/") && this.context.length() > 1) {
            this.context = this.context.substring(0, this.context.length()-1);
        }
        if (this.path.endsWith("/") && this.context.length() > 1) {
            this.path = this.path.substring(0, this.path.length()-1);
        }
    }
    
    /**
     * Determines the slidePath from an webdav path.
     * 
     * @param   path relative or absolute webdav path 
     *
     * @throws  InvalidScopeException if the given path is absolute but not 
     *             in the scope given by the current slice context path. 
     *
     */
    public String getSlidePath (String davPath) throws InvalidScopeException {

        if (davPath.startsWith("/")) {
            // not a relative path
            if (!(davPath.startsWith(this.context))) {
                throw new InvalidScopeException (
                        "Uri \"" + davPath + "\" does not refer to " + context
                        + ". If an absolute scope is used, it must start with \""
                        + context + "\"");
            }
            if (davPath.length() == this.context.length()) {
                return "/";
            }
            if (this.context.length() > 1 && davPath.charAt(this.context.length()) != '/') {
                throw new InvalidScopeException (
                        "Uri \"" + davPath + "\" does not refer to " + context
                        + ". If an absolute scope is used, it must start with \""
                        + context + "\"");                
            }

            if (this.context.length() > 1) {
                return davPath.substring(this.context.length());
            } else {
                // context == "/"
                return davPath;
            }
        } else {
            // relative path
            if (path.length() > 1) {
                return this.path + "/" + davPath;
            } else {
                // this.path == "/"
                return this.path + davPath;
            }
        }
    }
    
    /**
     * Translates a slide uri to an absolute webdav path.
     * 
     * @param  slidePath slide internal uri
     */
    public String getContextPath (String slidePath) {
        if (slidePath.startsWith("/")) {
            if (context.length() > 1) {
                return context + slidePath;
            } else {
                // this.context == "/"
                return slidePath;
            }
        } else {
            if (context.length() > 1) {
                return context + "/" + slidePath;
            } else {
                // this.context == "/"
                return "/" + slidePath;
            }
        }
    }
}

