/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/store/org/apache/slide/store/tamino/datastore/MetaDataURLAccessor.java,v 1.3 2004/07/30 06:51:54 ozeigermann Exp $
 * $Revision: 1.3 $
 * $Date: 2004/07/30 06:51:54 $
 *
 * ====================================================================
 *
 * 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.TAccessLocation;
import com.softwareag.tamino.db.api.accessor.TXMLObjectAccessor;
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.TDataObject;
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.ArrayList;
import java.util.Hashtable;
import java.util.List;
import org.apache.slide.store.tamino.common.XGlobals;
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.XUri;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;


/**
 * Accessor class to retrive the host, port an servlet name to build
 * a complete WebDAV URL.
 *
 * @author juergen.pill@softwareag.com
 * @version $Revision: 1.3 $
 */
public class MetaDataURLAccessor implements XGlobals {
    
    private TConnection             tConnection;
    private TXMLObjectAccessor      metaAccessor;
    
    static private Hashtable  urlCache = new Hashtable();
    
    /**
     * Constructor.
     *
     * @param tConnection a valid connection to Tamino
     */
    public MetaDataURLAccessor (TConnection tConnection) throws Exception {
        this.tConnection  = tConnection;
        XUtilDBAccessor utilAcessor = new XUtilDBAccessor(tConnection);
        
        metaAccessor = tConnection.newXMLObjectAccessor(TAccessLocation.newInstance (META_COLLECTION), TJDOMObjectModel.getInstance());
        
        if (!utilAcessor.isSchema(META_COLLECTION, URL_SCHEMA_NAME)) {
            utilAcessor.createSchema(META_COLLECTION, URL_SCHEMA_NAME, TAMINO_NAMESPACE_URI);
        }
    }
    
    
    /**
     * This method reads the associated WebDAV URL prefix for a given Tamino collection
     *
     * @param    taminoCollection      the Tamino collection name
     *
     */
    public String readWebdavURL (String taminoCollection) throws Exception {
        String result = (String)urlCache.get(getUrlCacheKey(taminoCollection));
        if (result != null) return result;
        
        result = doReadWebdavURL(taminoCollection);
        if (result == null) result = getDefaultWebdavURL();
        
        urlCache.put(getUrlCacheKey(taminoCollection), result);
        
        return result;
    }
    
    
    /**
     * This method reads the associated WebDAV URL prefix for a given Tamino collection
     *
     * @param    tDataObject         a Tamino object containing the collection name
     *
     */
    public String readWebdavURL (TDataObject tDataObject) throws Exception {
        return readWebdavURL(tDataObject.getCollection());
    }
    
    
    
    
    /**
     * This method deletes the associated WebDAV URL prefix for a given Tamino collection
     *
     * @param    taminoCollection      the Tamino collection name
     *
     */
    public void deleteWebdavURL (String taminoCollection) throws Exception {
        String result = doReadWebdavURL(taminoCollection);
        if (result != null) {
            urlCache.remove(getUrlCacheKey(taminoCollection));
            doDeleteWebdavURL(taminoCollection);
        }
    }
    
    
    /**
     * This method deletes the associated WebDAV URL prefix for a given Tamino collection
     *
     * @param    tDataObject         a Tamino object containing the collection name
     *
     */
    public void deleteWebdavURL (TDataObject tDataObject) throws Exception {
        deleteWebdavURL(tDataObject.getCollection());
    }
    
    
    /**
     * This method stores the associated WebDAV URL prefix for a given Tamino collection
     *
     * @param    taminoCollection      the Tamino collection name
     * @param    host      the WebDAV host
     * @param    port      the WebDAV port
     * @param    server    the WebDAV server
     *
     */
    public void storeWebdavURL (String taminoCollection, String host, String port, String server) throws Exception {
        if (readWebdavURL(taminoCollection).equals(getWebdavURL(host, port, server))) return;
        if (doReadWebdavURL(taminoCollection) != null) doDeleteWebdavURL(taminoCollection);
        TXMLObject xmlObject = TXMLObject.newInstance( computeURLdocument(taminoCollection, host, port, server) );
        TResponse response = metaAccessor.insert( xmlObject );
        urlCache.remove(getUrlCacheKey(taminoCollection));
    }
    
    
    /**
     * This method checks if the associated WebDAV URL prefix matches a given Tamino collection
     *
     * @param    taminoCollection      the Tamino collection name
     * @param    host      the WebDAV host
     * @param    port      the WebDAV port
     * @param    server    the WebDAV server
     *
     */
    public boolean checkWebdavURL (String taminoCollection, String host, String port, String server) throws Exception {
        return readWebdavURL(taminoCollection).equals(getWebdavURL(host, port, server));
    }
    
    
    /**
     * This method calculates the WebDAV URL prefix based on host, server and port
     *
     * @param    host      the WebDAV host
     * @param    port      the WebDAV port
     * @param    server    the WebDAV server
     *
     */
    public String getWebdavURL (String host, String port, String server) {
        return XUri.HTTP_PREFIX + host + ":" + port + "/" + server + "/";
    }
    
    /**
     * This method returns a default WebDAV URL prefix
     *
     */
    public String getDefaultWebdavURL () {
        return "...";
    }
    
    
    /**
     * This method returns an XML document for the WebDAV URL
     *
     * @param    taminoCollection      the tamino collection name
     * @param    host      the WebDAV host
     * @param    port      the WebDAV port
     * @param    server    the WebDAV server
     *
     */
    private Document computeURLdocument (String taminoCollection, String host, String port, String server) {
        List elementList = new ArrayList();
        elementList.add(new Element("taminoCollection").addContent(taminoCollection));
        elementList.add(new Element("host").addContent(host));
        elementList.add(new Element("port").addContent(port));
        elementList.add(new Element("server").addContent(server));
        
        Namespace namespace = Namespace.getNamespace(TAMINO_NAMESPACE_PREFIX, TAMINO_NAMESPACE_URI);
        Element  root = new Element(URL_SCHEMA_ELEMENT_NAME, namespace);
        root.setContent(elementList);
        
        return new Document(root);
    }
    
    
    
    /**
     * This method reads the associated WebDAV URL prefix for a given Tamino collection
     *
     * @param    taminoCollection      the Tamino collection name
     * @param    host      the WebDAV host
     * @param    port      the WebDAV port
     * @param    server    the WebDAV server
     *
     */
    private String doReadWebdavURL (String taminoCollection) throws Exception {
        String result = null;
        XPathExpression query = XPathFactory.webdavUrls(taminoCollection);
        TResponse response = metaAccessor.query(query.getTQuery() );
        TXMLObject object = response.getFirstXMLObject();
        if (object != null && object.getElement() instanceof Element) {
            Element element = (Element)object.getElement();
            result = getWebdavURL(element.getChildText("host"),
                                  element.getChildText("port"),
                                  element.getChildText("server") );
        }
        return result;
    }
    
    
    
    
    
    /**
     * This method reads the associated WebDAV URL prefix for a given Tamino collection
     *
     * @param    taminoCollection      the Tamino collection name
     * @param    host      the WebDAV host
     * @param    port      the WebDAV port
     * @param    server    the WebDAV server
     *
     */
    private void doDeleteWebdavURL (String taminoCollection) throws Exception {
        XPathExpression query = XPathFactory.webdavUrls(taminoCollection);
        TResponse response = metaAccessor.delete(query.getTQuery() );
    }
    
    /**
     * This method returns the url cache key
     *
     */
    public String getUrlCacheKey (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;
    }
    
    
    
}


