content: package org.lightfish.business.heartbeat.boundary;
  
  import java.io.IOException;
  import java.lang.reflect.Method;
  import java.util.Date;
  import java.util.List;
  import java.util.concurrent.CopyOnWriteArraySet;
  import javax.annotation.PostConstruct;
  import javax.ejb.ConcurrencyManagement;
  import javax.ejb.ConcurrencyManagementType;
  import javax.ejb.Singleton;
  import javax.enterprise.event.Observes;
  import javax.inject.Inject;
  import javax.json.Json;
  import javax.json.JsonArrayBuilder;
  import javax.json.JsonObject;
  import javax.json.JsonObjectBuilder;
  import javax.websocket.OnClose;
  import javax.websocket.OnOpen;
  import javax.websocket.RemoteEndpoint;
  import javax.websocket.Session;
  import javax.websocket.server.ServerEndpoint;
  import org.lightfish.business.heartbeat.control.Serializer;
  import org.lightfish.business.logging.Log;
  import org.lightfish.business.servermonitoring.boundary.Severity;
  import org.lightfish.business.servermonitoring.entity.Snapshot;
  
  /**
   * @author: adam-bien.com
   */
  @Singleton
  @ServerEndpoint("/snapshots/json/")
  @ConcurrencyManagement(ConcurrencyManagementType.BEAN)
  public class SnapshotsSocketJSON {
  
      @Inject
      Log LOG;
  
      @Inject
      Serializer serializer;
  
      private CopyOnWriteArraySet<Session> sessions;
  
      @PostConstruct
      public void init() {
          this.sessions = new CopyOnWriteArraySet<>();
      }
  
      @OnOpen
      public void onOpen(Session session) {
          this.sessions.add(session);
      }
  
      @OnClose
      public void onClose(Session session) {
          this.sessions.remove(session);
      }
  
      public void onNewSnapshot(@Observes @Severity(Severity.Level.HEARTBEAT) Snapshot snapshot) {
          LOG.info("SnapshotsSocketJson.oneNewSnapshot: " + snapshot.getId());
          for (Session session : sessions) {
              if (session != null && session.isOpen()) {
                  LOG.info("Sending: " + snapshot.getId() + " to " + session.getId());
                  final RemoteEndpoint.Basic remote = session.getBasicRemote();
                  try {
                      String json = snapshotToJson(snapshot).toString();
                      remote.sendText(json);
                      LOG.info("Sending Snapshot " + json);
                  } catch (IOException ex) {
                      LOG.error("Problem sending Snapshot", ex);
                  }
              }
          }
      }
  
      public JsonObject snapshotToJson(Snapshot snapshot) {
          JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
          objectBuilder.add("snapshot", toJson(snapshot));
          return objectBuilder.build();
      }
  
      public JsonObject toJson(Object object) {
          JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
          Method methods[] = object.getClass().getDeclaredMethods();
          try {
              for (int i = 0; i < methods.length; i++) {
                  String method = methods[i].getName();
                  if (method.startsWith("get")) {
                      Object result = methods[i].invoke(object);
                      String property = method.replaceFirst("get", "");
                      property = Character.toLowerCase(property.charAt(0)) + property.substring(1);
                      if (methods[i].getReturnType().equals(List.class)) {
                          List resultList = (List) result;
                          JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
                          for (Object entry : resultList) {
                              if (entry instanceof String) {
                                  arrayBuilder.add((String) entry);
                              } else {
                                  JsonObject toJson = toJson(entry);
                                  arrayBuilder.add(toJson);
                              }
                          }
                          objectBuilder.add(property, arrayBuilder.build());
                      } else // for nicer JSON message
                      if (result instanceof Double) {
                          objectBuilder.add(property, (double) result);
                      } else if (result instanceof Integer) {
                          objectBuilder.add(property, (int) result);
                      } else if (result instanceof Boolean) {
                          objectBuilder.add(property, (boolean) result);
                      } else if (result instanceof Long) {
                          objectBuilder.add(property, (long) result);
                      } else if (result instanceof Date) {
                          objectBuilder.add(property, ((Date) result).getTime());
                      } else {
                          objectBuilder.add(property, "" + result);
                      }
                  }
  
              }
              return objectBuilder.build();
          } catch (Exception e) {
              e.printStackTrace();
              return null;
          }
      }
  }
  