/*
 * $Header: /home/cvspublic/jakarta-slide/src/webdav/server/org/apache/slide/webdav/util/ResourceWithProvidedProperties.java,v 1.8 2005/01/10 18:13:25 luetzkendorf Exp $
 * $Revision: 1.8 $
 * $Date: 2005/01/10 18:13:25 $
 *
 * ====================================================================
 *
 * Copyright 1999 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.util;

import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.apache.slide.common.PropertyName;
import org.apache.slide.common.SlideException;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.search.PropertyProvider;
import org.apache.slide.search.RequestedResource;

/**
 * This is an adapter that creates a RequestedResource from a given
 * NodeRevisionDescriptor(s). Additionally to the properties provided
 * by the descriptor also the properties of the given PropertyProvider
 * are provided by this resource.
 *
 * @version $Revision: 1.8 $
 *
 */
public class ResourceWithProvidedProperties implements RequestedResource {
    
    /**
     * The NodeRevisionDescriptors this resource is based on.
     */
    protected NodeRevisionDescriptors revisionDescriptors = null;
    
    /**
     * The NodeRevisionDescriptor this resource is based on.
     */
    protected NodeRevisionDescriptor revisionDescriptor = null;
    
    /**
     * The PropertyProvider that provides the additional properties.
     */
    protected PropertyProvider propertyProvider = null;
    
    /**
     * Creates a ResourceWithProvidedProperties.
     *
     * @param      revisionDescriptors  the NodeRevisionDescriptors this resource
     *                                  is based on.
     * @param      revisionDescriptor   the NodeRevisionDescriptor this resource
     *                                  is based on.
     * @param      propertyProvider     the PropertyProvider that provides the
     *                                  additional properties (may be <code>null</code>).
     */
    public ResourceWithProvidedProperties(NodeRevisionDescriptors revisionDescriptors,
                                          NodeRevisionDescriptor revisionDescriptor,
                                          PropertyProvider propertyProvider) {
        
        this.revisionDescriptors = revisionDescriptors;
        this.revisionDescriptor = revisionDescriptor;
        this.propertyProvider = propertyProvider;
    }
    
    /**
     * Returns the URI of the resource.
     *
     * @return     the URI of the resource.
     */
    public String getUri() {
        return revisionDescriptors.getOriginalUri();
    }
    
    /**
     * Returns the property with the given <code>propertyName</code>.
     *
     * @param      propertyName       the PropertyName of the property.
     *
     * @return     the property with the given <code>npropertyNameame</code>.
     *
     * @throws     SlideException
     */
    public NodeProperty getProperty(PropertyName propertyName) throws SlideException {
        if ( (propertyProvider != null) &&
            propertyProvider.isSupportedProperty(getUri(), propertyName) ) {
            return propertyProvider.getProperty(getUri(), propertyName);
        } else {
            return revisionDescriptor.getProperty(propertyName);
        }
    }
    
    /**
     * Returns the property with the given <code>name</code> and
     * <code>namespace</code>.
     *
     * @param      name       the name of the property.
     * @param      namespace  the namespace URI of the property.
     *
     * @return     the property with the given <code>name</code> and
     *             <code>namespace</code>.
     *
     * @throws     SlideException
     */
    public NodeProperty getProperty(String name, String namespace) throws SlideException {
        
        if ( (propertyProvider != null) &&
            propertyProvider.isSupportedProperty(getUri(), name, namespace) ) {
            return propertyProvider.getProperty(getUri(), name, namespace);
        }
        else {
            return revisionDescriptor.getProperty(name, namespace);
        }
    }
    
    /**
     * Returns an Iterator of PropertyName of all properties.
     *
     * @return     an Iterator of PropertyName.
     *
     * @throws     SlideException
     */
    public Iterator getAllPropertiesNames() throws SlideException {
        
        Set propertyNamesList = new HashSet();
        Enumeration props = revisionDescriptor.enumerateProperties();
        NodeProperty property = null;
        if (props != null) {
            while (props.hasMoreElements()) {
                property = (NodeProperty)props.nextElement();
                propertyNamesList.add(property.getPropertyName());
            }
        }
        
        if  (propertyProvider != null) {
            Iterator iterator = propertyProvider.getSupportedPropertiesNames(getUri());
            while (iterator.hasNext()) {
                propertyNamesList.add(iterator.next());
            }
        }
        
        return propertyNamesList.iterator();
    }
    
    /**
     * Returns all properties as an Iterator of NodeProperty objects.
     *
     * @return     all properties as an Iterator of NodeProperty objects.
     *
     * @throws     SlideException
     */
    public Iterator getAllProperties() throws SlideException {
        
        Set propertyList = new HashSet();
        Enumeration props = revisionDescriptor.enumerateProperties();
        if (props != null) {
            while (props.hasMoreElements()) {
                propertyList.add(props.nextElement());
            }
        }
        
        if  (propertyProvider != null) {
        Iterator iterator = propertyProvider.getSupportedProperties(getUri());
        while (iterator.hasNext()) {
            propertyList.add(iterator.next());
            }
        }
        
        return propertyList.iterator();
    }
    
}

