/*
 * $Header: /home/cvspublic/jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/MergeExpressionMixed.java,v 1.1 2004/11/29 18:39:38 luetzkendorf Exp $
 * $Revision: 1.1 $
 * $Date: 2004/11/29 18:39:38 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 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.index.lucene.expressions;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

import org.apache.slide.index.lucene.Index;
import org.apache.slide.search.BadQueryException;
import org.apache.slide.search.SearchException;
import org.apache.slide.search.basic.ComparableResourcesPool;
import org.apache.slide.search.basic.IBasicResultSet;
import org.apache.slide.search.basic.expression.GenericBasicExpression;


/**
 * Implements <code>and</code>.
 */
public class MergeExpressionMixed extends AbstractLuceneExpression
{
	private AbstractLuceneExpression expression;
	private Collection basicExpressions; 
    /**
     * Constructor.
     * @param index The index to be searched.
     * @param expressions list of expressions (must all be derived from 
     *        {@link AbstractLuceneExpression}, i.e. must all be lucene executable)
     */
    public MergeExpressionMixed(Index index, AbstractLuceneExpression expression, 
    		Collection basicExpressions)
    {
        super(index);
        
        this.expression = expression;
        this.basicExpressions = basicExpressions;
        
    }

    public IBasicResultSet execute() throws SearchException {
		
    	// 1st execute the lucene expression
    	IBasicResultSet resultSet = this.expression.execute();
    	
    	// iterate over the basic expressions and execute them relative to 
    	// the current result set
    	for(Iterator i = this.basicExpressions.iterator(); i.hasNext();) {
    		Object o = i.next();
    		
    		try {
    			GenericBasicExpression expression = (GenericBasicExpression)o;
    			
    			expression.setRequestedResourcePool(
    					new ComparableResourcesPoolImpl(resultSet));
    			
    			resultSet = expression.execute();
    		} catch(ClassCastException e) {
    			throw new SearchException("Unexpected query structure", e);
    		}
    	}
    	
    	return resultSet;
	}
    
    private static class ComparableResourcesPoolImpl 
		implements ComparableResourcesPool 
    {
    	private IBasicResultSet resultSet;
    	
    	ComparableResourcesPoolImpl(IBasicResultSet resultSet) {
    		this.resultSet = resultSet;
    	}
		
		public Set getPool() throws BadQueryException {
			return this.resultSet;
		}
		public boolean partialResult() {
			return false;
		}
		public Iterator resourceIterator() throws BadQueryException {
			return this.resultSet.iterator();
		}
    }
}
