/* Copyright (c) 2001-2018, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hsqldb.server;
import java.lang.reflect.
Constructor;
import java.lang.reflect.
InvocationTargetException;
import java.net.
InetAddress;
import java.net.
ServerSocket;
import java.net.
Socket;
/**
* Base class for producing the Socket objects used by HSQLDB.
*
* @author Blaine Simpson (blaine dot simpson at admc dot com)
* @author Campbell Burnet (campbell-burnet@users dot sourceforge.net)
* @version 2.3.0
* @since 1.7.2
*/
public class
HsqlSocketFactory {
// ----------------------------- static members ---------------------------------
private static
HsqlSocketFactory plainImpl;
private static
HsqlSocketFactory sslImpl;
// ------------------------------ constructors ---------------------------------
/**
* External construction disabled. New factory instances are retrieved
* through the newHsqlSocketFactory method instead.
*/
protected
HsqlSocketFactory() throws
Exception {}
// ------------------------- factory builder method ----------------------------
/**
* Retrieves an HsqlSocketFactory whose subclass and attributes are
* determined by the specified argument, tls.
*
* @param tls whether to retrieve a factory producing SSL sockets
* @throws Exception if the new factory cannot be constructed or is
* of the wrong type
* @return a new factory
*/
public static
HsqlSocketFactory getInstance(boolean
tls) throws
Exception {
return
tls ?
getSSLImpl()
:
getPlainImpl();
}
// -------------------------- public instance methods --------------------------
public void
configureSocket(
Socket socket) {
// default: do nothing
}
/**
* Returns a server socket bound to the specified port.
* The socket is configured with the socket options
* given to this factory.
*
* @return the ServerSocket
* @param port the port to which to bind the ServerSocket
* @throws Exception if a network error occurs
*/
public
ServerSocket createServerSocket(int
port) throws
Exception {
return new
ServerSocket(
port);
}
/**
* Returns a server socket bound to the specified port.
* The socket is configured with the socket options
* given to this factory.
*
* @return the ServerSocket
* @param port the port to which to bind the ServerSocket
* @throws Exception if a network error occurs
*/
public
ServerSocket createServerSocket(int
port,
String address) throws
Exception {
return new
ServerSocket(
port, 128,
InetAddress.
getByName(
address));
}
/**
* If socket argument is not null, returns it. If it is null,
* creates a socket and connects it to the specified remote host at the
* specified remote port. This socket is configured using the socket options
* established for this factory.
*
* @return the socket
* @param socket the existing socket, can be null
* @param host the server host
* @param port the server port
* @throws Exception if a network error occurs
*/
public
Socket createSocket(
Socket socket,
String host,
int
port) throws
Exception {
return
socket == null ? new
Socket(
host,
port)
:
socket;
}
/**
* Creates a socket and connects it to the specified remote host at the
* specified remote port. This socket is configured using the socket options
* established for this factory.
*
* @return the socket
* @param host the server host
* @param port the server port
* @throws Exception if a network error occurs
*/
public
Socket createSocket(
String host, int
port) throws
Exception {
return new
Socket(
host,
port);
}
/**
* Retrieves whether this factory produces secure sockets.
*
* @return true if this factory produces secure sockets
*/
public boolean
isSecure() {
return false;
}
// ------------------------ static utility methods -----------------------------
private static
HsqlSocketFactory getPlainImpl() throws
Exception {
synchronized (
HsqlSocketFactory.class) {
if (
plainImpl == null) {
plainImpl = new
HsqlSocketFactory();
}
}
return
plainImpl;
}
private static
HsqlSocketFactory getSSLImpl() throws
Exception {
synchronized (
HsqlSocketFactory.class) {
if (
sslImpl == null) {
sslImpl =
newFactory("org.hsqldb.server.HsqlSocketFactorySecure");
}
}
return
sslImpl;
}
/**
* Retrieves a new HsqlSocketFactory whose class
* is determined by the implClass argument. The basic contract here
* is that implementations constructed by this method should return
* true upon calling isSecure() iff they actually create secure sockets.
* There is no way to guarantee this directly here, so it is simply
* trusted that an implementation is secure if it returns true
* for calls to isSecure();
*
* @return a new secure socket factory
* @param implClass the fully qualified name of the desired
* class to construct
* @throws Exception if a new secure socket factory cannot
* be constructed
*/
private static
HsqlSocketFactory newFactory(
String implClass)
throws
Exception {
Class clazz;
Constructor ctor;
Class[]
ctorParm;
Object[]
ctorArg;
Object factory;
clazz =
Class.
forName(
implClass);
ctorParm = new
Class[0];
// protected constructor
ctor =
clazz.
getDeclaredConstructor(
ctorParm);
ctorArg = new
Object[0];
try {
factory =
ctor.
newInstance(
ctorArg);
} catch (
InvocationTargetException e) {
Throwable t =
e.
getTargetException();
throw (
t instanceof
Exception) ? ((
Exception)
t)
: new
RuntimeException(
t.
toString());
}
return (
HsqlSocketFactory)
factory;
}
// --
}