/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/testsuite/junit/store/org/apache/slide/store/tamino/datastore/XTSD3Test.java,v 1.3 2004/07/30 06:52:18 ozeigermann Exp $
 * $Revision: 1.3 $
 * $Date: 2004/07/30 06:52:18 $
 *
 * ====================================================================
 *
 * 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.TNonXMLObjectAccessor;
import com.softwareag.tamino.db.api.accessor.TSchemaDefinition3Accessor;
import com.softwareag.tamino.db.api.accessor.TUndefineException;
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.TConnectionFactory;
import com.softwareag.tamino.db.api.objectModel.TNonXMLObject;
import com.softwareag.tamino.db.api.objectModel.TXMLObject;
import com.softwareag.tamino.db.api.objectModel.dom.TDOMObjectModel;
import com.softwareag.tamino.db.api.objectModel.jdom.TJDOMObjectModel;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.slide.store.tamino.Configuration;
import org.apache.slide.store.tamino.common.XGlobals;
import org.apache.slide.store.tamino.datastore.schema.XSchemaFactory;
import org.apache.slide.util.XException;


/**
 ** Test the TSD3 compatibility.
 **
 ** @author Hardy.Kiefer@softwareag.com
 **
 ** @version 0.1
 **/
public class XTSD3Test
    extends TestCase
    implements XGlobals {

    private static final String     XML_CONTENT_FILE = "joesgarage.xml";
    private static final String        XML_UPPER_TAG = "cd";
    private static final String NON_XML_CONTENT_FILE = "code.gif";
    private static final String     NON_XML_FILE_EXT = "gif";
    private static final String NON_XML_FILE_CONTENT_TYPE = "image/gif";
    private static final String      NON_XML_DOCTYPE = "non_xml_doctype";

    private static final String            TSD3_COLL = "TSD3_test_coll";
    private static final String            TSD2_COLL = "TSD2_test_coll";

    private static final String           LOCAL_HOST = "localhost";
    private static final String         DEAULT_HOST = LOCAL_HOST;
    private static final String           DEFAULT_DB = "mydb";

    private TAccessLocation      contentLocationTSD3 = TAccessLocation.newInstance(TSD3_COLL);
    private TAccessLocation      contentLocationTSD2 = TAccessLocation.newInstance(TSD2_COLL);
    private TConnection taminoConnection;
    private String dbUri;
    private XDbHandler dbHandler;
    private XUtilDbSession dbSession;

    /**
     ** Construct a test case with the given test method name.
     **
     ** @pre   testMethodName != null
     ** @post  true
     **
     ** @param testMethodName   name of the test method that should be invoked
     **/
    public XTSD3Test (String testMethodName) {
        super (testMethodName);
    }

    /**
     ** Start precisely this test suite with the commandline interface.
     **
     ** @pre   true
     ** @post  true
     **
     ** @param args   commandline options (none are evaluated)
     **/
    public static void main( String[] args ) {
        junit.textui.TestRunner.run( suite() );
    }

    /**
     ** Return a TestSuite.
     **
     ** @pre   true
     ** @post  true
     **
     ** @return  TestSuite as a Test
     **/
    public static Test suite () {
        // automatically call each method starting with 'test'.
        TestSuite suite = new TestSuite (XTSD3Test.class);
        return suite;
    }

    /**
     ** Construct your fixtures for the test cases in CaseTemplate.
     **
     ** @pre   true
     ** @post  true
     **/
    protected void setUp() throws Exception {
        super.setUp();
        dbUri = Configuration.get().getTaminoDatabaseUrl();
        TConnectionFactory connectionFactory   = TConnectionFactory.getInstance();
        taminoConnection = connectionFactory.newConnection(dbUri);
    }

    /**
     * Creates a TSD3 collection, add a TSD3 XML and nonXML schema
     *
     */
    private void createTSD3collection() throws TException {
        TSchemaDefinition3Accessor schema3Accessor = taminoConnection.
            newSchemaDefinition3Accessor(TDOMObjectModel.getInstance());

        // first try to delete the already existent collection:
        try {
            schema3Accessor.undefine( TSD3_COLL, null );
        } catch ( TUndefineException e ) {
            System.out.println(TSD3_COLL+" could not be undefined!");
        }

        TXMLObject xmlSchema = XSchemaFactory.
            getXMLContentSchema(TSD3_COLL, XML_UPPER_TAG, TSD3_SCHEMA_VERSION);
        schema3Accessor.define (xmlSchema);
        TXMLObject nonXmlSchema = XSchemaFactory.
            getNonXMLContentSchema (TSD3_COLL, NON_XML_DOCTYPE);
        schema3Accessor.define (nonXmlSchema);
    }



    /**
     * Store Data into a TSD3 collection.
     *
     */
    private void storeDataIntoCollection(TAccessLocation contentLocation, String collection) throws TException, IOException, XException  {
        // xml:
        TXMLObjectAccessor xmlContentAccessor = taminoConnection.
            newXMLObjectAccessor(contentLocation, TJDOMObjectModel.getInstance());
        // get xml file:
        URL xmlContentURL = getClass().getResource (XML_CONTENT_FILE);
        assertTrue(XML_CONTENT_FILE + " not found", xmlContentURL != null);
        TXMLObject xmlObject = TXMLObject.newInstance( xmlContentURL );

        xmlContentAccessor.insert(xmlObject);


        // non-xml:
        TNonXMLObjectAccessor nonXMLContentAccessor = taminoConnection.
            newNonXMLObjectAccessor(contentLocation);
        // get non-xml file:
        URL nonXmlContentURL = getClass().getResource (NON_XML_CONTENT_FILE);
        assertTrue(NON_XML_CONTENT_FILE + " not found", nonXmlContentURL != null);
        String contentDir = (new File(nonXmlContentURL.getFile())).getParent();
        File contentFile = new File (contentDir + File.separator + NON_XML_CONTENT_FILE);
        InputStream is = new FileInputStream(contentFile);
        String contentType = NON_XML_FILE_CONTENT_TYPE;

        TNonXMLObject nonXmlObject = TNonXMLObject.
            newInstance( is, collection, NON_XML_DOCTYPE, null, contentType );

        nonXMLContentAccessor.insert(nonXmlObject);
    }

    /**
     * creates some schemas, XML and nonXML and creates XContentIDs for
     * dummy documents. Now checks, if the strings are created properly
     * and the state is ok.
     *
     */
    public void testTSD3() throws Exception {

        // create TSD2 and TSD3 collection and schemas:
        // createTSD2collection();
        createTSD3collection();

        // store data in both collection:
        storeDataIntoCollection( contentLocationTSD3, TSD3_COLL );
        //storeDataIntoCollection( contentLocationTSD2, TSD2_COLL );

        // get DB session and check:
        dbSession = getDbSession( TSD3_COLL );
        if ( dbSession != null ) {
            // test schema language:
            
            float majorVersion = dbSession.getTaminoMajorVersion();
            
            String schemaVersion;
            if (majorVersion > 4)
                schemaVersion = TSD4_SCHEMA_VERSION;
            else
                schemaVersion = TSD3_SCHEMA_VERSION;
            
            checkSchemaLanguageVersion(TSD3_COLL, schemaVersion);

            // test xml/non-xml schema:
            // checkSchemaForXML_NonXML();
        }

        //        dbSession = getDbSession( TSD2_COLL );
        //        if ( dbSession != null ) {
        //            // test schema language:
        //            checkSchemaLanguageVersion(TSD2_COLL, TSD2_SCHEMA_VERSION);
//
        //             // test xml/non-xml schema:
        //            checkSchemaForXML_NonXML();
        //        }
    }

    /**
     * creates a XDbSession for a given collection.
     * @param collection  collection
     * @return  an instance of XDbSession
     *
     */
    private XUtilDbSession getDbSession( String collection ) throws XException {
        XUtilDbSession result = null;
        dbHandler = new XDbHandler(Configuration.get().namespace, Configuration.get().getTaminoUrl(),
                                   Configuration.get().taminoDatabase, collection);
        dbHandler.initialize();
        result = dbHandler.createUtilDbSession();
        result.setDbHandler(dbHandler);
        return result;
    }

    /**
     * Test the correct version of schema language.
     * @param collection  collection
     * @param schemaVersion  schemaVersion
     *
     */
    private void checkSchemaLanguageVersion( String collection, String schemaVersion ) {
        String schemaLanguage = "";
        try {
            schemaLanguage = dbSession.getSchemaLanguage( collection );
        } catch (Exception e){
            e.printStackTrace();
            assertTrue(e + " :Cannot get schema language of " + collection + " !", false);
        }
        if ( !schemaLanguage.equals(schemaVersion) ) {
            assertTrue("Schema version of " + collection + " not correct!", false);
        }
    }
}

