All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bushe.swing.event.annotation.ProxyTopicSubscriber Maven / Gradle / Ivy

package org.bushe.swing.event.annotation;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.bushe.swing.event.EventService;
import org.bushe.swing.event.VetoTopicEventListener;

/** A class that subscribes to an EventService on behalf of another object.
 * This class is not used directly (though you could), but rather through the use of the
 * {@link @org.bushe.swing.event.annotation.EventTopicSubscriber}.  Advanced EventBus
 * users could use this class in Aspect-Oriented code.  Consider using the
 * {@link AnnotationProcessor} instead, it may suit your needs and be easier.*/
public class ProxyTopicSubscriber extends AbstractProxySubscriber
        implements org.bushe.swing.event.EventTopicSubscriber, VetoTopicEventListener {
   private String topic;

   /**
    * Creates a proxy.  This does not subscribe it.
    *
    * @param proxiedSubscriber the subscriber that the proxy will call when an event is published
    * @param subscriptionMethod the method the proxy will call, must have an Object as it's first and only parameter
    * @param referenceStrength if the subscription is weak, the reference from the proxy to the real subscriber should
    * be too
    * @param es the EventService we will be subscribed to, since we may need to unsubscribe when weak refs no longer
    * exist
    * @param topic the topic to subscribe to, used for unsubscription only
    * @param veto if this proxy is for a veto subscriber
    */
   public ProxyTopicSubscriber(Object proxiedSubscriber, Method subscriptionMethod, ReferenceStrength referenceStrength,
           EventService es, String topic, boolean veto) {
      this(proxiedSubscriber, subscriptionMethod, referenceStrength, 0, es, topic, veto);
   }

   /**
    * Creates a proxy.  This does not subscribe it.
    *
    * @param proxiedSubscriber the subscriber that the proxy will call when an event is published
    * @param subscriptionMethod the method the proxy will call, must have an Object as it's first and only parameter
    * @param referenceStrength if the subscription is weak, the reference from the proxy to the real subscriber should
    * be too
    * @param es the EventService we will be subscribed to, since we may need to unsubscribe when weak refs no longer
    * exist
    * @param topic the topic to subscribe to, used for unsubscription only
    * @param veto if this proxy is for a veto subscriber
    */
   public ProxyTopicSubscriber(Object proxiedSubscriber, Method subscriptionMethod, ReferenceStrength referenceStrength,
           int priority, EventService es, String topic, boolean veto) {
      super(proxiedSubscriber, subscriptionMethod, referenceStrength, priority, es, veto);
      this.topic = topic;
      if (topic == null) {
         throw new IllegalArgumentException("Proxies for topic subscribers require a non-null topic.");
      }
      Class[] params = subscriptionMethod.getParameterTypes();
      if (params == null || params.length != 2 || !String.class.equals(params[0]) || params[1].isPrimitive()) {
         throw new IllegalArgumentException("The subscriptionMethod must have the two parameters, the first one must be a String and the second a non-primitive (Object or derivative).");
      }
   }

   /**
    * Handles the event publication by pushing it to the real subscriber's subscription Method.
    *
    * @param topic the topic on which the object is being published
    * @param data The Object that is being published on the topic.
    */
   public void onEvent(String topic, Object data) {
      Object[] args = new Object[]{topic, data};
      Object obj = null;
      Method subscriptionMethod = null;
      try {
         obj = getProxiedSubscriber();
         if (obj == null) {
            return;
         }
         subscriptionMethod = getSubscriptionMethod();
         subscriptionMethod.invoke(obj, args);
      } catch (IllegalAccessException e) {
         String message = "IllegalAccessException when invoking annotated method from EventService publication.  Topic:" + topic + ", data:" + data + ", subscriber:" + getProxiedSubscriber() + ", subscription Method=" + getSubscriptionMethod();
         retryReflectiveCallUsingAccessibleObject(args, subscriptionMethod, obj, e, message);
      } catch (InvocationTargetException e) {
         throw new RuntimeException("InvocationTargetException when invoking annotated method from EventService publication.  Topic:" + topic + ", data:" + data + ", subscriber:" + getProxiedSubscriber() + ", subscription Method=" + getSubscriptionMethod(), e);
      }
   }


   public boolean shouldVeto(String topic, Object data) {
      Object[] args = new Object[]{topic, data};
      Object obj = null;
      Method subscriptionMethod = null;
      try {
         obj = getProxiedSubscriber();
         if (obj == null) {
            return false;
         }
         subscriptionMethod = getSubscriptionMethod();
         return Boolean.valueOf(subscriptionMethod.invoke(obj, args)+"");
      } catch (IllegalAccessException e) {
         String message = "IllegalAccessException when invoking annotated veto method from EventService publication.  Topic:" + topic + ", data:" + data + ", subscriber:" + getProxiedSubscriber() + ", subscription Method=" + getSubscriptionMethod();
         return retryReflectiveCallUsingAccessibleObject(args, subscriptionMethod, obj, e, message);
      } catch (InvocationTargetException e) {
         throw new RuntimeException("InvocationTargetException when invoking annotated veto method from EventService publication.  Topic:" + topic + ", data:" + data + ", subscriber:" + getProxiedSubscriber() + ", subscription Method=" + getSubscriptionMethod(), e);
      }
   }

   protected void unsubscribe(String topic) {
      if (veto) {
         getEventService().unsubscribeVetoListener(topic, this);
      } else {
         getEventService().unsubscribe(topic, this);
      }
   }

   @Override
   public boolean equals(Object obj) {
      if (obj instanceof ProxyTopicSubscriber) {
         if (!super.equals(obj)) {
            return false;
         }
         ProxyTopicSubscriber proxyTopicSubscriber = (ProxyTopicSubscriber) obj;
         if (topic.equals(proxyTopicSubscriber.topic)) {
            if (topic == null) {
               return false;
            } else {
               if (!topic.equals(proxyTopicSubscriber.topic)) {
                  return false;
               }
            }
         }
         return true;
      } else {
         return false;
      }
   }


   @Override
   public String toString() {
      return "ProxyTopicSubscriber{" +
              "topic='" + topic + '\'' +
              "veto='" + veto + '\'' +
              "realSubscriber=" + getProxiedSubscriber() +
              ", subscriptionMethod=" + getSubscriptionMethod() +
              ", referenceStrength=" + getReferenceStrength() +
              ", eventService=" + getEventService() +
              '}';
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy