diff --git a/gemeinsamforschen/pom.xml b/gemeinsamforschen/pom.xml index 52c20b79f71aee59a5981002bb0cfffe254b46ba..28935787734589410a19ebda3dbf20e738c73da0 100644 --- a/gemeinsamforschen/pom.xml +++ b/gemeinsamforschen/pom.xml @@ -165,6 +165,20 @@ <version>1.3.4</version> </dependency> + <!-- websocket api --> + <dependency> + <groupId>javax.websocket</groupId> + <artifactId>javax.websocket-api</artifactId> + <version>1.1</version> + </dependency> + + <!-- gson --> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.8.5</version> + </dependency> + <dependency> <groupId>com.atlassian.commonmark</groupId> <artifactId>commonmark</artifactId> diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/AnnotationMessage.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/AnnotationMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..318aceb2ee29fb7db7c3890649e4950b7484f82e --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/AnnotationMessage.java @@ -0,0 +1,47 @@ +package unipotsdam.gf.modules.annotation.model; + +public class AnnotationMessage { + // variables + private String from; + private AnnotationMessageType type; + private String annotationId; + + public enum AnnotationMessageType { + GET, + DELETE + } + + // methods + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public AnnotationMessageType getType() { + return type; + } + + public void setType(AnnotationMessageType type) { + this.type = type; + } + + public String getAnnotationId() { + return annotationId; + } + + public void setAnnotationId(String annotationId) { + this.annotationId = annotationId; + } + + @Override + public String toString() { + return "AnnotationMessage{" + + "from='" + from + '\'' + + ", type=" + type + + ", annotationId='" + annotationId + '\'' + + '}'; + } +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationMessageDecoder.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationMessageDecoder.java new file mode 100644 index 0000000000000000000000000000000000000000..e4b2d83285499611edd4012ec85c8162effa22f5 --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationMessageDecoder.java @@ -0,0 +1,34 @@ +package unipotsdam.gf.modules.annotation.websocket; + +import com.google.gson.Gson; +import unipotsdam.gf.modules.annotation.model.AnnotationMessage; + +import javax.websocket.DecodeException; +import javax.websocket.Decoder; +import javax.websocket.EndpointConfig; + +public class AnnotationMessageDecoder implements Decoder.Text<AnnotationMessage> { + + public static Gson gson = new Gson(); + + @Override + public AnnotationMessage decode(String s) throws DecodeException { + AnnotationMessage annotationMessage = gson.fromJson(s, AnnotationMessage.class); + return annotationMessage; + } + + @Override + public boolean willDecode(String s) { + return (null != s); + } + + @Override + public void init(EndpointConfig endpointConfig) { + // todo + } + + @Override + public void destroy() { + // todo + } +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationMessageEncoder.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationMessageEncoder.java new file mode 100644 index 0000000000000000000000000000000000000000..161055827abf16881c241bdfe30bb59b466848b0 --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationMessageEncoder.java @@ -0,0 +1,29 @@ +package unipotsdam.gf.modules.annotation.websocket; + +import com.google.gson.Gson; +import unipotsdam.gf.modules.annotation.model.AnnotationMessage; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +public class AnnotationMessageEncoder implements Encoder.Text<AnnotationMessage> { + + private static Gson gson = new Gson(); + + @Override + public String encode(AnnotationMessage annotationMessage) throws EncodeException { + String json = gson.toJson(annotationMessage); + return json; + } + + @Override + public void init(EndpointConfig endpointConfig) { + // todo + } + + @Override + public void destroy() { + // todo + } +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationWebSocketEndpoint.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationWebSocketEndpoint.java new file mode 100644 index 0000000000000000000000000000000000000000..c36339797670a79c0afbff002a87102b7296433b --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationWebSocketEndpoint.java @@ -0,0 +1,64 @@ +package unipotsdam.gf.modules.annotation.websocket; + +import unipotsdam.gf.modules.annotation.model.AnnotationMessage; + +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.HashMap; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +@ServerEndpoint(value = "/ws/annotation/{targetId}", decoders = AnnotationMessageDecoder.class, encoders = AnnotationMessageEncoder.class) +public class AnnotationWebSocketEndpoint { + + private Session session; + private static final Set<AnnotationWebSocketEndpoint> endpoints = new CopyOnWriteArraySet<>(); + private static HashMap<String, String> targets = new HashMap<>(); + + @OnOpen + public void onOpen(Session session, @PathParam("targetId") String targetId) throws IOException { + // initialize session + this.session = session; + // save endpoint in set of endpoints + endpoints.add(this); + // save mapping of session and target id + targets.put(session.getId(), targetId); + + System.out.println(endpoints.toString()); + } + + @OnMessage + public void onMessage(Session session, AnnotationMessage annotationMessage) throws IOException, EncodeException { + annotationMessage.setFrom(targets.get(session.getId())); + broadcast(annotationMessage); + + } + + @OnClose + public void onClose(Session session) throws IOException { + endpoints.remove(this); + } + + @OnError + public void onError(Session session, Throwable throwable) { + // todo + } + + private void broadcast(AnnotationMessage annotationMessage) throws IOException, EncodeException { + endpoints.forEach(endpoint -> { + synchronized (endpoint) { + try { + if (targets.get(endpoint.session.getId()).equals(annotationMessage.getFrom())) { + endpoint.session.getBasicRemote().sendObject(annotationMessage); + } + } + catch (IOException | EncodeException e) { + e.printStackTrace(); + } + } + }); + } + +} diff --git a/gemeinsamforschen/src/main/webapp/assets/js/annotationScript.js b/gemeinsamforschen/src/main/webapp/assets/js/annotationScript.js index 5a18f3fde00b2d000e819670fc0f2fd0331a7245..0a4f4214503add3745e39a4ac7bf23934de5bcbb 100644 --- a/gemeinsamforschen/src/main/webapp/assets/js/annotationScript.js +++ b/gemeinsamforschen/src/main/webapp/assets/js/annotationScript.js @@ -12,6 +12,8 @@ var documentText, startCharacter, endCharacter; */ $(document).ready(function() { + connect("200"); + /** * Context menu handler */ diff --git a/gemeinsamforschen/src/main/webapp/assets/js/annotationWebsocket.js b/gemeinsamforschen/src/main/webapp/assets/js/annotationWebsocket.js new file mode 100644 index 0000000000000000000000000000000000000000..6b7410de06e9ddd050e07abe2e0ea7aba1f2c2ad --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/assets/js/annotationWebsocket.js @@ -0,0 +1,22 @@ +var ws; + +function connect(targetId) { + var host = document.location.host; + var pathname = document.location.pathname; + + ws = new WebSocket("ws://" + host + "/ws/annotation/" + targetId); + + ws.onmessage = function (e) { + var message = JSON.parse(e.data); + console.log(message.from) + }; +} + +function send(type, annotationId) { + var json = JSON.stringify({ + "type":type, + "annotationId":annotationId + }) + + ws.send(json); +} \ No newline at end of file diff --git a/gemeinsamforschen/src/main/webapp/pages/annotation-document.jsp b/gemeinsamforschen/src/main/webapp/pages/annotation-document.jsp index 36738f2a5114c65cbb42722c95910d842442156c..4d8fc1a2faf5fca6922f567b84d07a345c7d3aa9 100644 --- a/gemeinsamforschen/src/main/webapp/pages/annotation-document.jsp +++ b/gemeinsamforschen/src/main/webapp/pages/annotation-document.jsp @@ -34,6 +34,8 @@ <script src="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.js" type="text/javascript"></script> <!-- js - utility script --> <script src="../assets/js/utility.js"></script> + <!-- js - annotation websocket script --> + <script src="../assets/js/annotationWebsocket.js"></script> <!-- js - annotationScript --> <script src="../assets/js/annotationScript.js"></script>