org.h2.plus.H2Server Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of h2-plus Show documentation
Show all versions of h2-plus Show documentation
Extended implementation of H2
The newest version!
/*
* Copyright 2016-2017 the original author or authors.
*
* 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.
*/
package org.h2.plus;
import java.io.IOException;
import java.net.ServerSocket;
import java.nio.file.Files;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.h2.plus.exception.H2ServerException;
import org.h2.tools.Server;
import org.h2.util.StringUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.Synchronized;
/**
* H2 server
*/
public class H2Server {
/**
* Lock object
*/
private final Object lock = new Object();
/**
* {@link Server}
*/
private Server delegate;
/**
* Get running port
*
* @return running port
*/
public int getPort() {
return this.delegate.getPort();
}
/**
* Constructor
*
* @param delegate {@link Server}
*/
protected H2Server(@NonNull Server delegate) {
this.delegate = delegate;
}
/**
* Get {@link Builder}
*
* @return {@link Builder}
*/
public static Builder builder() {
return new Builder();
}
/**
* Start server
*
* @return {@link H2Server}
* @throws H2ServerException if failed to start
*/
@Synchronized("lock")
public H2Server start() throws H2ServerException {
if (this.isRunning()) {
throw new H2ServerException("Server is already running");
}
try {
this.delegate.start();
return this;
}
catch (SQLException e) {
throw new H2ServerException("Failed to start server", e);
}
}
/**
* Stop server
*
* @return {@link H2Server}
* @throws H2ServerException if failed to stop
*/
@Synchronized("lock")
public H2Server stop() throws H2ServerException {
if (!this.isRunning()) {
throw new H2ServerException("Server is not running");
}
this.delegate.stop();
return this;
}
/**
* Check server is running
*
* @return {@code true} if server is running
*/
@Synchronized("lock")
public boolean isRunning() {
return this.delegate.isRunning(false);
}
/**
* Builder
*/
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public static class Builder {
/**
* Port
*/
private int port;
/**
* Set port
*
* @param port port
* @return {@link Builder}
*/
public Builder port(int port) {
this.port = port;
return this;
}
/**
* Base directory
*/
private String baseDir;
/**
* Set base directory
*
* @param baseDir base directory
* @return {@link Builder}
*/
public Builder baseDir(String baseDir) {
this.baseDir = baseDir;
return this;
}
/**
* Allow others
*/
private boolean allowOthers;
/**
* Set allow others
*
* @param allowOthers allow others
* @return {@link Builder}
*/
public Builder allowOthers(boolean allowOthers) {
this.allowOthers = allowOthers;
return this;
}
/**
* Daemon
*/
private boolean daemon = true;
/**
* Set daemon
*
* @param daemon daemon
* @return {@link Builder}
*/
public Builder daemon(boolean daemon) {
this.daemon = daemon;
return this;
}
/**
* Build {@link H2Server}
*
* @return {@link H2Server}
* @throws H2ServerException if failed to build
*/
public H2Server build() throws H2ServerException {
// Detect parameters
int port = this.port;
if (port == 0) {
port = this.detectFreePort();
}
String baseDir = this.baseDir;
if (StringUtils.isNullOrEmpty(baseDir)) {
baseDir = this.detectBaseDir();
}
// Create arguments
List args = new ArrayList<>();
args.add("-tcp");
args.add("-tcpPort");
args.add(String.valueOf(port));
args.add("-baseDir");
args.add(baseDir);
if (this.allowOthers) {
args.add("-tcpAllowOthers");
}
if (this.daemon) {
args.add("-tcpDaemon");
}
// Create server
try {
return new H2Server(Server.createTcpServer(args.toArray(new String[0])));
}
catch (SQLException e) {
throw new H2ServerException("Failed to build H2 server", e);
}
}
/**
* Detect free port
*
* @return port
* @throws H2ServerException if failed to detect
*/
protected int detectFreePort() throws H2ServerException {
try (ServerSocket socket = new ServerSocket(0)) {
int port = socket.getLocalPort();
socket.setReuseAddress(true);
return port;
}
catch (IOException e) {
throw new H2ServerException("Failed to detect free port", e);
}
}
/**
* Detect base directory
*
* @return base directory
* @throws H2ServerException if failed to detect
*/
protected String detectBaseDir() throws H2ServerException {
try {
return Files.createTempDirectory("H2-").toString();
}
catch (IOException e) {
throw new H2ServerException("Failed to detect base directory", e);
}
}
}
}