/*
 * $Header: /home/cvspublic/jakarta-slide/src/stores/org/apache/slide/search/basic/sample/BasicExpressionFactorySample.java,v 1.5 2004/07/28 09:34:22 ib Exp $
 * $Revision: 1.5 $
 * $Date: 2004/07/28 09:34:22 $
 *
 * ====================================================================
 *
 * 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.basic.sample;

import java.util.Collection;

import org.apache.slide.content.NodeProperty.NamespaceCache;
import org.apache.slide.search.BadQueryException;
import org.apache.slide.search.PropertyProvider;
import org.apache.slide.search.basic.IBasicExpression;
import org.apache.slide.search.basic.IBasicExpressionFactory;
import org.apache.slide.search.basic.IBasicQuery;
import org.jdom.Element;

/**
 * This factory creates executable BasicExpressions. An instance is created for
 * each SEARCH request.
 *
 * @version $Revision: 1.5 $
 */
public class BasicExpressionFactorySample implements IBasicExpressionFactory {
    
    
    private IBasicQuery query;
    protected PropertyProvider propertyProvider;
    
    /**
     * called for merge expressions (or, and).
     *
     * @param    mergeOperator       and, or
     * @param    namespace           the namespace of this expression
     * @param    expressionsToMerge  all expressions, that shall be merged
     *
     * @return   an IBasicExpression
     *
     * @throws   BadQueryException
     *
     */
    public IBasicExpression createMergeExpression (String mergeOperator,
                                                   String namespace,
                                                   Collection expressionsToMerge)
        throws BadQueryException
    {
        // you might want to check for the namespace
        BasicExpressionSample result = null;
        try {
            result = new BasicExpressionSample (mergeOperator, expressionsToMerge, this);
        }
        
        // if one of the expressions is for example a generic expression,
        // a ClassCastException is thrown, merge is not possible, so return null.
        catch (ClassCastException e) {
            System.out.println("one of the the expressions is not an ExpressionSample");
        }
        
        return result;
    }
    
    /**
     * Called by the expression compiler for each leave expression.
     *
     * @param    element             an Element discribing the expression
     *
     * @return   an IBasicExpression
     *
     * @throws   BadQueryException
     *
     */
    public IBasicExpression createExpression (Element element)
        throws BadQueryException
    {
        BasicExpressionSample result = null;
        
        if (element == null) {
            result = new BasicExpressionSample ("(no WHERE specified)", this);
        }
        else {
            String namespace = element.getNamespace().getURI();
            if (namespace.equals (NamespaceCache.DEFAULT_URI))
                result = createDAVExpression (element);
            
            // allow store specific extensions
            //  else if (namespace.equals (MyNamespace))
            //      result = createMyExpression (element);
        }
        
        return result;
    }
    
    
    /**
     * Called, when the expression is in the default (DAV:) namespace.
     *
     *
     * @param    e                   an Element
     *
     * @return   a BasicExpressionTemplate
     *
     */
    private BasicExpressionSample createDAVExpression (Element e) {
        String name = e.getName();
        BasicExpressionSample result = null;
        
        if (name.equals ("eq")) {
            String prop = propName (e);
            String literal = e.getChild ("literal", e.getNamespace()).getText();
            result = new BasicExpressionSample ("(" + prop + " equals " + literal + ")", this);
        }
            
        else if (name.equals ("lt")) {
            String prop = propName (e);
            String literal = e.getChildText ("literal", e.getNamespace());
            
            result = new BasicExpressionSample ("(" + prop + " lower_than " + literal + ")", this);
        }
        // ...
        
        return result;
    }
        
    /**
     * called by BasicExpressionCompiler after construction.
     *
     * @param    query               the associated BasicQuery
     * @param    propertyProvider    the PropertyProvider for this expression.
     *
     * @throws   BadQueryException
     *
     */
    public void init(IBasicQuery query, PropertyProvider propertyProvider)
        throws BadQueryException
    {
        this.query = (IBasicQuery) query;
        this.propertyProvider = propertyProvider;
    }
    
    /**
     * Method getPropertyProvider
     *
     * @return   the PropertyProvider
     *
     */
    public PropertyProvider getPropertyProvider() {
        return propertyProvider;
    }
    
    /**
     * Method getQuery
     *
     * @return   the IBasicQuery
     *
     */
    public IBasicQuery getQuery() {
        return query;
    }
    
    
    private String propName (Element e) {
        Element propElem = e.getChild ("prop", e.getNamespace());
        Element el = (Element) propElem.getChildren().get(0);
        return el.getName();
    }
}

