svn commit: r1393349 - /sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Objects.java
Author: desruisseaux Date: Wed Oct 3 08:39:49 2012 New Revision: 1393349 URL: http://svn.apache.org/viewvc?rev=1393349view=rev Log: Added an utility methods required by WeakHashSet. Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Objects.java Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Objects.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Objects.java?rev=1393349r1=1393348r2=1393349view=diff == --- sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Objects.java (original) +++ sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Objects.java Wed Oct 3 08:39:49 2012 @@ -16,6 +16,8 @@ */ package org.apache.sis.internal.util; +import java.util.Arrays; + /** * Place holder for {@link java.util.Objects}. This class will be deleted when we will be allowed @@ -46,13 +48,113 @@ public final class Objects { } /** - * See JDK7 javadoc. + * Convenience method for testing two objects for equality. One or both objects may be null. + * This method do strongnot/strong iterates recursively in array elements. If array needs + * to be compared, use one of {@link Arrays} method or {@link #deepEquals deepEquals} instead. + * p + * bNote on assertions:/b There is no way to ensure at compile time that this method + * is not invoked with array arguments, while doing so would usually be a program error. + * Performing a systematic argument check would impose a useless overhead for correctly + * implemented {@link Object#equals} methods. As a compromise we perform this check at runtime + * only if assertions are enabled. Using assertions for argument check in a public API is + * usually a deprecated practice, but this particular method is for internal use only. + * p + * strongWARNING: This method will be removed when SIS will switch to JDK7. + * This method will be replaced by the new {@code java.util.Objects.equals} method. + * Developers who are already on JDK7 should use that JDK method instead./strong * * @param o1 First object to compare. * @param o2 Second object to compare. * @return {@code true} if both objects are equal. + * @throws AssertionError If assertions are enabled and at least one argument is an array. */ public static boolean equals(final Object o1, final Object o2) { +assert o1 == null || !o1.getClass().isArray() : o1; +assert o2 == null || !o2.getClass().isArray() : o2; return (o1 == o2) || (o1 != null o1.equals(o2)); } + +/** + * Convenience method for testing two objects for equality. One or both objects may be null. + * If both are non-null and are arrays, then every array elements will be compared. + * p + * This method may be useful when the objects may or may not be array. If they are known + * to be arrays, consider using {@link Arrays#deepEquals(Object[],Object[])} or one of its + * primitive counter-part instead. + * p + * strongRules for choosing an {@code equals} or {@code deepEquals} method/strong + * ul + * liIf emboth/em objects are declared as {@code Object[]} (not anything else like + * {@code String[]}), consider using {@link Arrays#deepEquals(Object[],Object[])} except + * if it is known that the array elements can never be other arrays./li + * + * liOtherwise if both objects are arrays (e.g. {@code Expression[]}, {@code String[]}, + * {@code int[]}, ietc./i), use {@link Arrays#equals(Object[],Object[])}. This + * rule is applicable to arrays of primitive type too, since {@code Arrays.equals} is + * overridden with primitive counter-parts./li + * + * liOtherwise if at least one object is anything else than {@code Object} (e.g. + * {@code String}, {@code Expression}, ietc./i), use {@link #equals(Object,Object)}. + * Using this {@code deepEquals} method would be an overkill since there is no chance that + * {@code String} or {@code Expression} could be an array./li + * + * liOtherwise if emboth/em objects are declared exactly as {@code Object} type and + * it is known that they could be arrays, only then invoke this {@code deepEquals} method. + * In such case, make sure that the hash code is computed using {@link #deepHashCode(Object)} + * for consistency./li + * /ul + * p + * strongWARNING: This method will be removed when SIS will switch to JDK7. + * This method will be replaced by the new {@code java.util.Objects.deepEquals} method. + * Developers who are already on JDK7 should use that JDK method instead./strong + * + * @param object1 The first object to compare, or {@code null}. + * @param object2 The
svn commit: r1393350 - in /sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util: DaemonThread.java ReferenceQueueConsumer.java Threads.java
Author: desruisseaux Date: Wed Oct 3 08:40:55 2012 New Revision: 1393350 URL: http://svn.apache.org/viewvc?rev=1393350view=rev Log: Maintains a chained list of DaemonThreads to terminate when a OSGi bundle is desactivated. Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/DaemonThread.java sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/ReferenceQueueConsumer.java sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Threads.java Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/DaemonThread.java URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/DaemonThread.java?rev=1393350r1=1393349r2=1393350view=diff == --- sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/DaemonThread.java (original) +++ sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/DaemonThread.java Wed Oct 3 08:40:55 2012 @@ -16,15 +16,18 @@ */ package org.apache.sis.internal.util; +import java.util.List; +import java.util.ArrayList; + /** - * Base class for all daemon threads in the SIS library. This class provides a - * {@link #isKillRequested()} flag which shall be tested by the daemon threads. - * It is okay to test this flag only when catching {@link InterruptedException}, - * as below: + * Base class for all daemon threads in the SIS library. All {@code DaemonThread} instances are + * expected to run for the whole JVM lifetime (they are strongnot/strong executor threads). + * This class provides a {@link #isKillRequested()} flag which shall be tested by the subclasses. + * It is okay to test this flag only when catching {@link InterruptedException}, as below: * * {@preformat java - * while (someCondition) { + * while (true) { * try { * someObject.wait(); * } catch (InterruptedException e) { @@ -40,57 +43,118 @@ package org.apache.sis.internal.util; * @version 0.3 * @module */ -public class DaemonThread extends Thread { +abstract class DaemonThread extends Thread { /** - * Set to {@code true} when the {@link #kill()} method has been invoked. + * The previous element in a chain of {@code DaemonThread}s. We maintain a linked list of + * {@code DaemonThread} to be killed when {@link #killAll(DaemonThread)} will be invoked. + * We do not rely on the thread listed by the {@link Threads#RESOURCE_DISPOSERS} group + * because in an OSGi context, we need to handle separately the threads created by each + * SIS module. + */ +private final DaemonThread previous; + +/** + * Set to {@code true} when a kill is requested. */ private volatile boolean killRequested; /** * Creates a new daemon thread. This constructor sets the daemon flag to {@code true}. + * p + * We need to maintain a list of daemon threads created by each SIS module in order to + * kill them at shutdown time (not strictly necessary for pure JSEE applications, but + * required in OSGi environment). Each module using {@code DaemonThread} shall maintain + * its strongown/strong list (don't use the list of another module), like below: + * + * {@preformat java + * class MyInternalClass { + * static DaemonThread lastCreatedDaemon; + * } + * + * class AnOtherClass { + * private static final MyDaemonThread; + * static { + * synchronized (MyInternalClass.class) { + * MyInternalClass.lastCreatedDaemon = myDaemonThread = new MyDaemonThread( + * Threads.RESOURCE_DISPOSERS, MyThread, MyInternalClass.lastCreatedDaemon); + * } + * } + * } + * + * See {@link ReferenceQueueConsumer} for a real example. * * @param group The thread group. * @param name The thread name. + * @param lastCreatedDaemon The previous element in a chain of {@code DaemonThread}s, + *or {@code null}. Each SIS module shall maintain its own chain, if any. */ -protected DaemonThread(final ThreadGroup group, final String name) { +protected DaemonThread(final ThreadGroup group, final String name, final DaemonThread lastCreatedDaemon) { super(group, name); +previous = lastCreatedDaemon; setDaemon(true); } /** - * Returns {@code true} if {@link #kill()} has been invoked. + * Must be overridden by subclass for performing the actual work. + */ +@Override +public abstract void run(); + +/** + * Returns {@code true} if this daemon thread shall terminate. + * This happen at shutdown time. * - * @return {@code true} if {@link #kill()} has been invoked. + * @return {@code true} if this daemon thread shall terminate. */