Beispiel #1
0
 public static UUID convert16to32(UUID uuid) throws Exception {
   byte b[] = uuid.toByteArray();
   if (b.length != 2) throw new Exception("Not a 16-bits UUID!");
   UUID retour = new UUID();
   retour.uuidBytes = new byte[] {0, 0, 0, 0};
   for (int i = 2; i < 4; i++) retour.uuidBytes[i] += b[i - 2];
   retour.uuidLong = uuid.uuidLong;
   retour.uuidString = null;
   return retour;
 }
Beispiel #2
0
 public static UUID convert32to128(UUID uuid) {
   byte[] b = uuid.toByteArray();
   UUID retour = new UUID(b);
   if (b.length == 16) return retour;
   retour.uuidBytes = new byte[16];
   System.arraycopy(getBaseUUIDAsBytes(), 0, retour.uuidBytes, 0, 16);
   retour.uuidString = "";
   retour.uuidLong = 0;
   int decal = b.length == 2 ? 2 : 0;
   for (int i = 0; i < b.length; i++) {
     retour.uuidBytes[i + decal] += b[i];
   }
   return retour;
 }
Beispiel #3
0
/**
 * EventBus that handles normal Events (local) and RemoteEvents
 *
 * @author Mark Donszelmann
 */
public class RemoteEventBus extends SimpleEventBus {

  //	private Logger log = LoggerFactory.getLogger(getClass().getName());

  private static final boolean DEBUG = false;

  protected static <H> void dispatchEvent(RemoteEvent<H> event, H handler) {
    event.dispatch(handler);
  }

  protected static void setSourceUuidOfEvent(RemoteEvent<?> event, int uuid) {
    event.setSourceUUID(uuid);
  }

  protected static void setEventBusUuidOfEvent(RemoteEvent<?> event, long eventBusUUID) {
    event.setEventBusUUID(eventBusUUID);
  }

  private interface Command {
    void execute();
  }

  private Long uuid = UUID.uuidLong(8);

  private int firingDepth = 0;

  private List<Command> deferredDeltas;

  private final Map<RemoteEvent.Type<?>, Map<Integer, List<?>>> map =
      new HashMap<RemoteEvent.Type<?>, Map<Integer, List<?>>>();

  public RemoteEventBus() {}

  public Long getUUID() {
    return uuid;
  }

  public <H> HandlerRegistration addHandler(RemoteEvent.Type<H> type, H handler) {
    return doAdd(type, 0, handler);
  }

  public <H> HandlerRegistration addHandlerToSource(
      final RemoteEvent.Type<H> type, int uuid, final H handler) {
    if (uuid == 0) {
      throw new NullPointerException("Cannot add a handler with a 0 uuid");
    }

    return doAdd(type, uuid, handler);
  }

  public void fireEvent(RemoteEvent<?> event) {
    if (DEBUG) {
      //			log.info("Fire event " + event.getClass());
    }
    doFire(event, 0);
  }

  public void fireEventFromSource(RemoteEvent<?> event, int uuid) {
    if (uuid == 0) {
      throw new NullPointerException("Cannot fire from a 0 uuid");
    }
    if (DEBUG) {
      //			log.info("Fire event " + event.getClass() + " " + uuid);
    }
    doFire(event, uuid);
  }

  private void defer(Command command) {
    if (deferredDeltas == null) {
      deferredDeltas = new ArrayList<Command>();
    }
    deferredDeltas.add(command);
  }

  private <H> HandlerRegistration doAdd(
      final RemoteEvent.Type<H> type, final int uuid, final H handler) {
    if (type == null) {
      throw new NullPointerException("Cannot add a handler with a null type");
    }
    if (handler == null) {
      throw new NullPointerException("Cannot add a null handler");
    }

    if (firingDepth > 0) {
      enqueueAdd(type, uuid, handler);
    } else {
      doAddNow(type, uuid, handler);
    }

    return new HandlerRegistration() {
      public void removeHandler() {
        if (firingDepth > 0) {
          enqueueRemove(type, uuid, handler);
        } else {
          doRemoveNow(type, uuid, handler);
        }
      }
    };
  }

