/*
 * $Header: /home/cvspublic/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MethodUtil.java,v 1.5 2004/07/28 09:32:17 ib Exp $
 * $Revision: 1.5 $
 * $Date: 2004/07/28 09:32:17 $
 *
 * ====================================================================
 *
 * 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.webdav.method;

import java.util.List;

import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.SlideException;
import org.apache.slide.content.RevisionNotFoundException;
import org.apache.slide.content.NodeProperty.NamespaceCache;
import org.apache.slide.lock.ObjectLockedException;
import org.apache.slide.macro.ConflictException;
import org.apache.slide.macro.ForbiddenException;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.structure.LinkedObjectNotFoundException;
import org.apache.slide.structure.ObjectAlreadyExistsException;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.webdav.util.PreconditionViolationException;
import org.apache.slide.webdav.util.ViolatedPrecondition;
import org.apache.slide.webdav.util.WebdavConstants;
import org.jdom.Element;
import org.jdom.JDOMException;

/**
 * Static util methods.
 *
 */
public abstract class MethodUtil {
    /**
     * Get return status based on exception type.
     */
    public static String getErrorMessage(Throwable ex) {
        if ( !(ex instanceof SlideException) ) {
            return "";
        } else {
            return getErrorMessage((SlideException)ex);
        }
    }

    /**
     * Get the return status message info on exception type.
     */
    public static String getErrorMessage(SlideException ex) {
        try {
            throw ex;
        } catch(ObjectNotFoundException e) {
            return e.getObjectUri();
        } catch(ConflictException e) {
            return e.getObjectUri();
        } catch(ForbiddenException e) {
            return e.getObjectUri();
        } catch(AccessDeniedException e) {
            return e.getObjectUri();
        } catch(ObjectAlreadyExistsException e) {
            return e.getObjectUri();
        } catch(ServiceAccessException e) {
            return getErrorMessage((ServiceAccessException)e);
        } catch(LinkedObjectNotFoundException e) {
            return e.getTargetUri();
        } catch(RevisionNotFoundException e) {
            return e.getObjectUri();
        } catch(ObjectLockedException e) {
            return e.getObjectUri();
        } catch(PreconditionViolationException e) {
            return e.getObjectUri();
        } catch(SlideException e) {
            return e.getMessage();
        }
    }




    /**
     * Get return status based on exception type.
     */
    public static String getErrorMessage(ServiceAccessException ex) {
        Throwable cause = ex.getCauseException();
        if (cause == null || !(cause instanceof SlideException) )  {
            return "";  // this is the default}
        } else  {
            return getErrorMessage((SlideException)cause);
        }
    }

    //--

    /**
     * Generate &lt;error&gt; for the given precondition violation.
     *
     * @param     violatedPrecondition  the ViolatedPrecondition that describes
     *                                  the violated precondition.
     *
     * @return the &lt;error&gt; for the given precondition violation.
     */
    public static Element getPreconditionViolationError(ViolatedPrecondition violatedPrecondition) {
        return getPreconditionViolationError(violatedPrecondition,
                                             NamespaceCache.DEFAULT_NAMESPACE);
    }

    /**
     * Generate &lt;error&gt; for the given precondition violation.
     *
     * @param     violatedPrecondition  the ViolatedPrecondition that describes
     *                                  the violated precondition.
     *
     * @return the &lt;error&gt; for the given precondition violation.
     */
    public static Element getPreconditionViolationError(ViolatedPrecondition violatedPrecondition, org.jdom.Namespace namespace) {

        Element error = new Element(WebdavConstants.E_ERROR,
                                    namespace);
        Element violatedPreconditionElement = new Element(violatedPrecondition.getPrecondition(),
                                                          namespace);
        error.addContent(violatedPreconditionElement);
        return error;
    }


    /**
     * Generate &lt;responsedescription&gt; for the given precondition violation.
     *
     * @param pve the ProconditionViolationException that describes the violated
     *            precondition.
     *
     * @return the &lt;responsedescription&gt; for the given precondition violation.
     */
    public static Element getPreconditionViolationResponseDescription(PreconditionViolationException pve) {
        Element responseDescription = new Element(WebdavConstants.E_RESPONSEDESCRIPTION, NamespaceCache.DEFAULT_NAMESPACE);
        responseDescription.addContent(MethodUtil.getPreconditionViolationError(pve.getViolatedPrecondition()));
        return responseDescription;
    }

    //--


    /**
     * Get return status based on exception type.
     */
    public static String getURI(Throwable ex) {
        if ( !(ex instanceof SlideException) ) {
            return "";
        } else {
            return getURI((SlideException)ex);
        }
    }


    /**
     * Get the URI contained in the exception, if available.
     */
    public static String getURI(SlideException ex) {
        try {
            throw ex;
        } catch(ObjectNotFoundException e) {
            return e.getObjectUri();
        } catch(ConflictException e) {
            return e.getObjectUri();
        } catch(ForbiddenException e) {
            return e.getObjectUri();
        } catch(AccessDeniedException e) {
            return e.getObjectUri();
        } catch(ObjectAlreadyExistsException e) {
            return e.getObjectUri();
        } catch(ServiceAccessException e) {
            return getURI((ServiceAccessException)ex);
        } catch(LinkedObjectNotFoundException e) {
            return e.getTargetUri();
        } catch(RevisionNotFoundException e) {
            return e.getObjectUri();
        } catch(ObjectLockedException e) {
            return e.getObjectUri();
        } catch(SlideException e) {
            return "";
        }
    }

    /**
     * Get return status based on exception type.
     */
    private static String getURI(ServiceAccessException ex) {
        Throwable cause = ex.getCauseException();
        if (cause == null || !(cause instanceof SlideException) )  {
            return "";  // this is the default}
        } else  {
            return getURI((SlideException)cause);
        }
    }

    //--

    // TODO: find other places that should use this method
    public static boolean isValidSegment(String segment) {
        // TODO: more checks?
        return segment.indexOf('/') == -1;
    }


    // TODO: find other places that should use this method
    public static String getChildUrl(List children, String elementName) throws JDOMException {
        // TODO: decode URL?
        return getChildText(children, elementName);
    }

    /**
     * Precondition: ofs < children.size(), children.get(ofs) instanceof Element
     *
     * @return never null
     */
    public static String getChildText(List children, String elementName) throws JDOMException {
        // We cannot access elements with their index because there might additional
        // content elements not mentioned in the DTD

        Element child;
        int i;
        int max;
        Element found;

        found = null;
        max = children.size();
        for (i = 0; i < max; i++) {
            child = (Element) children.get(i);
            if (child.getName().equals(elementName)) {
                if (found != null) {
                    throw new JDOMException("multiple child elements '" + elementName + "' found.");
                }
                found = child;
            }
        }
        if (found == null) {
            throw new JDOMException("child element '" + elementName + "' not found.");
        }
        return found.getText();
    }
}


