/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/store/org/apache/slide/store/tamino/datastore/search/XPathPool.java,v 1.3 2004/07/30 06:51:58 ozeigermann Exp $
 * $Revision: 1.3 $
 * $Date: 2004/07/30 06:51:58 $
 *
 * ====================================================================
 *
 * 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.store.tamino.datastore.search;

import org.apache.slide.store.tamino.common.XGlobals;
import org.apache.slide.store.tamino.store.ISlideAccessor;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.slide.common.PropertyName;
import org.apache.slide.search.BadQueryException;
import org.apache.slide.search.InvalidQueryException;
import org.jdom.Attribute;
import org.jdom.Element;

/**
 * The XPathPool holds all content queries of one XBasicQuery. In this pool
 * an XContentQuery is identified by a user defined name. This name must be
 * unique in this XBasicQuery.
 *
 * @author <a href="mailto:martin.wallmer@softwareag.com">Martin Wallmer</a>
 * @version $Revision: 1.3 $
 */
public class XPathPool {
    private Map pool = new HashMap ();

    private XBasicQueryImpl query;

    /**
     * Constructor
     *
     * @param    query               a  XBasicQueryImpl
     *
     */
    public XPathPool (XBasicQueryImpl query) {
        this.query = query;
    }

    /**
     * Method getContentQuery
     *
     * @param    e                   an Element
     *
     * @return   a XContentQuery
     *
     * @throws   InvalidQueryException
     *
     */
    public XPathContentQuery getContentQuery (Element e) throws InvalidQueryException {
        return getContentQuery (e.getAttributes(), e.getText ());
    }

    /**
     * Method getContentQuery. In attributes either the attribute
     * XPATH_PROP_NAME or XPATH_REF_NAME must be specified. If XPATH_PROP_NAME
     * is specified, a new XContentQuery with xPath is created and stored
     * in the pool with the value of XPATH_PROP_NAME as key. If XPATH_REF_NAME
     * is specified, the XContentQuery stored under that key is returned.
     *
     * @param    attributes          a  List
     * @param    xPath               a  String
     *
     * @return   a XContentQuery
     *
     * @throws   InvalidQueryException
     *
     */
    public XPathContentQuery getContentQuery (List attributes, String xPath)
        throws InvalidQueryException {
        XPathContentQuery result = null;
        String id  = "";
        String refId = "";

        Attribute propNameAttr = null;
        Attribute refNameAttr = null;

        String queryNamespace = XGlobals.TAMINO_NAMESPACE_URI;
        String queryNamespacePrefix = XGlobals.TAMINO_NAMESPACE_PREFIX;

        Iterator it = attributes.iterator();


        // must have either attribute name or refname
        while (it.hasNext()){
            Attribute att = (Attribute)it.next();
            String sName = att.getName ();


            // set attributes

            if (sName.equals (XLiterals.XPATH_PROP_NAME)) {
                propNameAttr = att;
            }
            else if (sName.equals (XLiterals.XPATH_REF_NAME)) {
                refNameAttr = att;
            }
            else if (sName.equals (XLiterals.XPATH_NAMESPACE)) {
                queryNamespace = att.getValue();
            }
            else if (sName.equals (XLiterals.XPATH_UNWRAP)) {

            }
            else {
                throw new InvalidQueryException ("Attribute " + sName + " not supported");
            }
        }

        if (propNameAttr == null && refNameAttr == null) {
            throw new InvalidQueryException
                ("Element xpath must either have attribute \"" +
                     XLiterals.XPATH_PROP_NAME + "\" or \"" +
                     XLiterals.XPATH_REF_NAME + "\"");
        }


        if (propNameAttr != null) {
            id = propNameAttr.getValue();
            if (pool.containsKey (id)) {
                throw new InvalidQueryException
                    ("there is already a query with id = " + id);
            }
            PropertyName propName = new PropertyName (id, queryNamespace);
            result = new XPathContentQuery (xPath, (ISlideAccessor) query.getStore (), propName, query);
            pool.put (id, result);
        }

        else  {
            refId = refNameAttr.getValue();
            result = (XPathContentQuery) pool.get (refId);

            if (result == null)
                throw new InvalidQueryException ("there is no query with id = " + refId);
        }

        return result;
    }
}

