svn commit: r1393349 - /sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Objects.java

2012-10-03 Thread desruisseaux
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

2012-10-03 Thread desruisseaux
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.
  */