/*
 * $Header: /home/cvspublic/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/report/AbstractReport.java,v 1.9 2004/08/05 14:43:34 dflorey Exp $
 * $Revision: 1.9 $
 * $Date: 2004/08/05 14:43:34 $
 *
 * ====================================================================
 *
 * 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.report;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.RequestedProperties;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.SlideException;
import org.apache.slide.common.SlideToken;
import org.apache.slide.content.Content;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.content.NodeProperty.NamespaceCache;
import org.apache.slide.search.Search;
import org.apache.slide.security.Security;
import org.apache.slide.structure.Structure;
import org.apache.slide.webdav.WebdavServletConfig;
import org.apache.slide.webdav.util.AclConstants;
import org.apache.slide.webdav.util.DeltavConstants;
import org.apache.slide.webdav.util.PreconditionViolationException;
import org.apache.slide.webdav.util.PropertyRetriever;
import org.apache.slide.webdav.util.PropertyRetrieverImpl;
import org.apache.slide.webdav.util.WebdavStatus;
import org.apache.slide.webdav.util.WebdavUtils;
import org.jdom.Element;
import org.jdom.Namespace;


/**
 * Abstract report worker.
 *
 */
public abstract class AbstractReport implements DeltavConstants, AclConstants {
    
    protected static final Namespace DNSP = NamespaceCache.DEFAULT_NAMESPACE;
    protected static final String HTTP_VERSION = "HTTP/1.1";
    
    protected SlideToken slideToken;
    protected NamespaceAccessToken token;
    protected WebdavServletConfig config;
    protected String slideContextPath;
    protected Structure structure;
    protected Content content;
    protected Security security;
    protected Search search;
    protected PropertyRetriever retriever;
    
    /**
     * Constructor
     *
     * @param    slideToken          a  SlideToken
     * @param    token               a  NamespaceAccessToken
     * @param    resourcePath        a  String
     * @param    config              a  WebdavServletConfig
     * @param    servletPath         a String, the result of HttpRequest.getServletPath()
     * @param    contextPath         a  String , the result of HttpRequest.getContextPath()
     */
    public AbstractReport(SlideToken slideToken, NamespaceAccessToken token, WebdavServletConfig config, String slideContextPath) {
        this.slideToken = slideToken;
        this.token = token;
        this.config = config;
        this.slideContextPath = slideContextPath;
        this.structure = token.getStructureHelper();
        this.content = token.getContentHelper();
        this.security = token.getSecurityHelper();
        this.search = token.getSearchHelper();
        this.retriever = new PropertyRetrieverImpl(token, slideToken, config);
    }
    
    /**
     * Initialize report worker with specified report element
     *
     * @param    resourcePath        a  String
     * @param    reportElm           an Element
     *
     * @throws   PreconditionViolationException
     */
    public abstract void init(String resourcePath, Element reportElm) throws PreconditionViolationException;
    
    /**
     * Execute report and add results to given multistatus element
     *
     * @param    resourcePath        a  String
     * @param    multistatusElm      an Element
     * @param    depth               an int
     *
     * @throws   SlideException
     * @throws   IOException
     *
     */
    public abstract void execute(String resourcePath, Element multistatusElm, int depth) throws SlideException, IOException;
    
    /**
     * Method checkPreconditions
     * @param    resourcePath        a  String
     * @param    depth               an int
     * @throws   PreconditionViolationException
     * @throws   ServiceAccessException
     */
    public void checkPreconditions(String resourcePath, int depth) throws PreconditionViolationException, ServiceAccessException {
        // no preconditions
    }
    
    protected Element getResponseElement(SlideToken slideToken, String resourcePath, NodeRevisionNumber revisionNumber, RequestedProperties requestedProperties) {
        
        Element responseElm = new Element(E_RESPONSE, DNSP);
        Element hrefElm = new Element(E_HREF, DNSP);

        String absUri = WebdavUtils.getAbsolutePath (resourcePath, slideContextPath, config);
        hrefElm.setText (absUri);
        responseElm.addContent(hrefElm);
        
        try {
            List propstatList = retriever.getPropertiesOfObject(requestedProperties,
                                                                resourcePath,
                                                                revisionNumber,
                                                                slideContextPath,
                                                                true);
            Iterator iterator = propstatList.iterator();
            while (iterator.hasNext()) {
                responseElm.addContent((Element)iterator.next());
            }
        }
        catch (Exception e) {
            responseElm = getErrorResponse(resourcePath, WebdavUtils.getErrorCode(e), null);
        }
        return responseElm;
    }
    
    protected Element getErrorResponse(String resourcePath, int statusCode, String condition) {
        
        Element responseElm = new Element(E_RESPONSE, DNSP);
        
        Element hrefElm = new Element(E_HREF, DNSP);
        hrefElm.setText(WebdavUtils.getAbsolutePath (resourcePath, slideContextPath, config));
        responseElm.addContent(hrefElm);
        Element propStatElm = new Element(E_PROPSTAT, DNSP);
        responseElm.addContent(propStatElm);
        
        Element statusElm = new Element(E_STATUS, DNSP);
        statusElm.setText(HTTP_VERSION+" "+statusCode+" "+WebdavStatus.getStatusText(statusCode));
        propStatElm.addContent(statusElm);
        
        if (condition != null) {
            Element responseDescriptiont = new Element(E_RESPONSEDESCRIPTION, DNSP);
            Element errorElm = new Element(E_ERROR, DNSP);
            responseDescriptiont.addContent(errorElm);
            Element conditionElm = new Element(condition, DNSP);
            errorElm.addContent(conditionElm);
            propStatElm.addContent(responseDescriptiont);
        }
        return responseElm;
    }
}

