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

import com.softwareag.tamino.db.api.accessor.TAccessLocation;
import com.softwareag.tamino.db.api.accessor.TXMLObjectAccessor;
import com.softwareag.tamino.db.api.common.TException;
import com.softwareag.tamino.db.api.connection.TConnection;
import com.softwareag.tamino.db.api.connection.TConnectionImpl;
import com.softwareag.tamino.db.api.connection.TPooledConnection;
import com.softwareag.tamino.db.api.objectModel.TXMLObject;
import com.softwareag.tamino.db.api.objectModel.jdom.TJDOMObjectModel;
import com.softwareag.tamino.db.api.response.TResponse;
import java.util.Hashtable;
import org.apache.slide.store.tamino.common.XGlobals;
import org.apache.slide.store.tamino.datastore.XConnection;
import org.apache.slide.store.tamino.datastore.XPathExpression;
import org.apache.slide.store.tamino.datastore.XPathFactory;
import org.apache.slide.store.tamino.datastore.XUtilDBAccessor;
import org.apache.slide.util.XAssertionFailed;
import org.apache.slide.util.XException;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;

/**
 * DB accessor to maintain the global parameters (DeltaV paths) linked to a collection.
 *
 * @author Peter.Nevermann@softwareag.com
 * @version $Revision: 1.3 $
 */
public class GlobalsAccessor implements XGlobals {
    
    private TConnection             tConnection;
    private TXMLObjectAccessor      metaAccessor;
    
    
    /**
     * Default constructor.
     *
     * @param xcon a valid connection to Tamino
     */
    public GlobalsAccessor( XConnection xcon ) throws XException  {
        this.tConnection = xcon.getTConnection();
        this.metaAccessor = tConnection.newXMLObjectAccessor( TAccessLocation.newInstance (META_COLLECTION), TJDOMObjectModel.getInstance() );
        
        XUtilDBAccessor schemaAcessor = new XUtilDBAccessor( tConnection );
        if( !schemaAcessor.isSchema(META_COLLECTION, GLOBALS_SCHEMA_NAME) ) {
            schemaAcessor.createSchema( META_COLLECTION, GLOBALS_SCHEMA_NAME, TAMINO_NAMESPACE_URI );
        }
    }
    
    private static Hashtable globalsElmCache = new Hashtable();
    
    /**
     * This method returns the url cache key
     *
     */
    public String getGlobalsElmCacheKey (String taminoCollection) {
        String dbUri;
        
        if (tConnection instanceof TConnectionImpl)
            dbUri = ((TConnectionImpl)tConnection).getDatabaseURI();
            
        else if (tConnection instanceof TPooledConnection)
            dbUri = ((TPooledConnection)tConnection).getDatabaseURI();
            
            
        else
            throw new XAssertionFailed ("unknown type of TConnection: " + tConnection.getClass().toString());
        
        return dbUri + "/"+taminoCollection;
    }
    
    
    public Element readGlobalsElm( String taminoCollection ) throws XException {
        Element result = (Element)globalsElmCache.get(getGlobalsElmCacheKey(taminoCollection));
        if (result != null) return result;
        
        try {
            XPathExpression query = XPathFactory.globalsConfig( taminoCollection );
            TResponse response = metaAccessor.query( query.getTQuery() );
            if( !response.getReturnValue().equals("0") )
                throw new XException( "Query "+query+" failed, return value is "+response.getReturnValue() );
            
            TXMLObject object = response.getFirstXMLObject();
            if (object != null && object.getElement() instanceof Element) {
                result = (Element)object.getElement();
                globalsElmCache.put(getGlobalsElmCacheKey(taminoCollection), result);
            }
            return result;
        }
        catch (TException e) {
            throw new XException( "Read globals for collection "+taminoCollection+" failed", e );
        }
    }
    
    //    public void deleteGlobals( String taminoCollection ) throws XException {
    //        globalsElmCache.remove(taminoCollection);
    //        try {
    //            if( readGlobalsElm(taminoCollection) == null )
    //                return;
//
    //            XPathGlobals query = new XPathGlobals( taminoCollection );
    //            TResponse response = metaAccessor.delete( query.getTQuery() );
    //            if( !response.getReturnValue().equals("0") )
    //                throw new XException( "Delete with "+query+" failed, return value is "+response.getReturnValue() );
    //        }
    //        catch (TException e) {
    //            throw new XException( "Delete globals for collection "+taminoCollection+" failed", e );
    //        }
    //    }
    
    public void createGlobals( String taminoCollection, Element configElm ) throws XException {
        try {
            if( readGlobalsElm(taminoCollection) != null )
                throw new XException( "Insert globals for collection "+taminoCollection+" failed - already exists" );
            Element root = new Element( GLOBALS_SCHEMA_ELEMENT_NAME, TAMINO_NAMESPACE_PREFIX, TAMINO_NAMESPACE_URI );
            Element tcolElm = new Element( "taminoCollection" );
            tcolElm.addContent( taminoCollection );
            root.addContent( tcolElm );
            root.addContent( configElm );
            XMLOutputter out = new XMLOutputter();
            TXMLObject xmlObject = TXMLObject.newInstance( out.outputString(root) );
            TResponse response = metaAccessor.insert( xmlObject );
            if( !response.getReturnValue().equals("0") )
                throw new XException( "Insert globals for collection "+taminoCollection+" failed, return value is "+response.getReturnValue() );
        }
        catch (TException e) {
            throw new XException( "Insert globals for collection "+taminoCollection+" failed", e );
        }
    }
    
    public void updateGlobals( String taminoCollection, String xmlConfig ) throws XException {
        globalsElmCache.remove(taminoCollection);
        try {
            if( readGlobalsElm(taminoCollection) == null )
                throw new XException( "Update globals for collection "+taminoCollection+" failed - not found" );
            TXMLObject xmlObject = TXMLObject.newInstance( xmlConfig );
            TResponse response = metaAccessor.update( xmlObject );
            if( !response.getReturnValue().equals("0") )
                throw new XException( "Update globals for collection "+taminoCollection+" failed, return value is "+response.getReturnValue() );
        }
        catch (TException e) {
            throw new XException( "Update globals for collection "+taminoCollection+" failed", e );
        }
    }
    
}