  private <H> void doAddNow(RemoteEvent.Type<H> type, int uuid, H handler) {
    List<H> l = ensureHandlerList(type, uuid);
    l.add(handler);
  }

  private <H> void doFire(RemoteEvent<H> event, int uuid) {
    if (event == null) {
      throw new NullPointerException("Cannot fire null event");
    }
    try {
      firingDepth++;

      if (uuid != 0) {
        setSourceUuidOfEvent(event, uuid);
      }

      setEventBusUuidOfEvent(event, getUUID());

      List<H> handlers = getDispatchList(event.getAssociatedType(), uuid);
      Set<Throwable> causes = null;

      ListIterator<H> it = handlers.listIterator();
      while (it.hasNext()) {
        H handler = it.next();

        try {
          dispatchEvent(event, handler);
        } catch (Throwable e) {
          if (causes == null) {
            causes = new HashSet<Throwable>();
          }
          causes.add(e);
        }
      }

      if (causes != null) {
        throw new UmbrellaException(causes);
      }
    } finally {
      firingDepth--;
      if (firingDepth == 0) {
        handleQueuedAddsAndRemoves();
      }
    }
  }

  private <H> void doRemoveNow(RemoteEvent.Type<H> type, int uuid, H handler) {
    List<H> l = getHandlerList(type, uuid);

    boolean removed = l.remove(handler);
    assert removed : "redundant remove call";
    if (removed && l.isEmpty()) {
      prune(type, uuid);
    }
  }

  private <H> void enqueueAdd(final RemoteEvent.Type<H> type, final int uuid, final H handler) {
    defer(
        new Command() {
          public void execute() {
            doAddNow(type, uuid, handler);
          }
        });
  }

  private <H> void enqueueRemove(final RemoteEvent.Type<H> type, final int uuid, final H handler) {
    defer(
        new Command() {
          public void execute() {
            doRemoveNow(type, uuid, handler);
          }
        });
  }

  private <H> List<H> ensureHandlerList(RemoteEvent.Type<H> type, int uuid) {
    Map<Integer, List<?>> sourceMap = map.get(type);
    if (sourceMap == null) {
      sourceMap = new HashMap<Integer, List<?>>();
      map.put(type, sourceMap);
    }

    // safe, we control the puts.
    @SuppressWarnings("unchecked")
    List<H> handlers = (List<H>) sourceMap.get(uuid);
    if (handlers == null) {
      handlers = new ArrayList<H>();
      sourceMap.put(uuid, handlers);
    }

    return handlers;
  }

  private <H> List<H> getDispatchList(RemoteEvent.Type<H> type, int uuid) {
    List<H> directHandlers = getHandlerList(type, uuid);
    if (uuid == 0) {
      return directHandlers;
    }

    List<H> globalHandlers = getHandlerList(type, 0);

    List<H> rtn = new ArrayList<H>(directHandlers);
    rtn.addAll(globalHandlers);
    return rtn;
  }

  private <H> List<H> getHandlerList(RemoteEvent.Type<H> type, int uuid) {
    Map<Integer, List<?>> sourceMap = map.get(type);
    if (sourceMap == null) {
      return Collections.emptyList();
    }

    // safe, we control the puts.
    @SuppressWarnings("unchecked")
    List<H> handlers = (List<H>) sourceMap.get(uuid);
    if (handlers == null) {
      return Collections.emptyList();
    }

    return handlers;
  }

  private void handleQueuedAddsAndRemoves() {
    if (deferredDeltas != null) {
      try {
        for (Command c : deferredDeltas) {
          c.execute();
        }
      } finally {
        deferredDeltas = null;
      }
    }
  }

  private void prune(RemoteEvent.Type<?> type, int uuid) {
    Map<Integer, List<?>> sourceMap = map.get(type);

    List<?> pruned = sourceMap.remove(uuid);

    assert pruned != null : "Can't prune what wasn't there";
    assert pruned.isEmpty() : "Pruned unempty list!";

    if (sourceMap.isEmpty()) {
      map.remove(type);
    }
  }

  @Override
  public String toString() {
    return "RemoteEventBus";
  }
}