X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.project%2Fsrc%2Forg%2Fsimantics%2Fproject%2Fmanagement%2FServerManager.java;fp=bundles%2Forg.simantics.project%2Fsrc%2Forg%2Fsimantics%2Fproject%2Fmanagement%2FServerManager.java;h=936ded8b31f580d85ca38cbdab4b8ae70f2102b5;hp=205706c48c0bab2e7b63d864540f0f70a37f4572;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.project/src/org/simantics/project/management/ServerManager.java b/bundles/org.simantics.project/src/org/simantics/project/management/ServerManager.java index 205706c48..936ded8b3 100644 --- a/bundles/org.simantics.project/src/org/simantics/project/management/ServerManager.java +++ b/bundles/org.simantics.project/src/org/simantics/project/management/ServerManager.java @@ -1,496 +1,496 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management - * in Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.project.management; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.BindException; -import java.net.Socket; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -import org.simantics.databoard.util.StreamUtil; -import org.simantics.db.Driver; -import org.simantics.db.Driver.Management; -import org.simantics.db.ReadGraph; -import org.simantics.db.ServerEx; -import org.simantics.db.ServerI; -import org.simantics.db.ServiceLocator; -import org.simantics.db.Session; -import org.simantics.db.WriteOnlyGraph; -import org.simantics.db.common.request.ReadRequest; -import org.simantics.db.common.request.WriteOnlyRequest; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.service.ClusterUID; -import org.simantics.db.service.XSupport; -import org.simantics.graph.db.CoreInitialization; -import org.simantics.layer0.DatabaseManagementResource; -import org.simantics.layer0.Layer0; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Server Manager handles starting and pooling of ProCore server instances. - * - * @author Toni Kalajainen - */ -public class ServerManager { - private static final Logger LOGGER = LoggerFactory.getLogger(ServerManager.class); - - /** Default properties with default user and password */ - public static final Properties DEFAULT; - - /** Driver for database." */ - final Driver driver; - - /** Actual Server Instances. This object is synchronized by itself as lock. */ - Map servers = Collections.synchronizedMap( new HashMap() ); - - /** - * Create a new server manager. - * - * @param applicationDirectory location of org.simantics.db.build - * @throws IOException - */ - public ServerManager(Driver driver) throws IOException { - this.driver = driver; - } - public Management getManagement(File dbFolder) throws DatabaseException { - // We are using ProCoreDriver and know it's address format and security model. Not good! - return driver.getManagement(dbFolder.getAbsolutePath(), null); - } - /** - * Create a new database that is initialized with given graphs. - * One of them must be layer0. - * Database directory is created if it did not exist. - * - * @param databaseDirectory place where database is installed - * @param initialGraphs initialGraphs to install - * @throws DatabaseException - */ - public Session createDatabase(File databaseDirectory) throws DatabaseException { - try { - LOGGER.debug("Creating database to "+ databaseDirectory); - - Session session = null; - ServerEx server1 = getServer(databaseDirectory); - server1.start(); - try { - // This will initialize the fixed URIs and corresponding resources. - // These are needed by the query system to parse URIs. - // The server will generate the clusters for the generated resources. - // The layer0 statements will be generated in phase two. - // This will close the connection to server because the only thing - // you can do with this connection is to initialize the fixed URIs. - Properties info = new Properties(); - info.setProperty("user", "Default User"); - info.setProperty("password", ""); - session = server1.createSession(info); - XSupport xs = session.getService(XSupport.class); - ClusterUID[] clusters = xs.listClusters(); - if (clusters.length > 1) {// Database contain clusters, assuming initialization is done."); - ReadRequest req = new ReadRequest() { - @Override - public void run(ReadGraph g) { - // Registers Layer0 with the session ServiceLocator. - Layer0.getInstance(g); - } - }; - session.syncRequest(req); - return session; - } - CoreInitialization.initializeBuiltins(session); - // This will try to initialize Builtins.class but because there is no statements - // in the server only the previously added fixed URIs are found. - // If we'd want to get rid of the missing layer0 URI warnings then - // a non initialized session should be used to add graph statements - // without using Builtins.class at all or by initializing Builtins.class - // only with the fixed URIs. - session.getService(XSupport.class).setServiceMode(true, true); - - // This will add layer0 statements. The query mechanism is not - // yet totally functional because there is no statements in the - // server. Mainly WriteOnly request is available here. - GraphBundle l0 = PlatformUtil.getGraph("org.simantics.layer0"); - final GraphBundleEx l0ex = GraphBundleEx.extend(l0); - l0ex.build(); - long[] resourceArray = CoreInitialization.initializeGraph(session, l0ex.getGraph()); - l0ex.setResourceArray(resourceArray); - session.getService(XSupport.class).setServiceMode(true, true); - - DatabaseManagementResource.getInstance(session); - Layer0.getInstance(session); - session.syncRequest(new WriteOnlyRequest() { - @Override - public void perform(WriteOnlyGraph graph) throws DatabaseException { - // Root Library is a cluster set - graph.newClusterSet(graph.getRootLibrary()); - DatabaseManagement mgt = new DatabaseManagement(); - mgt.createGraphBundle(graph, l0ex); - graph.flushCluster(); - }}); - return session; - } finally { - if (null == session) - server1.stop(); - } - } catch (Exception e) { - throw new DatabaseException("Failed to create Simantics database.", e); - } - } - - /** - * Get a server that can be started and stopped. - * - * The result is actually a proxy server. Each successful start() increases - * reference count and stop() decreases. The actual server is closed - * once all proxies are closed. - * - * @param databaseDirectory - * @return server - * @throws DatabaseException - */ - private ServerEx getServer(File databaseDirectory) throws DatabaseException { - File file = databaseDirectory.getAbsoluteFile(); - - ServerHost host = null; - synchronized(servers) { - host = servers.get(file); - if (host==null) { - // Instantiate actual server. We are using ProCoreDriver and know it's address format and security model. Not good! - ServerI server = driver.getServer(file.getAbsolutePath(), null); - - try { - host = new ServerHost(server, databaseDirectory); - } catch (IOException e) { - throw new DatabaseException("Failed to load " + databaseDirectory, e); - } - - servers.put(file, host); - } - } - - ServerEx proxy = new ProxyServer(host); - return proxy; - } - - /** - * @param parseUnresolved - * @return - */ -// public ServerEx getServer(ServerAddress endpoint) { -// return new ConnectedServer(endpoint); -// } - - /** - * Close the server manager, close all servers. - * Deletes temporary files. - */ - public void close() { - synchronized(servers) { - for (ServerHost host : servers.values()) { - ServerI server = host.actual; - try { - if (server.isActive()) - server.stop(); - } catch (DatabaseException e) { - LOGGER.error("Failed to stop database server.", e); - } - } - servers.clear(); - } - } - - public static int getFreeEphemeralPort() { - while(true) { - try { - Socket s = null; - try { - s = new Socket(); - s.bind(null); - return s.getLocalPort(); - } finally { - if (s != null) - s.close(); - } - } catch(BindException e) { - // Nothing to do, try next port - } catch (Throwable e) { - throw new Error(e); - } - } - } - - public static void createServerConfig(File file) throws IOException { - InputStream is = ServerManager.class.getResourceAsStream("server_template.cnfg"); - byte[] data = StreamUtil.readFully(is); - is.close(); - - FileOutputStream os = new FileOutputStream(file, false); - os.write(data); - Properties properties = new Properties(); - properties.store(os, "# automatically generated properties"); - os.close(); - } - - /** - * ServerHost hosts a ServerI instance. For each successful start() a - * reference count is increased and each stop() & kill() it is decreased. - */ - class ServerHost implements ServerEx { - - File database; - ServerI actual; - int refCount = 0; - Properties properties; - - public ServerHost(ServerI actual, File database) - throws IOException { - this.actual = actual; - this.database = database; - this.properties = new Properties(); - } - - public File getDatabase() { - return database; - } - - /** - * Get properties - * @return properties - */ - public Properties getProperties() { - return properties; - } - - @Override - public String getAddress() - throws DatabaseException { - return actual.getAddress(); - } - -// @Override -// public synchronized ServerAddress getServerAddress() -// throws DatabaseException { -// throw new DatabaseException("ServerHost.getServerAddress is not supported. Use getAddress instead."); -// } - - @Override - public boolean isActive() { - try { - return actual.isActive(); - } catch (DatabaseException e) { - return false; - } - } - - /** - * Start server if refCount = 0. If running or start was successful - * the refcount is increased. - * - * For each succesful start(), a stop() or kill() is expected. - */ - @Override - public void start() throws DatabaseException { - boolean isRunning = actual.isActive(); - - if (!isRunning) { - actual.start(); - } - - refCount++; - } - - @Override - public void stop() throws DatabaseException { - if (refCount <= 0) - throw new DatabaseException("Trying to stop a standing process."); - refCount--; - if (refCount > 1) - return; - actual.stop(); - } - - @Override - public Session createSession(Properties properties) throws DatabaseException { - return driver.getSession(actual.getAddress(), properties); - } - - @Override - public ServiceLocator getServiceLocator(Properties info) throws DatabaseException { - return createSession(info); - } - - @Override - public String execute(String command) throws DatabaseException { - return actual.execute(command); - } - - @Override - public String executeAndDisconnect(String command) throws DatabaseException { - return actual.executeAndDisconnect(command); - } - } - - /** - * Proxy Server starts actual server (ServerHost) when first start():ed, - * and closes the actual server once all proxy servers are closed. - * - * @author Toni Kalajainen - */ - public class ProxyServer implements ServerEx { - - boolean running; - ServerHost actual; - - public ProxyServer(ServerHost actual) { - this.actual = actual; - } - - public File getDatabase() { - return actual.getDatabase(); - } - - /** - * Get server properties - * - * @return properties - * @throws IOException - */ - public Properties getProperties() { - return actual.getProperties(); - } - - @Override - public String getAddress() - throws DatabaseException { - return actual.getAddress(); - } - -// @Override -// public synchronized ServerAddress getServerAddress() -// throws DatabaseException { -// return actual.getServerAddress(); -// } - - @Override - public boolean isActive() { - return running && actual.isActive(); - } - - @Override - public void start() throws DatabaseException { - if (running) return; - actual.start(); - running = true; - } - - @Override - public void stop() throws DatabaseException { - if (!running) return; - actual.stop(); - running = false; - } - - @Override - public Session createSession(Properties properties) throws DatabaseException { - return driver.getSession(actual.getAddress(), properties); - } - - @Override - public ServiceLocator getServiceLocator(Properties info) throws DatabaseException { - return createSession(info); - } - - @Override - public String execute(String command) throws DatabaseException { - return actual.execute(command); - } - - @Override - public String executeAndDisconnect(String command) throws DatabaseException { - return actual.executeAndDisconnect(command); - } - } - -// public class ConnectedServer implements ServerEx { -// -// ServerAddress endpoint; -// -// public ConnectedServer(ServerAddress endpoint) { -// this.endpoint = endpoint; -// } -// -// @Override -// public void start() throws DatabaseException { -// // Intentional NOP. Cannot control through socket. -// } -// -// @Override -// public void stop() throws DatabaseException { -// // Intentional NOP. Cannot control through socket. -// } -// -// @Override -// public boolean isActive() { -// // Without better knowledge -// return true; -// } -// -// @Override -// public String getAddress() -// throws DatabaseException { -// return endpoint.getDbid(); -// } -// -// @Override -// public synchronized ServerAddress getServerAddress() -// throws DatabaseException { -// return new ServerAddress(endpoint.getAddress()); -// } -// -// @Override -// public Session createSession(Properties properties) -// throws DatabaseException { -// return driver.getSession(getServerAddress().toString(), properties); -// } -// -// @Override -// public ServiceLocator getServiceLocator(Properties info) throws DatabaseException { -// return createSession(info); -// } -// -// @Override -// public String execute(String command) throws DatabaseException { -// // Intentional NOP. Cannot control through socket. -// return null; -// } -// -// @Override -// public String executeAndDisconnect(String command) throws DatabaseException { -// // Intentional NOP. Cannot control through socket. -// return null; -// } -// } - - static { - DEFAULT = new Properties(); - DEFAULT.setProperty("user", "Default User"); - DEFAULT.setProperty("password", ""); - } - -} - +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.project.management; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.BindException; +import java.net.Socket; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.simantics.databoard.util.StreamUtil; +import org.simantics.db.Driver; +import org.simantics.db.Driver.Management; +import org.simantics.db.ReadGraph; +import org.simantics.db.ServerEx; +import org.simantics.db.ServerI; +import org.simantics.db.ServiceLocator; +import org.simantics.db.Session; +import org.simantics.db.WriteOnlyGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteOnlyRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.service.ClusterUID; +import org.simantics.db.service.XSupport; +import org.simantics.graph.db.CoreInitialization; +import org.simantics.layer0.DatabaseManagementResource; +import org.simantics.layer0.Layer0; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Server Manager handles starting and pooling of ProCore server instances. + * + * @author Toni Kalajainen + */ +public class ServerManager { + private static final Logger LOGGER = LoggerFactory.getLogger(ServerManager.class); + + /** Default properties with default user and password */ + public static final Properties DEFAULT; + + /** Driver for database." */ + final Driver driver; + + /** Actual Server Instances. This object is synchronized by itself as lock. */ + Map servers = Collections.synchronizedMap( new HashMap() ); + + /** + * Create a new server manager. + * + * @param applicationDirectory location of org.simantics.db.build + * @throws IOException + */ + public ServerManager(Driver driver) throws IOException { + this.driver = driver; + } + public Management getManagement(File dbFolder) throws DatabaseException { + // We are using ProCoreDriver and know it's address format and security model. Not good! + return driver.getManagement(dbFolder.getAbsolutePath(), null); + } + /** + * Create a new database that is initialized with given graphs. + * One of them must be layer0. + * Database directory is created if it did not exist. + * + * @param databaseDirectory place where database is installed + * @param initialGraphs initialGraphs to install + * @throws DatabaseException + */ + public Session createDatabase(File databaseDirectory) throws DatabaseException { + try { + LOGGER.debug("Creating database to "+ databaseDirectory); + + Session session = null; + ServerEx server1 = getServer(databaseDirectory); + server1.start(); + try { + // This will initialize the fixed URIs and corresponding resources. + // These are needed by the query system to parse URIs. + // The server will generate the clusters for the generated resources. + // The layer0 statements will be generated in phase two. + // This will close the connection to server because the only thing + // you can do with this connection is to initialize the fixed URIs. + Properties info = new Properties(); + info.setProperty("user", "Default User"); + info.setProperty("password", ""); + session = server1.createSession(info); + XSupport xs = session.getService(XSupport.class); + ClusterUID[] clusters = xs.listClusters(); + if (clusters.length > 1) {// Database contain clusters, assuming initialization is done."); + ReadRequest req = new ReadRequest() { + @Override + public void run(ReadGraph g) { + // Registers Layer0 with the session ServiceLocator. + Layer0.getInstance(g); + } + }; + session.syncRequest(req); + return session; + } + CoreInitialization.initializeBuiltins(session); + // This will try to initialize Builtins.class but because there is no statements + // in the server only the previously added fixed URIs are found. + // If we'd want to get rid of the missing layer0 URI warnings then + // a non initialized session should be used to add graph statements + // without using Builtins.class at all or by initializing Builtins.class + // only with the fixed URIs. + session.getService(XSupport.class).setServiceMode(true, true); + + // This will add layer0 statements. The query mechanism is not + // yet totally functional because there is no statements in the + // server. Mainly WriteOnly request is available here. + GraphBundle l0 = PlatformUtil.getGraph("org.simantics.layer0"); + final GraphBundleEx l0ex = GraphBundleEx.extend(l0); + l0ex.build(); + long[] resourceArray = CoreInitialization.initializeGraph(session, l0ex.getGraph()); + l0ex.setResourceArray(resourceArray); + session.getService(XSupport.class).setServiceMode(true, true); + + DatabaseManagementResource.getInstance(session); + Layer0.getInstance(session); + session.syncRequest(new WriteOnlyRequest() { + @Override + public void perform(WriteOnlyGraph graph) throws DatabaseException { + // Root Library is a cluster set + graph.newClusterSet(graph.getRootLibrary()); + DatabaseManagement mgt = new DatabaseManagement(); + mgt.createGraphBundle(graph, l0ex); + graph.flushCluster(); + }}); + return session; + } finally { + if (null == session) + server1.stop(); + } + } catch (Exception e) { + throw new DatabaseException("Failed to create Simantics database.", e); + } + } + + /** + * Get a server that can be started and stopped. + * + * The result is actually a proxy server. Each successful start() increases + * reference count and stop() decreases. The actual server is closed + * once all proxies are closed. + * + * @param databaseDirectory + * @return server + * @throws DatabaseException + */ + private ServerEx getServer(File databaseDirectory) throws DatabaseException { + File file = databaseDirectory.getAbsoluteFile(); + + ServerHost host = null; + synchronized(servers) { + host = servers.get(file); + if (host==null) { + // Instantiate actual server. We are using ProCoreDriver and know it's address format and security model. Not good! + ServerI server = driver.getServer(file.getAbsolutePath(), null); + + try { + host = new ServerHost(server, databaseDirectory); + } catch (IOException e) { + throw new DatabaseException("Failed to load " + databaseDirectory, e); + } + + servers.put(file, host); + } + } + + ServerEx proxy = new ProxyServer(host); + return proxy; + } + + /** + * @param parseUnresolved + * @return + */ +// public ServerEx getServer(ServerAddress endpoint) { +// return new ConnectedServer(endpoint); +// } + + /** + * Close the server manager, close all servers. + * Deletes temporary files. + */ + public void close() { + synchronized(servers) { + for (ServerHost host : servers.values()) { + ServerI server = host.actual; + try { + if (server.isActive()) + server.stop(); + } catch (DatabaseException e) { + LOGGER.error("Failed to stop database server.", e); + } + } + servers.clear(); + } + } + + public static int getFreeEphemeralPort() { + while(true) { + try { + Socket s = null; + try { + s = new Socket(); + s.bind(null); + return s.getLocalPort(); + } finally { + if (s != null) + s.close(); + } + } catch(BindException e) { + // Nothing to do, try next port + } catch (Throwable e) { + throw new Error(e); + } + } + } + + public static void createServerConfig(File file) throws IOException { + InputStream is = ServerManager.class.getResourceAsStream("server_template.cnfg"); + byte[] data = StreamUtil.readFully(is); + is.close(); + + FileOutputStream os = new FileOutputStream(file, false); + os.write(data); + Properties properties = new Properties(); + properties.store(os, "# automatically generated properties"); + os.close(); + } + + /** + * ServerHost hosts a ServerI instance. For each successful start() a + * reference count is increased and each stop() & kill() it is decreased. + */ + class ServerHost implements ServerEx { + + File database; + ServerI actual; + int refCount = 0; + Properties properties; + + public ServerHost(ServerI actual, File database) + throws IOException { + this.actual = actual; + this.database = database; + this.properties = new Properties(); + } + + public File getDatabase() { + return database; + } + + /** + * Get properties + * @return properties + */ + public Properties getProperties() { + return properties; + } + + @Override + public String getAddress() + throws DatabaseException { + return actual.getAddress(); + } + +// @Override +// public synchronized ServerAddress getServerAddress() +// throws DatabaseException { +// throw new DatabaseException("ServerHost.getServerAddress is not supported. Use getAddress instead."); +// } + + @Override + public boolean isActive() { + try { + return actual.isActive(); + } catch (DatabaseException e) { + return false; + } + } + + /** + * Start server if refCount = 0. If running or start was successful + * the refcount is increased. + * + * For each succesful start(), a stop() or kill() is expected. + */ + @Override + public void start() throws DatabaseException { + boolean isRunning = actual.isActive(); + + if (!isRunning) { + actual.start(); + } + + refCount++; + } + + @Override + public void stop() throws DatabaseException { + if (refCount <= 0) + throw new DatabaseException("Trying to stop a standing process."); + refCount--; + if (refCount > 1) + return; + actual.stop(); + } + + @Override + public Session createSession(Properties properties) throws DatabaseException { + return driver.getSession(actual.getAddress(), properties); + } + + @Override + public ServiceLocator getServiceLocator(Properties info) throws DatabaseException { + return createSession(info); + } + + @Override + public String execute(String command) throws DatabaseException { + return actual.execute(command); + } + + @Override + public String executeAndDisconnect(String command) throws DatabaseException { + return actual.executeAndDisconnect(command); + } + } + + /** + * Proxy Server starts actual server (ServerHost) when first start():ed, + * and closes the actual server once all proxy servers are closed. + * + * @author Toni Kalajainen + */ + public class ProxyServer implements ServerEx { + + boolean running; + ServerHost actual; + + public ProxyServer(ServerHost actual) { + this.actual = actual; + } + + public File getDatabase() { + return actual.getDatabase(); + } + + /** + * Get server properties + * + * @return properties + * @throws IOException + */ + public Properties getProperties() { + return actual.getProperties(); + } + + @Override + public String getAddress() + throws DatabaseException { + return actual.getAddress(); + } + +// @Override +// public synchronized ServerAddress getServerAddress() +// throws DatabaseException { +// return actual.getServerAddress(); +// } + + @Override + public boolean isActive() { + return running && actual.isActive(); + } + + @Override + public void start() throws DatabaseException { + if (running) return; + actual.start(); + running = true; + } + + @Override + public void stop() throws DatabaseException { + if (!running) return; + actual.stop(); + running = false; + } + + @Override + public Session createSession(Properties properties) throws DatabaseException { + return driver.getSession(actual.getAddress(), properties); + } + + @Override + public ServiceLocator getServiceLocator(Properties info) throws DatabaseException { + return createSession(info); + } + + @Override + public String execute(String command) throws DatabaseException { + return actual.execute(command); + } + + @Override + public String executeAndDisconnect(String command) throws DatabaseException { + return actual.executeAndDisconnect(command); + } + } + +// public class ConnectedServer implements ServerEx { +// +// ServerAddress endpoint; +// +// public ConnectedServer(ServerAddress endpoint) { +// this.endpoint = endpoint; +// } +// +// @Override +// public void start() throws DatabaseException { +// // Intentional NOP. Cannot control through socket. +// } +// +// @Override +// public void stop() throws DatabaseException { +// // Intentional NOP. Cannot control through socket. +// } +// +// @Override +// public boolean isActive() { +// // Without better knowledge +// return true; +// } +// +// @Override +// public String getAddress() +// throws DatabaseException { +// return endpoint.getDbid(); +// } +// +// @Override +// public synchronized ServerAddress getServerAddress() +// throws DatabaseException { +// return new ServerAddress(endpoint.getAddress()); +// } +// +// @Override +// public Session createSession(Properties properties) +// throws DatabaseException { +// return driver.getSession(getServerAddress().toString(), properties); +// } +// +// @Override +// public ServiceLocator getServiceLocator(Properties info) throws DatabaseException { +// return createSession(info); +// } +// +// @Override +// public String execute(String command) throws DatabaseException { +// // Intentional NOP. Cannot control through socket. +// return null; +// } +// +// @Override +// public String executeAndDisconnect(String command) throws DatabaseException { +// // Intentional NOP. Cannot control through socket. +// return null; +// } +// } + + static { + DEFAULT = new Properties(); + DEFAULT.setProperty("user", "Default User"); + DEFAULT.setProperty("password", ""); + } + +} +