Package org.apache.openejb.server.hsql

Source Code of org.apache.openejb.server.hsql.HsqlService

/**
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.openejb.server.hsql;

import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.resource.jdbc.plugin.HsqldbDataSourcePlugin;
import org.apache.openejb.server.SelfManaging;
import org.apache.openejb.server.ServerService;
import org.apache.openejb.server.ServiceException;
import org.apache.openejb.spi.ContainerSystem;
import org.hsqldb.Database;
import org.hsqldb.DatabaseManager;
import org.hsqldb.Server;
import org.hsqldb.persist.HsqlDatabaseProperties;
import org.hsqldb.persist.HsqlProperties;
import org.hsqldb.server.ServerConfiguration;
import org.hsqldb.server.ServerConstants;

import javax.naming.Binding;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;

/**
* @version $Rev: 1368056 $ $Date: 2012-08-01 17:29:50 +0200 (Mer, 01 aoû 2012) $
*/
public class HsqlService implements ServerService, SelfManaging {
    // copied from org.hsqldb.server.ServerProperties since it uses package visibility
    private static final java.lang.String sc_key_port = "server.port";
    private static final java.lang.String sc_key_silent = "server.silent";
    private static final java.lang.String sc_key_dbname = "server.dbname";
    private static final java.lang.String sc_key_address = "server.address";
    private static final java.lang.String sc_key_database = "server.database";
    private static final java.lang.String sc_key_no_system_exit = "server.no_system_exit";

    private int port = ServerConfiguration.getDefaultPort(ServerConstants.SC_PROTOCOL_HSQL, false);
    private String ip = ServerConstants.SC_DEFAULT_ADDRESS;
    private Server server;

    public String getName() {
        return "hsql";
    }

    public int getPort() {
        return port;
    }

    public String getIP() {
        return ip;
    }


    public void init(Properties p) throws Exception {
        Properties properties = new Properties();
        for (Map.Entry<Object, Object> entry : p.entrySet()) {
            // Sometimes the properties object has non string values
            if (!(entry.getKey() instanceof String)) continue;
            if (!(entry.getValue() instanceof String)) continue;

            String property = (String) entry.getKey();
            String value = (String) entry.getValue();

            if (property.startsWith(sc_key_dbname + ".") ||
                    property.startsWith(sc_key_database + ".")) {

                throw new ServiceException("Databases cannot be declared in the hsql.properties.  " +
                        "Instead declare a database connection in the openejb.conf file");
            }

            if ("port".equals(property)) {
                properties.setProperty(sc_key_port, value);
            } else if ("bind".equals(property)) {
                properties.setProperty(sc_key_address, value);
            } else {
                properties.setProperty(property, value);
            }
        }
        properties.setProperty(sc_key_no_system_exit, "true");

        boolean disabled = Boolean.parseBoolean(properties.getProperty("disabled"));
        ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
        if (!disabled && containerSystem != null) {
            NamingEnumeration<Binding> bindings;
            try {
                bindings = containerSystem.getJNDIContext().listBindings("openejb/Resource/");
                Set<String> dbnames = new TreeSet<String>();
                for (Binding binding : Collections.list(bindings)) {
                    Object value = binding.getObject();
                    if (value instanceof DataSource) {
                        DataSource jdbc = (DataSource) value;
                        Connection connection = null;
                        String path = null;
                        try {
                            connection = jdbc.getConnection();
                            DatabaseMetaData meta = connection.getMetaData();
                            path = getPath(meta.getDriverName(), meta.getURL());
                        } catch (Throwable t) {
                            continue;
                        } finally {
                            if (connection != null) {
                                try {
                                    connection.close();
                                } catch (SQLException sqlEx) {
                                    // no-op
                                }
                            }
                        }

                        if (path != null) {
                            if (dbnames.size() > 9) {
                                throw new ServiceException("Hsql Server can only host 10 database instances");
                            }
                            String dbname = path.substring(path.lastIndexOf(':') + 1);
                            dbname = dbname.substring(dbname.lastIndexOf('/') + 1);
                            if (!dbnames.contains(dbname)) {
                                properties.put(sc_key_dbname + "." + dbnames.size(), dbname);
                                properties.put(sc_key_database + "." + dbnames.size(), path);
                                dbnames.add(dbname);
                            }
                        }
                    }
                }
            } catch (NameNotFoundException e) {
            }

            // create the server
            server = new Server();
            // add the silent property
            properties.setProperty(sc_key_silent, "true");
            // set the log and error writers
            server.setLogWriter(new HsqlPrintWriter(false));
            server.setErrWriter(new HsqlPrintWriter(true));
            server.setProperties(new HsqlProperties(properties));

            // get the port
            port = server.getPort();

            // get the Address
            String ipString = server.getAddress();
            if (ipString != null && ipString.length() > 0) {
                this.ip = ipString;
            }
        }
    }

    private String getPath(final String driver, final String url) {
        // is this connectoion using the hsql driver?
        if (!HsqlDatabaseProperties.PRODUCT_NAME.equals(driver)) {
            return null;
        }

        // is this a hsql url?
        if (url == null || !url.startsWith("jdbc:hsqldb:")) {
            return null;
        }

        // resolve the relative path and
        // hack off the jdbc:hsqldb stuff
        String path = HsqldbDataSourcePlugin.toAbsolutePath(url).substring("jdbc:hsqldb:".length());

        // is this a connection to a local file, mem, or res database?
        if (!path.startsWith("file:") && !path.startsWith("mem:") && path.startsWith("res:")) {
            return null;
        }

        return path;
    }

    public void service(InputStream inputStream, OutputStream outputStream) throws ServiceException, IOException {
        throw new UnsupportedOperationException("Method not implemented: service(InputStream in, OutputStream out)");
    }

    public void service(Socket socket) throws ServiceException, IOException {
        throw new UnsupportedOperationException("Method not implemented: service(Socket socket)");
    }

    public void start() throws ServiceException {
        if (server == null) return;
        server.start();
    }

    public void stop() throws ServiceException {
        if (server == null) return;
        try {
            server.stop();
        } finally {
            server = null;
            DatabaseManager.closeDatabases(Database.CLOSEMODE_COMPACT);
        }
    }
}
TOP

Related Classes of org.apache.openejb.server.hsql.HsqlService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.