/*****************************************************************************
 * Source code metadata
 *
 * Author    ijd
 * Package   Jena2 Tests
 * Created   Nov 12, 2007
 * Filename  DbImportTest.java
 *
 * (c) Copyright 2007 Hewlett-Packard Development Company, LP
 *****************************************************************************/

// Package
///////////////
package jena.example;


// Imports
///////////////
import java.io.StringReader;
import java.util.Calendar;

import org.apache.log4j.Logger;

import com.hp.hpl.jena.db.DBConnection;
import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.rdf.model.*;
import com.hp.hpl.jena.vocabulary.DC;

/**
 * <p>
 * This example shows how to reference existing models from a database when processing
 * imports.
 * </p>
 *
 * @author Ian Dickinson, HP Labs (<a href="mailto:Ian.Dickinson@hp.com">email</a>)
 */
public class DbImportTest
{
    // Constants
    //////////////////////////////////

    private static final String DB_USER = "jenatest";
    private static final String DB_PW = "jenatest";
    private static final String DB = "MySQL";
    private static final String DB_URL = "jdbc:mysql://localhost/jenatest";
    private static final String DB_DRIVER = com.mysql.jdbc.Driver.class.getName();

    // fake ontology URI's

    public static final String ONTOLOGY_A = "http://example.org/ontology/a";
    public static final String ONTOLOGY_B = "http://example.org/ontology/b";
    public static final String ONTOLOGY_C = "http://example.org/ontology/c";

    // Static variables
    //////////////////////////////////

    @SuppressWarnings(value = "unused")
    private static Logger log = Logger.getLogger( DbImportTest.class );

    // Instance variables
    //////////////////////////////////

    /** JDBC connection */
    private DBConnection m_conn;

    /** Jena RDB model maker */
    private ModelMaker m_maker;


    // Constructors
    //////////////////////////////////

    // External signature methods
    //////////////////////////////////

    public static void main( String[] args ) {
        new DbImportTest().run();
    }

    public void run() {
        attach();
        ensureLoaded( ONTOLOGY_A );
        ensureLoaded( ONTOLOGY_B );
        ensureUnloaded( ONTOLOGY_C );
        loadImportingOntology();
    }

    // Internal implementation methods
    //////////////////////////////////

    protected void attach() {
        m_conn = new DBConnection( DB_URL, DB_USER, DB_PW, DB );
        m_maker = ModelFactory.createModelRDBMaker( m_conn );

        try {
            Class.forName( DB_DRIVER );
        }
        catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.exit( 1 );
        }
    }

    protected void ensureLoaded( String ontologyURL ) {
        log.debug( "Checking to see if loaded: " + ontologyURL );

        if (!m_maker.hasModel( ontologyURL )) {
            log.debug( "Creating a new ontology store for: " + ontologyURL );

            // create the model in the database
            OntModel om = ModelFactory.createOntologyModel( getMaker(), m_maker.createModel( ontologyURL ) );

            // add some content - here we just fake it by adding a single dc:date property
            // to the owl:Ontology element
            Ontology ont = om.createOntology( ontologyURL );
            ont.addProperty( DC.date, om.createTypedLiteral( Calendar.getInstance() ) );
        }
    }

    protected void ensureUnloaded( String ontologyURL ) {
        log.debug( "Checking unloaded: " + ontologyURL );

        if (m_maker.hasModel( ontologyURL )) {
            log.debug( "Dropping ontology store for: " + ontologyURL );

            // create the ontology model
            m_maker.removeModel( ontologyURL );
        }
    }

    protected void loadImportingOntology() {
        String SOURCE = "@prefix rdf:         <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\n" +
                        "@prefix rdfs:        <http://www.w3.org/2000/01/rdf-schema#>.\n" +
                        "@prefix owl:         <http://www.w3.org/2002/07/owl#>.\n" +
                        "<" + ONTOLOGY_C + "> a owl:Ontology \n" +
                        "   ; owl:imports <" + ONTOLOGY_A + ">\n" +
                        "   ; owl:imports <" + ONTOLOGY_B + ">.\n";

        log.debug( "About to load source ontology:" );
        log.debug( SOURCE );

        // create an ont model spec that uses a custom document manager to
        // look for imports in the database
        OntModelSpec oms = getMaker();
        oms.setDocumentManager( new DbAwareDocumentManager( m_maker ) );

        // create the ontology model
        Model base = m_maker.createModel( ONTOLOGY_C );
        OntModel om = ModelFactory.createOntologyModel( oms, base );

        // read in some content which does importing
        om.read( new StringReader( SOURCE ), ONTOLOGY_C, "N3" );

        // as a test, write everything
        System.out.println( "Combined model contents:" );
        om.writeAll( System.out, "N3", null );
    }

    protected OntModelSpec getMaker() {
        OntModelSpec oms = new OntModelSpec( OntModelSpec.OWL_MEM );
        oms.setBaseModelMaker( m_maker );
        return oms;
    }


    //==============================================================================
    // Inner class definitions
    //==============================================================================

}

