/* * Copyright 2014 Goodow.com * * 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 com.goodow.realtime.channel.server.impl; import com.goodow.realtime.channel.Bus; import com.goodow.realtime.channel.BusHook; import com.goodow.realtime.channel.Message; import com.goodow.realtime.channel.State; import com.goodow.realtime.channel.impl.SimpleBus; import com.goodow.realtime.core.Handler; import com.goodow.realtime.core.Registration; import com.goodow.realtime.json.impl.JreJsonArray; import com.goodow.realtime.json.impl.JreJsonObject; import org.vertx.java.core.AsyncResult; import org.vertx.java.core.eventbus.EventBus; import org.vertx.java.core.json.JsonArray; import org.vertx.java.core.json.JsonObject; import java.util.logging.Level; import java.util.logging.Logger; public class VertxBus implements Bus { private static final Logger log = Logger.getLogger(VertxBus.class.getName()); @SuppressWarnings("unchecked") static Object unwrapMsg(Object vertxMessage) { if (vertxMessage instanceof JsonObject) { return new JreJsonObject(((JsonObject) vertxMessage).toMap()); } else if (vertxMessage instanceof JsonArray) { return new JreJsonArray(((JsonArray) vertxMessage).toList()); } else { return vertxMessage; } } static Object wrapMsg(Object realtimeMessage) { if (realtimeMessage instanceof JreJsonObject) { return new JsonObject(((JreJsonObject) realtimeMessage).toNative()); } else if (realtimeMessage instanceof JreJsonArray) { return new JsonArray(((JreJsonArray) realtimeMessage).toNative()); } else { return realtimeMessage; } } private final Bus localBus; private final EventBus eb; private State state; private BusHook hook; public VertxBus(EventBus eb) { this.eb = eb; state = State.OPEN; localBus = new SimpleBus(); } @Override public void close() { if (hook == null || hook.handlePreClose()) { state = State.CLOSING; localBus.close(); eb.close(new org.vertx.java.core.Handler<AsyncResult<Void>>() { @Override public void handle(AsyncResult<Void> ar) { if (ar.succeeded()) { state = State.CLOSED; if (hook != null) { hook.handlePostClose(); } } else { log.log(Level.SEVERE, "Failed to close EventBus", ar.cause()); } } }); } } @Override public State getReadyState() { return state; } @Override public String getSessionId() { return "vertx"; } @Override public VertxBus publish(String topic, Object msg) { if (hook == null || hook.handleSendOrPub(false, topic, msg, null)) { eb.publish(topic, wrapMsg(msg)); } return this; } @Override public Bus publishLocal(String topic, Object msg) { return localBus.publishLocal(topic, msg); } @SuppressWarnings("rawtypes") @Override public Registration subscribe(final String topic, final Handler<? extends Message> handler) { if (hook != null && !hook.handlePreSubscribe(topic, handler)) { return Registration.EMPTY; } final org.vertx.java.core.Handler<org.vertx.java.core.eventbus.Message> vertxHandler = wrapHandler(handler); eb.registerHandler(topic, vertxHandler, new org.vertx.java.core.Handler<AsyncResult<Void>>() { @Override public void handle(AsyncResult<Void> ar) { if (ar.failed()) { log.log(Level.SEVERE, "Failed to register handler on event bus", ar.cause()); } } }); return new Registration() { @Override public void unregister() { if (hook == null || hook.handleUnsubscribe(topic)) { eb.unregisterHandler(topic, vertxHandler, new org.vertx.java.core.Handler<AsyncResult<Void>>() { @Override public void handle(AsyncResult<Void> ar) { if (ar.failed()) { log.log(Level.SEVERE, "Failed to unregister handler on event bus", ar.cause()); } } }); } } }; } @SuppressWarnings("rawtypes") @Override public Registration subscribeLocal(final String topic, Handler<? extends Message> handler) { return localBus.subscribeLocal(topic, handler); } @Override public <T> VertxBus send(String topic, Object msg, final Handler<Message<T>> replyHandler) { if (hook == null || hook.handleSendOrPub(true, topic, msg, replyHandler)) { eb.send(topic, wrapMsg(msg), wrapHandler(replyHandler)); } return this; } @Override public <T> Bus sendLocal(String topic, Object msg, Handler<Message<T>> replyHandler) { return localBus.sendLocal(topic, msg, replyHandler); } @Override public VertxBus setHook(BusHook hook) { this.hook = hook; if (hook != null && state == State.OPEN) { hook.handleOpened(); } return this; } BusHook getHook() { return hook; } @SuppressWarnings("rawtypes") private org.vertx.java.core.Handler<org.vertx.java.core.eventbus.Message> wrapHandler( final Handler<? extends Message> handler) { return handler == null ? null : new org.vertx.java.core.Handler<org.vertx.java.core.eventbus.Message>() { @SuppressWarnings("unchecked") @Override public void handle(org.vertx.java.core.eventbus.Message message) { VertxMessage event = new VertxMessage(VertxBus.this, message); if (hook == null || hook.handleReceiveMessage(event)) { ((Handler<Message>) handler).handle(event); } } }; } }