Ranides Atterwim 4 lat temu
rodzic
commit
1f7b41326e

+ 48 - 0
assira.core/src/main/java/net/ranides/assira/concurrent/TaskInvoker.java

@@ -7,6 +7,9 @@ import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.atomic.AtomicReference;
 
+/**
+ * Utility methods scheduling tasks using global instance of java.util.Timer
+ */
 @UtilityClass
 public class TaskInvoker {
 
@@ -16,24 +19,69 @@ public class TaskInvoker {
 
     }
 
+    /**
+     * Executes action after "delay" milliseconds.
+     * Created TimerTask can be canceled.
+     *
+     * @param delay delay in ms
+     * @param action action
+     * @return TimerTask
+     */
     public static TimerTask later(long delay, Runnable action) {
         return later(delay, asTimerTask(action));
     }
 
+    /**
+     * Executes action after "delay" milliseconds.
+     * Returns TimerTask passed as an argument.
+     * Returned TimerTask can be canceled.
+     *
+     * @param delay delay
+     * @param task task
+     * @return TimerTask
+     */
     public static TimerTask later(long delay, TimerTask task) {
         Li.TIMER.schedule(task, delay);
         return task;
     }
 
+    /**
+     * Executes action periodically, in every "period" milliseconds, starting after "delay".
+     * Created TimerTask can be canceled.
+     *
+     * @param delay delay
+     * @param period period
+     * @param action action
+     * @return TimerTask
+     */
     public static TimerTask repeat(long delay, long period, Runnable action) {
         return repeat(delay, period, asTimerTask(action));
     }
 
+    /**
+     * Executes action periodically, in every "period" milliseconds, starting after "delay".
+     * Returns TimerTask passed as an argument.
+     * Returned TimerTask can be canceled.
+     *
+     * @param delay delay
+     * @param period period
+     * @param task task
+     * @return
+     */
     public static TimerTask repeat(long delay, long period, TimerTask task) {
         Li.TIMER.schedule(task, delay, period);
         return task;
     }
 
+    /**
+     * Executes action after "delay" milliseconds.
+     * If the same action is scheduled more than one time, it will cancel previous calls.
+     * Returned object can be used to cancel action.
+     *
+     * @param delay delay in ms
+     * @param action action
+     * @return Cancelable
+     */
     public static Cancelable lazy(long delay, Runnable action) {
         return new LazyCancelable(delay, action);
     }

+ 15 - 0
assira.core/src/main/java/net/ranides/assira/concurrent/TaskScheduler.java

@@ -12,6 +12,21 @@ import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Supplier;
 
+/**
+ * It is builder object designed to construct complex tasks.
+ *
+ * Constructed task can execute action or send event to specified router.
+ * You can specify router by reference or by name.
+ *
+ * Non-periodic tasks will call only "start" and "cancel" handlers.
+ *
+ * You can construct periodic task which will call "start", "finish", "cancel" and "interval" handlers.
+ *
+ * Periodic tasks can repeat specified number of times or infinitely.
+ *
+ * You can specificy router name as EventHandler.UI or EventHandler.UI_WAIT, then you can schedule action to be
+ * executed inside AWT thread (using SwingInvoeker)
+ */
 public class TaskScheduler {
 
     private EventRouter router;

+ 12 - 0
assira.core/src/main/java/net/ranides/assira/events/ActiveEvent.java

@@ -40,6 +40,8 @@ public class ActiveEvent implements Event {
 
     @Override
     public void dispatch(EventListener<?> listener) {
+        // please note that we keep track of ActiveEventListeners only
+        // we do not care about other listeners
         if(!(listener instanceof ActiveEventListener)) {
             return;
         }
@@ -51,6 +53,8 @@ public class ActiveEvent implements Event {
 
     @Override
     public void process(EventListener<?> listener) {
+        // please note that we keep track of ActiveEventListeners only
+        // we do not care about other listeners
         if(!(listener instanceof ActiveEventListener)) {
             return;
         }
@@ -72,6 +76,10 @@ public class ActiveEvent implements Event {
     /**
      * Returns true if this event was processed by some ActiveEventListener
      *
+     * Please note that this method returns "true" if processing did not started yet.
+     *
+     * It can be used only to detect, that processing is in progress.
+     *
      * @return bool
      */
     public boolean processed() {
@@ -83,6 +91,10 @@ public class ActiveEvent implements Event {
     /**
      * Waits until event is processed by some ActiveEventListener
      *
+     * Please note that this method returns immediately if processing did not started yet.
+     *
+     * It can be used only to wait, if processing is already in progress.
+     *
      * @return true if not canceled
      * @throws InterruptedException if terminated
      */

+ 11 - 0
assira.core/src/main/java/net/ranides/assira/events/ActiveEventListener.java

@@ -3,6 +3,11 @@ package net.ranides.assira.events;
 /**
  * Base class for all listeners capable of process ActiveEvents
  *
+ * It overrides "handleEvent" method and puts inside it additional logic marking event as processed.
+ *
+ * It should be abstract class with final "handleEvent", but unfortunatelly, Java supports only
+ * "functional interfaces", abstract classes can't be used as lambda expressions.
+ *
  * @param <T> T
  */
 public interface ActiveEventListener<T extends ActiveEvent> extends EventListener<T> {
@@ -19,5 +24,11 @@ public interface ActiveEventListener<T extends ActiveEvent> extends EventListene
 
     }
 
+    /**
+     * ActiveEventListener should implement action inside this method instead of
+     * "handleEvent" which is already implemented.
+     *
+     * @param event event
+     */
     void handleActiveEvent(T event);
 }

+ 25 - 2
assira.core/src/main/java/net/ranides/assira/events/Event.java

@@ -7,14 +7,37 @@
 package net.ranides.assira.events;
 
 /**
- * Podstawowy interfejs, który musi implementować każda klasa, która chce być
- * przesyłana jako zdarzenie przez {@link EventRouter}
+ * Base interface which must be implemented every class processed as event by EventListener or EventRouter.
+ *
+ * It is almost marker interface.
+ *
+ * Instance methods are by default no-ops, and there is no need to implement them.
+ *
+ * Only ActiveEvent implements them to keep track of processing.
+ * "dispatch" is executed by dispatcher, "process" is executed by ActiveEventListener at the end of processing.
+ *
  * @author ranides
  */
 public interface Event {
 
+    /**
+     * This method is called by EventDispatcher just before sending event into listener.
+     * If there is more than one listener insterested in event, method will be called for each of them.
+     *
+     * ActiveEvent class keeps track of all listeners started processing using this method.
+     *
+     * @param listener listener
+     */
     default void dispatch(EventListener<?> listener) { }
 
+    /**
+     * This method is called by ActiveEventListener at the end of "handleEvent".
+     * It is not called by other EventListener subclasses.
+     *
+     * ActiveEvent class keeps track of all listeners started and finished processing using this method.
+     *
+     * @param listener
+     */
     default void process(EventListener<?> listener) { }
 
 }

+ 40 - 2
assira.core/src/main/java/net/ranides/assira/events/EventBinding.java

@@ -9,24 +9,62 @@ package net.ranides.assira.events;
 import java.util.Objects;
 
 /**
+ * This class represents binding between event type and event listener.
+ *
+ * Event listeners can subscribe for specific types of events.
+ * Every subscription is represented by this class and can be retrieved from EventRouter
+ * using {@link EventRouter#getEventListeners()}
  *
  * @author ranides
+ * @param <T> T
  */
 public interface EventBinding<T extends Event> {
 
+    /**
+     * Type of accepted events. All subclasses will be accepted too.
+     *
+     * @return type
+     */
     Class<T> event();
 
+    /**
+     * EventListener processing received events.
+     *
+     * Plase note, that listener could be much more sophisticated, than ordinary function.
+     * It could be for example EventRouter or EventObserver.
+     *
+     * @return listener
+     */
     EventListener<? super T> listener();
-    
+
+    /**
+     * Creates new immutable object represeting specified binding.
+     *
+     * @param event event
+     * @param listener listener
+     * @param <TT> TT
+     * @return binding
+     */
     static <TT extends Event> EventBinding<TT> bind(Class<TT> event, EventListener<? super TT> listener) {
         return new Immutable<>(event, listener);
     }
-    
+
+    /**
+     * Default immutable implementation of EventBinding.
+     *
+     * @param <TT> TT
+     */
     final class Immutable<TT extends Event> implements EventBinding<TT> {
 
         private final Class<TT> event;
         private final EventListener<? super TT> listener;
 
+        /**
+         * Creates new immutable object represeting specified binding.
+         *
+         * @param event event
+         * @param listener listener
+         */
         public Immutable(Class<TT> event, EventListener<? super TT> listener) {
             this.event = event;
             this.listener = listener;

+ 3 - 0
assira.core/src/main/java/net/ranides/assira/events/EventRouter.java

@@ -58,6 +58,9 @@ public interface EventRouter extends EventListener<Event> {
     
     int getEventListenersCount();
 
+    @Override
+    void handleEvent(Event event);
+
     /**
      * Sygnalizuje podane zdarzenie rozsyłając komunikat do wszystkich obserwatorów.
      * Jeśli rozesłanie komunikatu nie jest możliwe, zwraca {@code false}.

+ 1 - 1
assira.core/src/main/java/net/ranides/assira/functional/special/LazyFunction.java

@@ -11,7 +11,7 @@ import java.util.function.Supplier;
  *
  * It is implementation dependent how aggressively LazyFunction tries to avoid calls.
  * Some LazyFunctions guarantee to not call more than once at all. Some others prefer to
- * avoid locking and could execute function more than once in different threads.
+ * avoid locking and could execute Supplier more than once in different threads.
  *
  * @param <T> T
  */

+ 143 - 22
assira.core/src/main/java/net/ranides/assira/generic/CompareUtils.java

@@ -11,30 +11,31 @@ import java.util.Comparator;
 import java.util.Map;
 import java.util.Objects;
 import java.util.function.Predicate;
-import java.util.function.Supplier;
 
+import lombok.experimental.UtilityClass;
 import net.ranides.assira.collection.IntComparator;
 import net.ranides.assira.collection.maps.WeakIdentMap;
-import net.ranides.assira.functional.FunctionUtils;
-import net.ranides.assira.functional.Functions;
-import net.ranides.assira.reflection.*;
 import net.ranides.assira.text.LexicalCast;
 
 
+/**
+ * Static methods for comparing objects, comparisons are null-safe.
+ */
 @SuppressWarnings({
     "PMD.ShortVar", 
     "PMD.ShortMethodName"
 })
-public final class CompareUtils {
+@UtilityClass
+public class CompareUtils {
 
     @SuppressWarnings({"rawtypes"})
-    private static final Comparator AUTO_COMPARATOR = new NComparator();
-
-    private CompareUtils() { }
+    private static final Comparator AUTO_COMPARATOR = new NaturalComparator();
 
     /**
      * Compares passed arguments usig Object#equals method.
-     * <div class="message-note">{@code null} safe method</div>
+     *
+     * Method is null-safe.
+     *
      * @param a a
      * @param b b
      * @return bool
@@ -47,6 +48,9 @@ public final class CompareUtils {
     /**
      * If both arguments are numbers ({@code instanceof Number}) then compares
      * with specified precision. Use standard comparison otherwise.
+     *
+     * Method is null-safe.
+     *
      * @param a a
      * @param b b
      * @param precision precision
@@ -62,6 +66,8 @@ public final class CompareUtils {
     
     /**
      * Compares numbers with specified precision.
+     * Method is null-safe.
+     *
      * @param a a
      * @param b b
      * @param precision precision
@@ -70,16 +76,44 @@ public final class CompareUtils {
     public static boolean equals(Number a, Number b, double precision) {
         return (null==a) ? (null==b) : (null!=b) && (Math.abs(a.doubleValue() - b.doubleValue()) <= precision);
     }
-    
+
+    /**
+     * Compares two values using natural comparator.
+     *
+     * Method is null-safe.
+     *
+     * @param value1 value1
+     * @param value2 value2
+     * @param <T> T
+     * @return int
+     */
     @SuppressWarnings("unchecked")
     public static <T> int cmp(T value1, T value2) {
         return AUTO_COMPARATOR.compare(value1, value2);
     }
-    
+
+    /**
+     * Compares two integer values.
+     *
+     * @param value1 value1
+     * @param value2 value2
+     * @return int
+     */
     public static int cmp(int value1, int value2) {
         return value1 - value2;
     }
-    
+
+    /**
+     * Compares two values using provided comparator.
+     * Comparator is optional.
+     * Method is null-safe only if provided comparator supports null values.
+     *
+     * @param comparator comparator
+     * @param value1 value1
+     * @param value2 value2
+     * @param <T> T
+     * @return int
+     */
     public static <T> int cmp(Comparator<? super T> comparator, T value1, T value2) {
         if(null != comparator ) {
             return comparator.compare(value1, value2);
@@ -87,7 +121,16 @@ public final class CompareUtils {
             return cmp(value1, value2);
         }
     }
-    
+
+    /**
+     * Compares two values using provided comparator.
+     * Comparator is optional.
+     *
+     * @param comparator comparator
+     * @param value1 value1
+     * @param value2 value2
+     * @return int
+     */
     public static int cmp(IntComparator comparator, int value1, int value2) {
         if(null != comparator ) {
             return comparator.compare(value1, value2);
@@ -96,7 +139,19 @@ public final class CompareUtils {
         }
         
     }
-    
+
+    /**
+     * Returns lower non-null value.
+     * Uses provided comparator for comparing objects.
+     *
+     * Method is null-safe.
+     *
+     * @param comparator comparator
+     * @param value1 value1
+     * @param value2 value2
+     * @param <T> T
+     * @return value
+     */
     public static <T> T lower(Comparator<? super T> comparator, T value1, T value2) {
         if(null == value1) {
             return value2;
@@ -106,11 +161,32 @@ public final class CompareUtils {
         }
         return cmp(comparator, value1, value2) < 0 ? value1 : value2;
     }
-    
+
+    /**
+     * Returns lower int value.
+     * Uses provided comparator for comparing objects.
+     *
+     * @param comparator comparator
+     * @param value1 value1
+     * @param value2 value2
+     * @return value
+     */
     public static int lower(IntComparator comparator, int value1, int value2) {
         return cmp(comparator, value1, value2) < 0 ? value1 : value2;
     }
-    
+
+    /**
+     * Returns higher non-null value.
+     * Uses provided comparator for comparing objects.
+     *
+     * Method is null-safe.
+     *
+     * @param comparator comparator
+     * @param value1 value1
+     * @param value2 value2
+     * @param <T> T
+     * @return value
+     */
     public static <T> T higher(Comparator<? super T> comparator, T value1, T value2) {
         if(null == value1) {
             return value2;
@@ -120,11 +196,29 @@ public final class CompareUtils {
         }
         return cmp(comparator, value1, value2) > 0 ? value1 : value2;
     }
-    
+
+    /**
+     * Returns higher int value.
+     * Uses provided comparator for comparing objects.
+     *
+     * @param comparator comparator
+     * @param value1 value1
+     * @param value2 value2
+     * @return value
+     */
     public static int higher(IntComparator comparator, int value1, int value2) {
         return cmp(comparator, value1, value2) > 0 ? value1 : value2;
     }
-    
+
+    /**
+     * Returns predicate which returns true if tested object is equal to provided one.
+     *
+     * Method is null-safe.
+     *
+     * @param a a
+     * @param <T> T
+     * @return predicate
+     */
     public static <T> Predicate<T> predicate(T a) {
         if(null == a) {
             return b -> b==null;
@@ -132,12 +226,29 @@ public final class CompareUtils {
             return b -> a.equals(b);
         }
     }
-    
+
+    /**
+     * Returns natural comparator.
+     * Comparator assumes that both objects are Comparable.
+     * It uses Comparable interface if objects are compatible.
+     * If not, it uses LexicalCast to normalize types.
+     *
+     * @param <T> T
+     * @return comparator
+     */
     @SuppressWarnings("unchecked")
     public static <T> Comparator<T> comparator() {
         return AUTO_COMPARATOR;
     }
 
+    /**
+     * Returns natural comparator for provided type.
+     * It could return optimized version for some types, for example for "int".
+     *
+     * @param type type
+     * @param <T> T
+     * @return comparator
+     */
     @SuppressWarnings("unchecked")
     public static <T> Comparator<T> comparator(Class<?> type) {
         if(int.class.equals(type) || Integer.class.equals(type)) {
@@ -147,6 +258,13 @@ public final class CompareUtils {
         }
     }
 
+    /**
+     * Returns reversed comparator
+     *
+     * @param comparator comparator
+     * @param <T> T
+     * @return comparator
+     */
     public static <T> Comparator<T> reversed(Comparator<T> comparator) {
         return comparator.reversed();
     }
@@ -162,12 +280,15 @@ public final class CompareUtils {
      * COMPARATOR.compare(a,b) = -COMPARATOR.compare(b,a) != 0
      *
      * This comparator is useful, if you want to store duplicates in standard TreeSets and TreeMaps
+     *
+     * @param <T> T
+     * @return comparator
      */
     public static <T> Comparator<T> identity() {
-        return new IComparator<>();
+        return new IdentComparator<>();
     }
 
-    private static final class IComparator<T> implements Comparator<T>, Serializable {
+    private static final class IdentComparator<T> implements Comparator<T>, Serializable {
 
         private final Map<T, Integer> map = new WeakIdentMap<>();
 
@@ -185,7 +306,7 @@ public final class CompareUtils {
         }
     }
     
-    private static final class NComparator implements Comparator<Comparable>, Serializable {
+    private static final class NaturalComparator implements Comparator<Comparable>, Serializable {
         
         private static final long serialVersionUID = 1L;
         

+ 5 - 0
assira.core/src/main/java/net/ranides/assira/generic/LazyReference.java

@@ -127,6 +127,11 @@ public final class LazyReference {
         return () -> cmp.apply(supplier);
     }
 
+    /**
+     * Initialization is lock-free. There is a chance of spurious "double initialization".
+     * @param <T> T
+     * @return function
+     */
     public static <T> LazyFunction<T> concurrent() {
         AtomicReference<T> ref = new AtomicReference<>(null);
         return (supplier) -> {