Author: desruisseaux
Date: Tue Jun  4 10:17:48 2013
New Revision: 1489369

URL: http://svn.apache.org/r1489369
Log:
First attempt to provide a base class for DataStore implementation.
There is some redundancies between this class and WarningConsumer for now.
We will try to resolve those redundancies later.

Added:
    
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/AbstractDataStore.java
      - copied, changed from r1488774, 
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java
Modified:
    
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java

Modified: 
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java?rev=1489369&r1=1489368&r2=1489369&view=diff
==============================================================================
--- 
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java
 [UTF-8] Tue Jun  4 10:17:48 2013
@@ -52,7 +52,7 @@ public final class WarningConsumer<T> ex
      * The listeners, or {@code null} if none. This is a <cite>copy on 
write</cite> array:
      * no elements are modified once the array have been created.
      */
-    private volatile WarningListener<? super T>[] listeners;
+    private WarningListener<? super T>[] listeners;
 
     /**
      * Creates a new instance with initially no listener.
@@ -84,7 +84,10 @@ public final class WarningConsumer<T> ex
      */
     @Override
     void sendWarning(final LogRecord record) {
-        final WarningListener[] current = listeners;
+        final WarningListener[] current;
+        synchronized (this) {
+            current = listeners;
+        }
         if (current != null) {
             for (final WarningListener<? super T> listener : listeners) {
                 listener.warningOccured(source, record);
@@ -101,7 +104,9 @@ public final class WarningConsumer<T> ex
      * @param  listener The listener to add.
      * @throws IllegalArgumentException If the given listener is already 
registered in this data store.
      */
-    public void addWarningListener(final WarningListener<? super T> listener) 
throws IllegalArgumentException {
+    public synchronized void addWarningListener(final WarningListener<? super 
T> listener)
+            throws IllegalArgumentException
+    {
         ArgumentChecks.ensureNonNull("listener", listener);
         final WarningListener<? super T>[] current = listeners;
         final int length = (current != null) ? current.length : 0;
@@ -125,7 +130,9 @@ public final class WarningConsumer<T> ex
      * @param  listener The listener to remove.
      * @throws NoSuchElementException If the given listener is not registered 
in this data store.
      */
-    public void removeWarningListener(final WarningListener<? super T> 
listener) throws NoSuchElementException {
+    public synchronized void removeWarningListener(final WarningListener<? 
super T> listener)
+            throws NoSuchElementException
+    {
         final WarningListener<? super T>[] current = listeners;
         if (current != null) {
             for (int i=0; i<current.length; i++) {

Copied: 
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/AbstractDataStore.java
 (from r1488774, 
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java)
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/AbstractDataStore.java?p2=sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/AbstractDataStore.java&p1=sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java&r1=1488774&r2=1489369&rev=1489369&view=diff
==============================================================================
--- 
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/AbstractDataStore.java
 [UTF-8] Tue Jun  4 10:17:48 2013
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.internal.storage;
+package org.apache.sis.storage;
 
 import java.util.Locale;
 import java.util.logging.Logger;
@@ -22,77 +22,60 @@ import java.util.logging.LogRecord;
 import java.util.NoSuchElementException;
 import org.apache.sis.util.Localized;
 import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.logging.WarningListener;
 
 
 /**
- * The leaf of a chain of {@link WarningProducer}, which hold the list of 
{@link WarningListener}s to notify.
- *
- * @param <T> The type of the object declared as warnings emitter.
+ * Skeleton implementation of {@link DataStore}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
  * @version 0.3
  * @module
  */
-public final class WarningConsumer<T> extends WarningProducer {
+public abstract class AbstractDataStore implements DataStore, Localized {
     /**
-     * The declared source of warnings. This is not necessarily the real 
source,
-     * but this is the source that we declare in public API.
-     */
-    private final T source;
-
-    /**
-     * Where to log the warnings when there is no registered listener.
+     * The locale to use for formatting warnings.
+     *
+     * @see #getLocale()
+     * @see #setLocale(Locale)
      */
-    private final Logger logger;
+    private Locale locale;
 
     /**
      * The listeners, or {@code null} if none. This is a <cite>copy on 
write</cite> array:
      * no elements are modified once the array have been created.
      */
-    private volatile WarningListener<? super T>[] listeners;
+    private WarningListener<? super DataStore>[] listeners;
 
     /**
      * Creates a new instance with initially no listener.
-     * Warnings will be logger to the given logger, unless at least one 
listener is registered.
-     *
-     * @param source The declared source of warnings. This is not necessarily 
the real source,
-     *               but this is the source that we declare in public API.
-     * @param logger Where to log the warnings when there is no registered 
listener.
      */
-    public WarningConsumer(final T source, final Logger logger) {
-        super(null);
-        this.source = source;
-        this.logger = logger;
+    public AbstractDataStore() {
+        locale = Locale.getDefault(Locale.Category.DISPLAY);
     }
 
     /**
-     * The locale to use for formatting warning messages, or {@code null} for 
the default locale.
-     * This method returns the {@link #source} locale if it implements the 
{@link Localized} interface,
-     * or {@code null} otherwise.
+     * The locale to use for formatting warnings and other messages. This 
locale if for user interfaces
+     * only - it has no effect on the data to be read or written from/to the 
data store.
+     *
+     * <p>The default value is the {@linkplain Locale#getDefault() system 
default locale}.</p>
      */
     @Override
-    public Locale getLocale() {
-        return (source instanceof Localized) ? ((Localized) 
source).getLocale() : null;
+    public synchronized Locale getLocale() {
+        return locale;
     }
 
     /**
-     * Invoked when a new warning has been emitted. This method notifies the 
listeners if any,
-     * or log the warning otherwise.
+     * Sets the locale to use for formatting warnings and other messages.
+     *
+     * @param locale The new locale to use.
      */
-    @Override
-    void sendWarning(final LogRecord record) {
-        final WarningListener[] current = listeners;
-        if (current != null) {
-            for (final WarningListener<? super T> listener : listeners) {
-                listener.warningOccured(source, record);
-            }
-        } else {
-            record.setLoggerName(logger.getName());
-            logger.log(record);
-        }
+    public synchronized void setLocale(final Locale locale) {
+        ArgumentChecks.ensureNonNull("locale", locale);
+        this.locale = locale;
     }
 
     /**
@@ -101,15 +84,18 @@ public final class WarningConsumer<T> ex
      * @param  listener The listener to add.
      * @throws IllegalArgumentException If the given listener is already 
registered in this data store.
      */
-    public void addWarningListener(final WarningListener<? super T> listener) 
throws IllegalArgumentException {
+    @Override
+    public synchronized void addWarningListener(final WarningListener<? super 
DataStore> listener)
+            throws IllegalArgumentException
+    {
         ArgumentChecks.ensureNonNull("listener", listener);
-        final WarningListener<? super T>[] current = listeners;
+        final WarningListener<? super DataStore>[] current = listeners;
         final int length = (current != null) ? current.length : 0;
 
         @SuppressWarnings({"unchecked", "rawtypes"}) // Generic array creation.
-        final WarningListener<? super T>[] copy = new WarningListener[length + 
1];
+        final WarningListener<? super DataStore>[] copy = new 
WarningListener[length + 1];
         for (int i=0; i<length; i++) {
-            final WarningListener<? super T> c = current[i];
+            final WarningListener<? super DataStore> c = current[i];
             if (c == listener) {
                 throw new 
IllegalArgumentException(Errors.format(Errors.Keys.ElementAlreadyPresent_1, 
listener));
             }
@@ -125,8 +111,11 @@ public final class WarningConsumer<T> ex
      * @param  listener The listener to remove.
      * @throws NoSuchElementException If the given listener is not registered 
in this data store.
      */
-    public void removeWarningListener(final WarningListener<? super T> 
listener) throws NoSuchElementException {
-        final WarningListener<? super T>[] current = listeners;
+    @Override
+    public synchronized void removeWarningListener(final WarningListener<? 
super DataStore> listener)
+            throws NoSuchElementException
+    {
+        final WarningListener<? super DataStore>[] current = listeners;
         if (current != null) {
             for (int i=0; i<current.length; i++) {
                 if (current[i] == listener) {
@@ -134,7 +123,7 @@ public final class WarningConsumer<T> ex
                         listeners = null;
                     } else {
                         @SuppressWarnings({"unchecked", "rawtypes"}) // 
Generic array creation.
-                        final WarningListener<? super T>[] copy = new 
WarningListener[current.length - 1];
+                        final WarningListener<? super DataStore>[] copy = new 
WarningListener[current.length - 1];
                         System.arraycopy(current, 0, copy, 0, i);
                         System.arraycopy(current, i+1, copy, i, copy.length - 
i);
                         listeners = copy;
@@ -145,4 +134,47 @@ public final class WarningConsumer<T> ex
         }
         throw new 
NoSuchElementException(Errors.format(Errors.Keys.NoSuchElement_1, listener));
     }
+
+    /**
+     * Invoked when a new warning has been emitted.
+     * The default implementation makes the following choice:
+     *
+     * <ul>
+     *   <li>If at least one warning listener has been {@linkplain 
#addWarningListener(WarningListener) registered},
+     *       then this method notifies all listeners and the log record is 
<strong>not</strong> logged.</li>
+     *   <li>Otherwise this method logs the given record to the logger 
returned by {@link #getLogger()}</li>
+     * </ul>
+     *
+     * @param warning The warning message together with programmatic 
information.
+     *
+     * @see WarningListener#warningOccured(Object, LogRecord)
+     */
+    protected void fireWarningOccurred(final LogRecord warning) {
+        final WarningListener[] current;
+        synchronized (this) {
+            current = listeners;
+        }
+        if (current != null) {
+            for (final WarningListener<? super DataStore> listener : 
listeners) {
+                listener.warningOccured(this, warning);
+            }
+        } else {
+            final Logger logger = getLogger();
+            warning.setLoggerName(logger.getName());
+            logger.log(warning);
+        }
+    }
+
+    /**
+     * Returns the logger where to send warnings when there is registered 
warning listeners.
+     * This logger may also be used for other purpose like configuration or 
debugging information.
+     *
+     * <p>The default implementation returns the {@code 
"org.apache.sis.storage"} logger.
+     * Subclasses should override for specifying a logger in their own 
namespace.</p>
+     *
+     * @return The logger where to send warnings and other messages produced 
by this data store.
+     */
+    protected Logger getLogger() {
+        return Logging.getLogger(DataStore.class);
+    }
 }


Reply via email to