--- /dev/null
+package org.simantics.history.rest;
+
+import java.util.EnumSet;
+import java.util.concurrent.Semaphore;
+
+import javax.servlet.DispatcherType;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.glassfish.jersey.jackson.JacksonFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.servlet.ServletContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HistoryRestServer {
+private static final Logger LOGGER = LoggerFactory.getLogger(HistoryRestServer.class);
+
+ private static HistoryRestServer INSTANCE = null;
+ private static Server server;
+ private static ServiceServerThread serverThread;
+
+ private static String allowOriginUrl = null;
+
+ private static String address = null;
+
+ private HistoryRestServer(int port) {
+ ResourceConfig config = new ResourceConfig();
+ // JSON serialization/deserialization
+ config.register(JacksonFeature.class);
+ // Actual API
+ config.register(HistoryRestApi.class);
+
+ ServletHolder holder = new ServletHolder(new ServletContainer(config));
+
+ server = new Server();
+ ServerConnector connector = new ServerConnector(server);
+ connector.setPort(port);
+
+ server.setConnectors(new Connector[] { connector });
+
+ ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
+ context.addServlet(holder, "/*");
+
+ if (allowOriginUrl != null){
+ org.eclipse.jetty.servlets.CrossOriginFilter cfilter = new org.eclipse.jetty.servlets.CrossOriginFilter();
+ FilterHolder filterHolder = new FilterHolder(cfilter);
+ filterHolder.setInitParameter(org.eclipse.jetty.servlets.CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, allowOriginUrl);
+ context.addFilter(filterHolder, "/*", EnumSet.allOf(DispatcherType.class));
+ }
+ }
+
+
+ private static class ServiceServerThread extends Thread {
+
+ Semaphore s;
+ @Override
+ public void run() {
+ try {
+ server.start();
+ address = server.getURI().toString()+"history/";
+ if (s != null)
+ s.release();
+ server.join();
+ } catch (Exception e) {
+ LOGGER.error("Could not start server ", e);
+ }
+ }
+
+ public void startAndWait() {
+ s = new Semaphore(0);
+ this.start();
+ try {
+ s.acquire();
+ } catch (InterruptedException e) {};
+ }
+ }
+
+ private static synchronized HistoryRestServer getInstance(int port) {
+ try {
+ if (INSTANCE == null) {
+ INSTANCE = new HistoryRestServer(port);
+ }
+ } catch (Exception e) {
+ LOGGER.error("Could not initialize SCL REST server", e);
+ }
+ return INSTANCE;
+ }
+
+ public static HistoryRestServer getRunningInstance() {
+ return INSTANCE;
+ }
+
+ public static void setAllowOrigin(String url) {
+ allowOriginUrl = url;
+ }
+
+ public static synchronized void startAsync(int port) throws Exception {
+ // Ensure that an instance is created
+ getInstance(port);
+ if (serverThread == null && server != null) {
+ serverThread = new ServiceServerThread();
+ serverThread.start();
+ }
+ }
+
+ public static synchronized void start(int port) throws Exception {
+ // Ensure that an instance is created
+ getInstance(port);
+ if (serverThread == null && server != null) {
+ serverThread = new ServiceServerThread();
+ serverThread.startAndWait();
+ }
+ }
+
+ public static synchronized void stop() throws Exception {
+ if (server != null)
+ server.stop();
+ serverThread = null;
+ INSTANCE = null;
+ address = null;
+
+ }
+
+ public static synchronized boolean running() {
+ return INSTANCE != null;
+ }
+
+ public static synchronized String address() {
+ return address;
+ }
+
+}