eu.cloud4soa.repository.utils.RepositoryManager.java Source code

Java tutorial

Introduction

Here is the source code for eu.cloud4soa.repository.utils.RepositoryManager.java

Source

/*
 *  Copyright 2013 Cloud4SOA, www.cloud4soa.eu
 *
 *  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.
 */

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package eu.cloud4soa.repository.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.io.IOUtils;
import org.ontoware.rdf2go.ModelFactory;
import org.ontoware.rdf2go.RDF2Go;
import org.ontoware.rdf2go.exception.ModelRuntimeException;
import org.ontoware.rdf2go.impl.jena26.ModelImplJena26;
import org.ontoware.rdf2go.model.Model;
import org.ontoware.rdf2go.model.Syntax;
import org.openrdf.rdf2go.RepositoryModel;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.http.HTTPRepository;
import org.openrdf.repository.sail.SailRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import com.hp.hpl.jena.sdb.SDBFactory;
import com.hp.hpl.jena.sdb.Store;
import com.hp.hpl.jena.sdb.StoreDesc;
import com.hp.hpl.jena.sdb.sql.SDBConnection;
import com.hp.hpl.jena.sdb.store.LayoutType;
import com.hp.hpl.jena.sdb.util.StoreUtils;
import com.viceversatech.rdfbeans.RDFBeanManager;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;

/**
 *
 * @author vins
 */
public class RepositoryManager {

    protected final static String DEFAULT_REPO_FILE_NAME = "repositoryFile.rdf";
    protected final static String DATA_FILE_NAME = "dataFile.ttl";
    protected final static String ONTOLOGY_FILE_NAME = "c4sOntology.ttl";
    protected final static String ONTOLOGY_PATH = "ontology";

    protected final static String FILE_BACKEND_OPT = "FILE";
    protected final static String DATABASE_BACKEND_OPT = "DATABASE";
    protected final static String EXT_SERVER_BACKEND_OPT = "EXT_SERVER";

    protected final static String HOME_DIR_PROPERTY = "c4s_home";
    protected final static String PROPERTY_FILE_NAME = "repository.properties";
    protected final static String REPO_NAME_PROPERTY = "fileBackend.fileName";
    protected final static String RDF2GO_IMPLEMENTATION = "implementation";
    protected final static String BACKEND_PROPERTY = "backend";
    protected final static String DB_CONF_PROPERTY = "dbBackend";
    protected final static String SESAME_CONF_PROPERTY = "extServerBackend";
    protected final static String SESAME_SERVER_URL_PROP = "serverUrl";

    protected enum SUPPORTED_DB {
        mysql, hsqldb;

        public static boolean contains(String s) {
            for (SUPPORTED_DB elem : values())
                if (elem.name().equals(s))
                    return true;
            return false;
        }

    }

    //Properties loaded by using Spring PropertyPlaceholderConfigurer
    @Value("ORD{rdf2go.jena.implementationClass}")
    protected String JENA_MODEL_FACTORY = "";
    @Value("ORD{rdf2go.implementationClass}")
    protected String rdf2GOImplementation = "";
    @Value("ORD{backend.file.name}")
    protected String repoFileName = "";
    @Value("ORD{backend.type}")
    protected String backend = "";
    @Value("ORD{backend.ext.serverUrl}")
    protected String sesameServerUrl = "";
    /*   @Value("ORD{backend.db.type}")  */ protected String dbType = "";

    @Value("ORD{dataSource.host}")
    protected String dbHost = "";
    @Value("ORD{dataSource.port}")
    protected String dbPort = "";
    @Value("ORD{dataSource.database}")
    protected String dbName = "";
    @Value("ORD{dataSource.user}")
    protected String dbUser = "";
    @Value("ORD{dataSource.password}")
    protected String dbPass = "";
    @Value("ORD{dataSource.driverClass}")
    protected String dbDriver = "";
    @Value("ORD{dataSource.protocol}")
    protected String dbProtocol = "";
    @Value("ORD{dataSource.properties}")
    protected String dbProperties = "";

    private static final Logger logger = LoggerFactory.getLogger(RepositoryManager.class);

    protected RDFBeanManager manager;
    protected SesameMysqlRepository mysqlRepository;
    protected HTTPRepository sesameServerRepository;
    protected Model rdf2goModel;
    protected SDBConnection sdbConn;
    protected Store store;
    protected com.hp.hpl.jena.rdf.model.Model jenaModel;
    @Autowired
    protected DataSource dataSource;

