/* Websocket Smartcard Signer Copyright (C) 2017 Damiano Falcioni ([email protected]) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ package df.sign.server; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import org.glassfish.tyrus.server.Server; public class WebSocketServer extends Thread { public final static int defaultPort = 8765; private Server server = null; private int port = -1; private boolean isStarted = false; private boolean isTerminated = false; private boolean terminate = false; private final Object terminate_lock = new Object(); private final Object isTerminated_lock = new Object(); private final Object isStarted_lock = new Object(); private ActionListener statusChangelistener = null; public WebSocketServer(int port){ this.port = port; server = new Server("0.0.0.0", this.port, "/websockets", null, WebSocketService.class); } public void onStatusChanged(ActionListener listener){ statusChangelistener = listener; } public boolean isStarted(){ synchronized (isStarted_lock) { return isStarted; } } public boolean isTerminated(){ synchronized (isTerminated_lock) { return isTerminated; } } public boolean isTerminating(){ synchronized (terminate_lock) { return terminate; } } public int getPort(){ return port; } @Override public void run() { isStarted = false; isTerminated = false; terminate = false; try { server.start(); if(statusChangelistener!=null) statusChangelistener.actionPerformed(new ActionEvent(this, 0, "started")); } catch (Exception e) { e.printStackTrace(); terminate = true; } synchronized (isStarted_lock) { isStarted = true; isStarted_lock.notifyAll(); } synchronized (terminate_lock) { while(!terminate){ try { terminate_lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); break; } } } server.stop(); if(statusChangelistener!=null) statusChangelistener.actionPerformed(new ActionEvent(this, 1, "terminated")); synchronized (isTerminated_lock) { isTerminated = true; isTerminated_lock.notifyAll(); } } public void waitTermination(){ synchronized (isTerminated_lock) { while(!isTerminated){ try { isTerminated_lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); break; } } } } public void waitStart(){ synchronized (isStarted_lock) { while(!isStarted){ try { isStarted_lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); break; } } } } public void serverThreadStart(){ this.start(); } public void terminate(){ terminate(0); } public void terminate(int afterSeconds) { if(afterSeconds!=0){ try { sleep(afterSeconds*1000); } catch (InterruptedException e) { e.printStackTrace(); } } synchronized (terminate_lock) { terminate = true; terminate_lock.notifyAll(); // Unblocks thread } } }