/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/store/org/apache/slide/store/tamino/datastore/XAccessor.java,v 1.1 2004/03/25 16:18:00 juergen Exp $
 * $Revision: 1.1 $
 * $Date: 2004/03/25 16:18:00 $
 *
 * ====================================================================
 *
 * 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;

import com.softwareag.tamino.db.api.accessor.TXMLObjectAccessor;
import com.softwareag.tamino.db.api.accessor.TXQuery;
import com.softwareag.tamino.db.api.common.TException;
import com.softwareag.tamino.db.api.objectModel.TXMLObjectIterator;
import com.softwareag.tamino.db.api.objectModel.jdom.TJDOMAdapter;
import com.softwareag.tamino.db.api.response.TResponse;
import org.apache.slide.store.tamino.common.XDatastoreException;
import org.apache.slide.store.tamino.common.XGlobals;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jdom.Element;

/**
 * @version $Revision: 1.1 $
 */
public abstract class XAccessor {
    protected final TXMLObjectAccessor accessor;
    
    public XAccessor(TXMLObjectAccessor accessor) {
        this.accessor = accessor;
    }

    //--

    public Map queryAllContentIds (String collection) throws XDatastoreException {
        return getIdTextMap(queryElements(XPathFactory.contentIds (collection)));
    }
    
    private static Map getIdTextMap(List elements) throws XDatastoreException {
        Map result;
        Iterator iter;
        Element el;
        
        result = new HashMap();
        iter = elements.iterator();
        while (iter.hasNext()) {
            el = (Element) iter.next();
            result.put( XUtilDbSession.getInoId(el), el.getText() );
        }
        return result;
    }
    
    protected Map getUurisMap(XPathExpression xPathExpr) throws XDatastoreException {
        Map result;
        Iterator iter;
        Element el;
        
        result = new HashMap();
        iter = queryElements(xPathExpr).iterator();
        while (iter.hasNext()) {
            el = (Element) iter.next();
            result.put( XUtilDbSession.getInoId(el), el.getAttributeValue( "uri" ) );
        }
        return result;
    }

    //--
    
    public Element queryOneElement(XPathExpression xPathExpr) throws XDatastoreException {
        List result;
        
        result = queryElements(xPathExpr);
        if (result.size() == 1) {
            return (Element) result.get(0);
        } else {
            throw new XDatastoreException("exactly one result expected for " + xPathExpr + ", got " + result.size());
        }
    }

    public Element queryOptElement(XPathExpression xPathExpr) throws XDatastoreException {
        List result;
        
        result = queryElements(xPathExpr);
        switch (result.size()) {
            case 0:
                return null;
            case 1:
                return (Element) result.get(0);
            default:
                throw new XDatastoreException("at most one result expected for " + xPathExpr + ", got " + result.size());
        }
    }
    
    public List queryElements(XPathExpression xPathExpr) throws XDatastoreException {
        List result;
        TResponse response;
        TXMLObjectIterator iter;
        TJDOMAdapter obj;
        
        result = new ArrayList();
        try {
            response = accessor.query (xPathExpr.getTQuery());
            if (!response.getReturnValue().equals("0")) {
                throw new XDatastoreException ("query '" + xPathExpr + "failed, return value is " + response.getReturnValue());
            }
            iter = response.getXMLObjectIterator();
            while (iter.hasNext()) {
                obj = (TJDOMAdapter) iter.next();
                result.add( obj.getElement() );
            }
        } catch (TException e) {
            throw new XDatastoreException (e);
        }
        return result;
    }
 
    //--
    
    public Element xqueryOptElement(String xqueryStr) throws XDatastoreException {
        List result;
        
        result = xqueryElements(xqueryStr);
        switch (result.size()) {
            case 0:
                return null;
            case 1:
                return (Element) result.get(0);
            default:
                throw new XDatastoreException("at most one result expected for " + xqueryStr + ", got " + result.size());
        }
    }
    
    public List xqueryElements(String xqueryStr) throws XDatastoreException {
        List result;
        TResponse response;
        TXMLObjectIterator iter;
        TJDOMAdapter obj;
        
        TXQuery xquery;

        xquery = TXQuery.newInstance(xqueryStr);
        result = new ArrayList();
        try {
            response = accessor.xquery(xquery);
            if (!response.getReturnValue().equals("0")) {
                throw new XDatastoreException ("xquery '" + xqueryStr + "failed, return value is " + response.getReturnValue());
            }
            iter = response.getXMLObjectIterator();
            while (iter.hasNext()) {
                obj = (TJDOMAdapter) iter.next();
                result.add( obj.getElement() );
            }
        } catch (TException e) {
            throw new XDatastoreException (e);
        }
        return result;
    }
    
    //--
    
    protected static void response(TResponse response) throws XDatastoreException {
        if (!response.getReturnValue().equals("0")) {
            throw new XDatastoreException("response code indicates an error: " + response.getReturnValue());
        }
    }
}
