/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/wvcm/src/org/apache/wvcm/ProviderImpl.java,v 1.14 2004/07/30 06:52:25 ozeigermann Exp $
 * $Revision: 1.14 $
 * $Date: 2004/07/30 06:52:25 $
 *
 * ====================================================================
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Slide", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * [Additional notices, if required by prior licensing conditions]
 *
 */

package org.apache.wvcm;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import javax.wvcm.AccessControlElement;
import javax.wvcm.Folder;
import javax.wvcm.Location;
import javax.wvcm.Principal;
import javax.wvcm.PropertyNameList;
import javax.wvcm.PropertyNameList.PropertyName;
import javax.wvcm.Provider;
import javax.wvcm.ProviderFactory;
import javax.wvcm.ResourceList;
import javax.wvcm.WvcmException;
import org.apache.wvcm.store.Accessor;
import org.apache.wvcm.store.AccessorFactory;
import org.jdom.input.SAXBuilder;

/**
 * Implementation of Provider.
 *
 * @author <a href="mailto:peter.nevermann@softwareag.com">Peter Nevermann</a>
 * @version $Revision: 1.14 $
 */
public class ProviderImpl implements Provider {

    private static Map parsers = new HashMap();
    
    private ProviderFactory.Callback callback = null;
    private Hashtable initParms = new Hashtable();
    private Accessor serverAccessor = null;
    private Location serverPrivilegesLocation = null;
    
    /**
     * Constructor called by ProviderFactory
     * @param callback The object containing the getAuthentication
     * method that the Provider will call whenever it needs
     * to authenticate the current user.
     */
    public ProviderImpl( ProviderFactory.Callback callback ) {
        this.callback = callback;
    }
    
    /**
     * Constructor called by ProviderFactory
     * @param callback The object containing the getAuthentication
     * method that the Provider will call whenever it needs
     * to authenticate the current user.
     * @param h A hashtable containing provider-specific initialization values.
     */
    public ProviderImpl( ProviderFactory.Callback callback, Hashtable h ) {
        this.callback = callback;
        this.initParms = h;
        this.serverAccessor = AccessorFactory.createServerAccessor( this );
    }
    
    /**
     * Return a list of {@link Workspace} objects which
     * can be used as the argument of the
     * {@link Workspace#setServerState} routine
     * for more than one {@link Workspace}.
     * If this Provider does not allow multiple workspaces to
     * share the same ServerState, an empty List is returned.
     * @param wantedPropertyList The properties available in the returned proxies.
     */
    public List serverSharedWorkspaceList(PropertyNameList wantedPropertyList) throws WvcmException {
        // TODO: prio=l, effort=1.0, descr=(server shared ws list)
        return null;
    }
    
    /**
     * Return a {@link Location} whose string value is the specified String.
     * @throws WvcmException with ILLEGAL_LOCATION_SYNTAX
     * if the String is not a valid location.
     */
    public Location location(String string) throws WvcmException {
        return new LocationImpl( string, this );
    }
    
    /**
     * Return an empty {@link ResourceList}.
     */
    public ResourceList resourceList() {
        // TODO: prio=m, effort=1.0, descr=(resource list)
        return null;
    }
    
    /**
     * Return a list of {@link Folder} objects that identify folders
     * on the client that contain workspaces for this Provider.
     * If this Provider does not support workspaces on the
     * client, an empty List is returned.
     * @param wantedPropertyList The properties available in the returned proxies.
     */
    public List clientWorkspaceFolderList(PropertyNameList wantedPropertyList) throws WvcmException {
        // TODO: prio=l, effort=1.0, descr=(client ws folder list)
        return null;
    }
    
    /**
     * Return a list of {@link Folder} objects that identify folders
     * on the server that contain workspaces for this Provider.
     * If this Provider does not allow the client to create new
     * workspaces on the server, an empty List is returned.
     * @param wantedPropertyList The properties available in the returned proxies.
     */
    public List serverWorkspaceFolderList(PropertyNameList wantedPropertyList) throws WvcmException {
        return serverAccessor.serverWorkspaceFolderList( wantedPropertyList );
    }
    
    /**
     * NOT YET STANDARD
     * Get the list of generic Privilege instances
     *
     * @return   a List
     */
    public List getGenericPrivilegeList() {
        return Collections.unmodifiableList(
            Arrays.asList(new AccessControlElement.Privilege[]{AccessControlElement.Privilege.ALL})
        );
    }
    
    /**
     * NOT YET STANDARD
     * Get the list of generic Principal instances
     *
     * @return   a List
     */
    public List getGenericPrincipalList() {
        return Collections.unmodifiableList(
            Arrays.asList(new Principal[]{Principal.ALL, Principal.OWNER, Principal.AUTHENTICATED, Principal.UNAUTHENTICATED, Principal.SELF})
        );
    }
    
    // -------------------------------------------------------------------------
    // Non-interface methods
    // -------------------------------------------------------------------------
    
    /**
     * Get the specified init parameter.
     *
     * @param    name the parameter name
     *
     * @return   the value
     *
     */
    public Object initParameter( String name ) {
        return initParms.get( name );
    }
    
    /**
     * Get the callback of this provider.
     *
     * @return   the callback
     *
     */
    public ProviderFactory.Callback callback() {
        return callback;
    }
    
    public Location serverPrivilegesLocation() throws WvcmException {
        if (serverPrivilegesLocation != null) {
            return serverPrivilegesLocation;
        }
        
        Folder root = location((String)initParameter("context")).folder();
        PropertyNameList pfl = new PropertyNameList(
            new PropertyName[]{
                PropertyName.PRIVILEGE_FOLDER_LIST
            }
        );
        root = (Folder)root.doReadProperties(pfl);
        List l = root.getPrivilegeFolderList();
        if (l != null && l.size() > 0) {
            serverPrivilegesLocation = ((Folder)l.get(0)).location();
        }
        
        if (serverPrivilegesLocation == null) {
            serverPrivilegesLocation = location((String)initParameter("context")).child("actions");
        }
        return serverPrivilegesLocation;
    }
    
    public static SAXBuilder getSAXBuilder() {
        String key = Thread.currentThread().getName();
        SAXBuilder result = (SAXBuilder)parsers.get(key);
        if (result == null) {
            result = new SAXBuilder();
            parsers.put(key, result);
        }
        return result;
    }
}