    /**
    * @return the manager
    */
    public RDFBeanManager getManager() {
        return manager;
    }

    public Model getModel() {
        return rdf2goModel;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void initRepository() throws Exception {
        logger.info("***********************************");

        this.setDbType();
        RDF2Go.register(this.rdf2GOImplementation);

        logger.info("creating the model ");
        rdf2goModel = this.modelBuilder(this.backend);
        rdf2goModel.open();

        if (rdf2goModel.isEmpty()) {
            logger.info("Loading data into model");
            this.loadDataIntoModel(rdf2goModel, backend);
        }

        logger.info("Creating the RDFBeanManager");
        manager = new RDFBeanManager(rdf2goModel);
        manager.setAutocommit(true);
        logger.info("Repository successfully created");

    }

    protected void loadDataIntoModel(Model model, String backendOption) throws Exception {

        if (this.backend.equals(FILE_BACKEND_OPT)) {
            logger.debug("Loading data into model from " + this.repoFileName);

            this.readDataFromFile(model, this.repoFileName);
        } else if (model.isEmpty()) {
            logger.debug("Loading data into model from default ontology " + this.ONTOLOGY_FILE_NAME);
            this.readDataFromFile(model, ONTOLOGY_FILE_NAME);
        }
    }

    protected void readDataFromFile(Model model, String filename) throws Exception {
        InputStream resourceStream;
        File file;
        Syntax syntax;

        resourceStream = this.getResourceStream(filename);

        try {
            model.readFrom(resourceStream, Syntax.Turtle);
            //                    model.readFrom(resourceStream);
            if (resourceStream != null) {
                resourceStream.close();
            }
        } catch (ModelRuntimeException e) {
            logger.error("Error in loading data in the model ", e);
            throw e;
        } catch (FileNotFoundException e) {
            logger.error("Error in loading data in the model ", e);
            throw e;
        } catch (IOException e) {
            logger.error("Error in loading data in the model ", e);
            throw e;
        }
    }

    protected InputStream getResourceStream(String filename) {
        InputStream resourceStream = null;
        File file;

        file = new File(filename);
        String abs = file.getAbsolutePath();
        if (!file.exists() && this.rdf2goModel.isEmpty()) {
            logger.debug(" File " + filename + " not found; reading from " + RepositoryManager.ONTOLOGY_FILE_NAME);
            resourceStream = RepositoryManager.class.getClassLoader().getResourceAsStream(
                    RepositoryManager.ONTOLOGY_PATH + "/" + RepositoryManager.ONTOLOGY_FILE_NAME);
        } else {
            logger.debug("Reading from " + filename);
            try {
                resourceStream = new FileInputStream(file);
            } catch (FileNotFoundException ex) {
                logger.error("Problems reading file " + filename, ex);
            }
            if (resourceStream == null) {
                throw new IllegalArgumentException("Could not open file " + filename);
            }
        }

        return resourceStream;
    }

    private void ensureFileExistsOrCopyFromDefault(File configFolder, String name, String defaultSourceName)
            throws IOException {
        File target = new File(configFolder, name);
        if (!target.exists()) {
            copyFromResourceToFile(defaultSourceName, target);
        }

    }

    private void copyFromResourceToFile(String resource, File target) throws IOException {
        try {
            InputStream in = RepositoryManager.class.getClassLoader().getResourceAsStream(resource);
            if (in == null) {
                logger.warn(" %%%missing " + resource + " from classpath");
            } else {
                // try to write the application logging file so admin can change it.
                try {
                    target.getParentFile().mkdirs();
                    FileOutputStream out = new FileOutputStream(target);
                    try {
                        byte[] buff = new byte[1024];
                        int read = 0;
                        while ((read = in.read(buff)) > 0) {
                            out.write(buff, 0, read);
                        }
                    } finally {
                        out.close();
                    }
                } finally {
                    in.close();
                }
            }
        } catch (IOException e) {
            logger.warn("couldn't write file " + target, e);
            throw e;
        }
    }

    protected File ensureDirectory(String directoryName) throws IOException {
        File configFolder;

        configFolder = new File(directoryName);
        if (!(configFolder.exists() && configFolder.isDirectory())) {
            logger.warn("Missing configuration folder " + configFolder);
            if (configFolder.mkdirs()) {
                logger.warn("Creating default configuration at " + configFolder);
            } else {
                logger.error("Cannot create directory " + directoryName);
                throw new IOException("Cannot create directory " + directoryName);
            }
        }
        return configFolder;
    }

    public void closeModel() {
        FileOutputStream outputStream;
        Model usedModel;

        logger.debug(" ****************    Closing the model    ***************");
        usedModel = manager.getModel();

        if (this.backend.equals(FILE_BACKEND_OPT)) {
            try {
                outputStream = new FileOutputStream(this.repoFileName);

                usedModel.writeTo(outputStream, Syntax.Turtle);

                outputStream.close();
            } catch (FileNotFoundException fnfe) {
                logger.error("Problems handling writing into file " + repoFileName, fnfe);
            } catch (IOException ioe) {
                logger.error("Problem writing model into file " + repoFileName, ioe);
            }
        } else if (this.backend.equals(DATABASE_BACKEND_OPT)) {
            this.sdbConn.close();
        }

        usedModel.close();
        /*        
                try { 
        this.mysqlRepository.shutDown();
                } catch (SailException se) {
        logger.error( "Problems shutting down repository", se);
                }
         * 
         */

    }

    protected Model getDatabaseRepository() throws Exception {
        Model model;
        Repository repo;

        logger.info("configuring repository on " + this.dbType + " database: " + this.getDBConnectString());
        if (this.hasJenaImplementation()) {
            logger.info("Loading db properties file");

            // Building the Store object loading it from a ttl configuration file
            //            String  configurationPath = "sdbconfig.ttl";
            //            logger.error("CONFIGURATION FILE: " + configurationPath);
            //            store = this.getStoreFromTTLConfigurationFile( configurationPath);

            // Building the Store from the PlaceHolder properties
            StoreDesc storeDesc = new StoreDesc(LayoutType.LayoutTripleNodesHash.getName(), this.dbType);
            //            this.sdbConn            = new SDBConnection( this.getDBConnectString(), this.dbUser, this.dbPass);

            //            Connection  con = DataSourceUtils.doGetConnection( dataSource );
            //            logger.debug( "Is the JDBC connection transactional? " + DataSourceUtils.isConnectionTransactional(con, dataSource));
            //            this.sdbConn  = new SDBConnection( con );

            this.sdbConn = new SDBConnection(dataSource);
            // enable query logging (log level must be set to INFO in logback.xml in order to actually get the query logged)
            this.sdbConn.setLogSQLStatements(true);

            this.store = SDBFactory.connectStore(sdbConn, storeDesc);

            // in case of in memory database, first I remove previous db
            //          if ( dbType.equals("hsqldb") && dbProtocol.substring(0, 15).equals("jdbc:hsqldb:mem")  ) {
            //              this.store.getTableFormatter().format();
            //          }

            if (!StoreUtils.isFormatted(this.store)) {
                this.store.getTableFormatter().create();
            }

            jenaModel = SDBFactory.connectDefaultModel(this.store);

            model = new ModelImplJena26(jenaModel);

        } else {
            mysqlRepository = new SesameMysqlRepository();
            repo = new SailRepository(mysqlRepository);
            logger.info("initializing repository on mysql database ");
            try {
                repo.initialize();
                logger.info("Repository initialized");
            } catch (RepositoryException e) {
                logger.error("Cannot initialize repository", e);
                throw e;
            }

            model = new RepositoryModel(repo);
        }

        return model;
    }

    protected Store getStoreFromTTLConfigurationFile(String fileUrl) throws Exception {
        Store store = null;
        String configurationPath = fileUrl;

        logger.error("CONFIGURATION FILE: " + configurationPath);
        try {

            File file = null;
            OutputStream out = null;

            file = File.createTempFile("sdbconfigTemp", ".ttl");
            out = new FileOutputStream(file);
            IOUtils.copy(RepositoryManager.class.getClassLoader().getResourceAsStream(configurationPath), out);
            out.flush();
            out.close();
            store = SDBFactory.connectStore(file.getAbsolutePath());
            file.deleteOnExit();

        } catch (Exception exception) {
            logger.error("CONFIGURATION ERROR while configure Store from the ttl file: " + configurationPath,
                    exception);
            throw exception;
        }

        return store;
    }

    protected Repository getExternalRepository() throws RepositoryException {
        Repository repository;

        logger.debug("|||| Creating the httpRepository" + this.sesameServerUrl);
        this.sesameServerRepository = new HTTPRepository(this.sesameServerUrl);
        logger.debug("|||| Created the httpRepository: " + this.sesameServerUrl);
        try {
            sesameServerRepository.initialize();
        } catch (RepositoryException re) {
            logger.error("Error initializing the repository", re);
            throw re;
        }

        logger.debug("Repository initialized");

        //      model = new RepositoryModel ( this.sesameServerRepository );

        return this.sesameServerRepository;
    }

    protected Model getFileRepository() throws IOException {

        //----------------------- RDF2go --------------------------   
        ModelFactory modelFactory = RDF2Go.getModelFactory();
        return modelFactory.createModel();
    }

    protected Model modelBuilder(String backedType) throws Exception {
        Repository resultingRepository;
        Model resultingModel;

        if (backedType.equals(FILE_BACKEND_OPT)) {
            resultingModel = this.getFileRepository();
        } else {
            if (backedType.equals(DATABASE_BACKEND_OPT)) {

                resultingModel = this.getDatabaseRepository();
            } else {
                resultingRepository = this.getExternalRepository();
                resultingModel = new RepositoryModel(resultingRepository);
            }

        }

        return resultingModel;
    }

    protected boolean hasJenaImplementation() {
        return (this.rdf2GOImplementation.equals(JENA_MODEL_FACTORY));
    }

    //    protected Properties getDProperties() {
    //        Properties  jenaProperties;
    //        
    //        jenaProperties  = new Properties();
    //        jenaProperties.setProperty( ModelFactoryImpl.BACKEND,           this.backend);
    //        jenaProperties.setProperty( ModelFactoryImpl.DB_CONNECT_STRING, this.getDBConnectString() );
    //        jenaProperties.setProperty( ModelFactoryImpl.SQL_DRIVERNAME,    this.getSqlDriver());
    //        jenaProperties.setProperty( ModelFactoryImpl.DB_USER,           this.getDBUser());
    //        jenaProperties.setProperty( ModelFactoryImpl.DB_PASSWD,         this.getDBPass());
    //        
    //        return jenaProperties;
    //    }

    protected String getDBConnectString() {
        StringBuffer dbConnectString;
        String serverName;
        String portNumber;

        dbConnectString = new StringBuffer("");
        dbConnectString.append(this.dbProtocol);
        if (dbHost != null && !dbHost.equals("")) {
            if (dbConnectString.length() > 2 && !dbConnectString
                    .substring(dbConnectString.length() - 2, dbConnectString.length()).equals("//")) {
                logger.info("^^^^^^ "
                        + dbConnectString.substring(dbConnectString.length() - 2, dbConnectString.length()));
                dbConnectString.append("//");
            }
            dbConnectString.append(this.dbHost);
            if (this.dbPort != null && !this.dbPort.equals("")) {
                dbConnectString.append(":").append(this.dbPort);
            }
            if (this.dbName != null && !dbName.equals("")) {
                dbConnectString.append("/").append(this.dbName);
            }
        }
        if (dbProperties != null) {
            dbConnectString.append(dbProperties);
        }

        /*        if ( this.dbType.equals("hsqldb") ) {
        dbConnectString.append(";sql.enforce_size=false");
                }
         * 
         */

        logger.debug("DB connection string: " + dbConnectString.toString());
        return dbConnectString.toString();
    }

    public void closeStore() {
        this.store.close();
    }

    public boolean checkAutocommit() {

        return this.jenaModel.supportsTransactions();

    }

    public void rollbackTxSemRepo() {
        this.jenaModel.abort();

    }

    public void commitTxSemRepo() {
        this.jenaModel.commit();
        this.manager.setAutocommit(true);

    }

    public void beginTxOnSemRepo() {
        this.manager.setAutocommit(false);
        this.jenaModel.begin();
    }

    protected void setDbType() throws Exception {
        String dbType;

        dbType = this.dbProtocol.substring(this.dbProtocol.indexOf(":") + 1);
        dbType = dbType.substring(0, dbType.indexOf(":"));

        logger.debug("database type: " + dbType);

        if (SUPPORTED_DB.contains(dbType)) {
            this.dbType = dbType;
        } else {
            throw new Exception("Unknown database type");
        }
    }

}