org.jboss.aerogear.sync.server.wildfly.SyncEndpoint.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.aerogear.sync.server.wildfly.SyncEndpoint.java

Source

/**
 * JBoss, Home of Professional Open Source
 * Copyright Red Hat, Inc., and individual contributors.
 *
 * 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.jboss.aerogear.sync.server.wildfly;

import com.fasterxml.jackson.databind.JsonNode;

import java.util.Map;
import java.util.logging.Logger;
import javax.websocket.CloseReason;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.OnClose;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.jboss.aerogear.sync.Document;
import org.jboss.aerogear.sync.PatchMessage;
import org.jboss.aerogear.sync.diffmatchpatch.JsonMapper;
import org.jboss.aerogear.sync.jsonpatch.JsonPatchEdit;
import org.jboss.aerogear.sync.jsonpatch.server.JsonPatchServerSynchronizer;
import org.jboss.aerogear.sync.server.MessageType;
import org.jboss.aerogear.sync.server.ServerInMemoryDataStore;
import org.jboss.aerogear.sync.server.ServerSyncEngine;
import org.jboss.aerogear.sync.server.Subscriber;

@ServerEndpoint("/sync")
public class SyncEndpoint {

    private static final JsonPatchServerSynchronizer synchronizer = new JsonPatchServerSynchronizer();
    private static final ServerInMemoryDataStore<JsonNode, JsonPatchEdit> dataStore = new ServerInMemoryDataStore<JsonNode, JsonPatchEdit>();
    private static final ServerSyncEngine<JsonNode, JsonPatchEdit> syncEngine = new ServerSyncEngine<JsonNode, JsonPatchEdit>(
            synchronizer, dataStore);
    private static final String DOC_ADD = "DOC_ADD";
    private static final String WILDFLY_SUBSCRIBER = "WILDFLY_SUBSCRIBER";
    private static final Logger logger = Logger.getLogger(SyncEndpoint.class.getSimpleName());
    private static final String DOCUMENT_ID = "DOCUMENT_ID";

    @OnMessage
    public String onMessage(String message, Session webSocketSession) {
        final JsonNode json = JsonMapper.asJsonNode(message);

        switch (MessageType.from(json.get("msgType").asText())) {
        case ADD:
            final Document<JsonNode> doc = syncEngine.documentFromJson(json);
            final String clientId = json.get("clientId").asText();
            final PatchMessage<JsonPatchEdit> patchMessage = addSubscriber(doc, clientId, webSocketSession);
            webSocketSession.getUserProperties().put(DOC_ADD, true);
            return (patchMessage.asJson());

        case PATCH:
            final PatchMessage<JsonPatchEdit> clientPatchMessage = syncEngine.patchMessageFromJson(json.toString());
            checkForReconnect(clientPatchMessage.documentId(), clientPatchMessage.clientId(), webSocketSession);
            patch(clientPatchMessage);
            break;
        case DETACH:
            // detach the client from a specific document.
            break;
        case UNKNOWN:
            return "{\"result\": \"Unknown msgType '" + json.get("msgType").asText() + "'\"}";

        }

        return message;
    }

    @OnOpen
    public void onOpen(Session session) {
        logger.info("WebSocket opened: " + session.getId());
    }

    @OnClose
    public void onClose(CloseReason reason, Session webSocketSession) {
        logger.info("Closing a WebSocket due to " + reason.getReasonPhrase());
        WildflySubscriber subscriber = (WildflySubscriber) webSocketSession.getUserProperties()
                .get(WILDFLY_SUBSCRIBER);
        String documentId = (String) webSocketSession.getUserProperties().get(DOCUMENT_ID);
        syncEngine.removeSubscriber(subscriber, documentId);

    }

    private PatchMessage<JsonPatchEdit> addSubscriber(final Document<JsonNode> document, final String clientId,
            Session session) {
        final Subscriber<Session> subscriber = new WildflySubscriber(clientId, session);
        return syncEngine.addSubscriber(subscriber, document);
    }

    private void patch(final PatchMessage<JsonPatchEdit> patchMessage) {
        syncEngine.notifySubscribers(syncEngine.patch(patchMessage));
    }

    private void checkForReconnect(final String documentId, final String clientId, final Session session) {
        if (getOrDefault(session.getUserProperties(), Boolean.FALSE) == Boolean.TRUE) {
            return;
        }
        logger.info("Reconnected client [" + clientId + "]. Adding as listener.");

        final WildflySubscriber subscriber = new WildflySubscriber(clientId, session);
        syncEngine.connectSubscriber(subscriber, documentId);
    }

    private static Boolean getOrDefault(final Map<String, Object> properties, final Boolean defaultValue) {
        final Boolean value = (Boolean) properties.get(DOC_ADD);
        return value != null ? value : defaultValue;
    }

}