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);
+ }
}