Author: desruisseaux
Date: Thu May 30 16:17:57 2013
New Revision: 1487913
URL: http://svn.apache.org/r1487913
Log:
Provides a WarningListener interface.
Added:
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java
(with props)
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java
(with props)
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningProducer.java
- copied, changed from r1487611,
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/WarningProducer.java
Removed:
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/WarningProducer.java
Modified:
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/ConformanceTest.java
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
Added:
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java?rev=1487913&view=auto
==============================================================================
---
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java
(added)
+++
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java
[UTF-8] Thu May 30 16:17:57 2013
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.util.logging;
+
+import java.util.EventListener;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+
+/**
+ * Intercepts non-fatal error messages logged by {@link
org.apache.sis.storage.DataStore} or other SIS objects.
+ * Warnings are encapsulated in {@link LogRecord} objects and logged at {@link
Level#WARNING} if the emitter does not
+ * have any registered any {@code WarningListener}. This listener allows
applications to intercept warning records for:
+ *
+ * <ul>
+ * <li>displaying the warning in a dialog or performing any other action
that the application may choose,</li>
+ * <li>reducing the amount of records to be logged.</li>
+ * </ul>
+ *
+ * The difference between using this listener or configuring the logging
{@link java.util.logging.Handler} is
+ * that listeners allow to handle the warnings on a per-{@code DataStore} (or
any other emitter) instance.
+ *
+ * @param <T> The type of the warnings emitter.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.3
+ * @version 0.3
+ * @module
+ *
+ * @see org.apache.sis.storage.DataStore#addWarningListener(WarningListener)
+ */
+public interface WarningListener<T> extends EventListener {
+ /**
+ * Reports the occurrence of a non-fatal error. The emitter process (often
a
+ * {@link org.apache.sis.storage.DataStore} in the midst of a reading
process)
+ * will continue following the call to this method.
+ *
+ * <p>The {@code LogRecord} provides the warning {@linkplain
LogRecord#getMessage() message} together with
+ * programmatic information like the {@linkplain
LogRecord#getSourceClassName() source class name} and
+ * {@linkplain LogRecord#getSourceMethodName() method name} where the
warning occurred. The log record
+ * may optionally contains the exception which has been {@linkplain
LogRecord#getThrown() thrown}.</p>
+ *
+ * <p>Applications may choose to ignore the warning, display a dialog or
take any other action they choose.
+ * Applications do not need to log the warning, since logging will be done
automatically if the emitter has
+ * no registered warning listeners.</p>
+ *
+ * @param source The object that emitted a warning.
+ * @param warning The warning message together with programmatic
information.
+ */
+ void warningOccured(T source, LogRecord warning);
+}
Propchange:
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified:
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1487913&r1=1487912&r2=1487913&view=diff
==============================================================================
---
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
[UTF-8] (original)
+++
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
[UTF-8] Thu May 30 16:17:57 2013
@@ -311,6 +311,11 @@ public final class Errors extends Indexe
public static final int NegativeArrayLength_1 = 78;
/**
+ * Element “{0}” has not been found.
+ */
+ public static final int NoSuchElement_1 = 96;
+
+ /**
* No property named “{0}” has been found in “{1}”.
*/
public static final int NoSuchProperty_2 = 73;
Modified:
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1487913&r1=1487912&r2=1487913&view=diff
==============================================================================
---
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] (original)
+++
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] Thu May 30 16:17:57 2013
@@ -88,6 +88,7 @@ NonTemporalUnit_1 = \u201c
NotANumber_1 = Argument \u2018{0}\u2019 shall not be NaN
(Not-a-Number).
NotAPrimitiveWrapper_1 = Class \u2018{0}\u2019 is not a primitive
type wrapper.
NotComparableClass_1 = Class \u2018{0}\u2019 is not a comparable.
+NoSuchElement_1 = Element \u201c{0}\u201d has not been found.
NoSuchProperty_2 = No property named \u201c{0}\u201d has been
found in \u201c{1}\u201d.
NoUnit = No unit of measurement has been specified.
NullArgument_1 = Argument \u2018{0}\u2019 shall not be null.
Modified:
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1487913&r1=1487912&r2=1487913&view=diff
==============================================================================
---
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] (original)
+++
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] Thu May 30 16:17:57 2013
@@ -78,6 +78,7 @@ NonTemporalUnit_1 = \u201c
NotANumber_1 = L\u2019argument \u2018{0}\u2019 ne doit pas
\u00eatre NaN (Not-a-Number).
NotAPrimitiveWrapper_1 = La classe \u2018{0}\u2019 n\u2019est pas un
adaptateur d\u2019un type primitif.
NotComparableClass_1 = La classe \u2018{0}\u2019 n\u2019est pas
comparable.
+NoSuchElement_1 = L\u2019\u00e9lement \u201c{0}\u201d n\u2019a
pas \u00e9t\u00e9 trouv\u00e9.
NoSuchProperty_2 = Aucune propri\u00e9t\u00e9 nomm\u00e9e
\u201c{0}\u201d n\u2019a \u00e9t\u00e9 trouv\u00e9e dans \u201c{1}\u201d.
NoUnit = Aucune unit\u00e9 de mesure n\u2019a
\u00e9t\u00e9 sp\u00e9cifi\u00e9e.
NullArgument_1 = L\u2019argument \u2018{0}\u2019 ne doit pas
\u00eatre nul.
Modified:
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java?rev=1487913&r1=1487912&r2=1487913&view=diff
==============================================================================
---
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java
[UTF-8] (original)
+++
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java
[UTF-8] Thu May 30 16:17:57 2013
@@ -21,6 +21,7 @@ import java.io.Closeable;
import java.io.IOException;
import javax.measure.unit.Unit;
import org.apache.sis.measure.Units;
+import org.apache.sis.internal.storage.WarningProducer;
/**
@@ -33,12 +34,18 @@ import org.apache.sis.measure.Units;
*/
public abstract class Decoder extends WarningProducer implements Closeable {
/**
+ * Sets to {@code true} for canceling a reading process.
+ * This flag is honored on a <cite>best effort</cite> basis only.
+ */
+ public volatile boolean canceled;
+
+ /**
* Creates a new decoder.
*
- * @param parent Where to send the warnings, or {@code null} if none.
+ * @param sink Where to send the warnings, or {@code null} if none.
*/
- protected Decoder(final WarningProducer parent) {
- super(parent);
+ protected Decoder(final WarningProducer sink) {
+ super(sink);
}
/**
Modified:
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java?rev=1487913&r1=1487912&r2=1487913&view=diff
==============================================================================
---
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
[UTF-8] (original)
+++
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
[UTF-8] Thu May 30 16:17:57 2013
@@ -37,7 +37,7 @@ import org.apache.sis.internal.jdk8.Func
import org.apache.sis.internal.netcdf.Decoder;
import org.apache.sis.internal.netcdf.Variable;
import org.apache.sis.internal.netcdf.GridGeometry;
-import org.apache.sis.internal.netcdf.WarningProducer;
+import org.apache.sis.internal.storage.WarningProducer;
import org.apache.sis.internal.storage.ChannelDataInput;
import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.internal.jdk8.JDK8;
@@ -173,16 +173,16 @@ public final class ChannelDecoder extend
* Creates a new decoder for the given file.
* This constructor parses immediately the header.
*
- * @param parent Where to send the warnings, or {@code null} if none.
+ * @param sink Where to send the warnings, or {@code null} if none.
* @param filename A file identifier used only for formatting error
message.
* @param channel The channel from where data are read.
* @throws IOException If an error occurred while reading the channel.
* @throws DataStoreException If the content of the given channel is not a
NetCDF file.
*/
- public ChannelDecoder(final WarningProducer parent, final String filename,
final ReadableByteChannel channel)
+ public ChannelDecoder(final WarningProducer sink, final String filename,
final ReadableByteChannel channel)
throws IOException, DataStoreException
{
- super(parent);
+ super(sink);
// The buffer must be backed by a Java {@code byte[]} array,
// because we will occasionally reference that array.
input = new ChannelDataInput(filename, channel,
ByteBuffer.allocate(4096), false);
Modified:
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java?rev=1487913&r1=1487912&r2=1487913&view=diff
==============================================================================
---
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
[UTF-8] (original)
+++
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
[UTF-8] Thu May 30 16:17:57 2013
@@ -21,11 +21,13 @@ import java.util.List;
import java.util.EnumSet;
import java.io.IOException;
import ucar.nc2.Group;
+import ucar.nc2.Dimension;
import ucar.nc2.Attribute;
import ucar.nc2.VariableIF;
import ucar.nc2.NetcdfFile;
import ucar.nc2.dataset.NetcdfDataset;
import ucar.nc2.dataset.CoordinateSystem;
+import ucar.nc2.util.CancelTask;
import ucar.nc2.units.DateUnit;
import ucar.nc2.time.Calendar;
import ucar.nc2.time.CalendarDate;
@@ -34,8 +36,7 @@ import org.apache.sis.util.ArraysExt;
import org.apache.sis.internal.netcdf.Decoder;
import org.apache.sis.internal.netcdf.Variable;
import org.apache.sis.internal.netcdf.GridGeometry;
-import org.apache.sis.internal.netcdf.WarningProducer;
-import ucar.nc2.Dimension;
+import org.apache.sis.internal.storage.WarningProducer;
/**
@@ -46,7 +47,7 @@ import ucar.nc2.Dimension;
* @version 0.3
* @module
*/
-public final class DecoderWrapper extends Decoder {
+public final class DecoderWrapper extends Decoder implements CancelTask {
/**
* The NetCDF file to read.
* This file is set at construction time.
@@ -85,15 +86,27 @@ public final class DecoderWrapper extend
* {@link NetcdfFile} instance, the {@link NetcdfDataset} subclass is
necessary in order to
* get coordinate system information.
*
- * @param parent Where to send the warnings, or {@code null} if none.
- * @param file The NetCDF file from which to parse metadata.
+ * @param sink Where to send the warnings, or {@code null} if none.
+ * @param file The NetCDF file from which to read data.
*/
- public DecoderWrapper(final WarningProducer parent, final NetcdfFile file)
{
- super(parent);
+ public DecoderWrapper(final WarningProducer sink, final NetcdfFile file) {
+ super(sink);
this.file = file;
}
/**
+ * Creates a new decoder for the given filename.
+ *
+ * @param sink Where to send the warnings, or {@code null} if none.
+ * @param filename The name of the NetCDF file from which to read data.
+ * @throws IOException If an error occurred while opening the NetCDF file.
+ */
+ public DecoderWrapper(final WarningProducer sink, final String filename)
throws IOException {
+ super(sink);
+ file = NetcdfDataset.openDataset(filename, false, this);
+ }
+
+ /**
* Defines the groups where to search for named attributes, in preference
order.
* The {@code null} group name stands for the global attributes.
*/
@@ -311,6 +324,27 @@ public final class DecoderWrapper extend
}
/**
+ * Invoked by the UCAR NetCDF library for checking if the reading process
has been canceled.
+ * This method returns the {@link #canceled} flag.
+ *
+ * @return The {@link #canceled} flag.
+ */
+ @Override
+ public boolean isCancel() {
+ return canceled;
+ }
+
+ /**
+ * Invoked by the UCAR NetCDF library when an error occurred.
+ *
+ * @param message The error message.
+ */
+ @Override
+ public void setError(final String message) {
+ warning(null, message);
+ }
+
+ /**
* Closes the NetCDF file.
*
* @throws IOException If an error occurred while closing the file.
Modified:
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java?rev=1487913&r1=1487912&r2=1487913&view=diff
==============================================================================
---
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
[UTF-8] (original)
+++
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
[UTF-8] Thu May 30 16:17:57 2013
@@ -64,7 +64,7 @@ import org.apache.sis.internal.netcdf.Ax
import org.apache.sis.internal.netcdf.Decoder;
import org.apache.sis.internal.netcdf.Variable;
import org.apache.sis.internal.netcdf.GridGeometry;
-import org.apache.sis.internal.netcdf.WarningProducer;
+import org.apache.sis.internal.storage.WarningProducer;
import org.apache.sis.internal.util.DefaultFactories;
import org.apache.sis.internal.metadata.MetadataUtilities;
@@ -169,12 +169,11 @@ final class MetadataReader extends Warni
/**
* Creates a new <cite>NetCDF to ISO</cite> mapper for the given source.
*
- * @param parent Where to send the warnings, or {@code null} if none.
* @param decoder The source of NetCDF attributes.
* @throws IOException If an I/O operation was necessary but failed.
*/
- MetadataReader(final WarningProducer parent, final Decoder decoder) throws
IOException {
- super(parent);
+ MetadataReader(final Decoder decoder) throws IOException {
+ super(decoder.sink);
this.decoder = decoder;
decoder.setSearchPath(SEARCH_PATH);
searchPath = decoder.getSearchPath();
Modified:
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/ConformanceTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/ConformanceTest.java?rev=1487913&r1=1487912&r2=1487913&view=diff
==============================================================================
---
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/ConformanceTest.java
[UTF-8] (original)
+++
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/ConformanceTest.java
[UTF-8] Thu May 30 16:17:57 2013
@@ -66,7 +66,7 @@ public final strictfp class ConformanceT
@Override
protected Metadata wrap(final NetcdfFile file) throws IOException {
final Decoder decoder = new DecoderWrapper(null, file);
- final MetadataReader ncISO = new MetadataReader(null, decoder);
+ final MetadataReader ncISO = new MetadataReader(decoder);
return ncISO.read();
// Do not close the file, as this will be done by the parent test
class.
}
Modified:
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java?rev=1487913&r1=1487912&r2=1487913&view=diff
==============================================================================
---
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java
[UTF-8] (original)
+++
sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java
[UTF-8] Thu May 30 16:17:57 2013
@@ -53,7 +53,7 @@ public final strictfp class MetadataRead
public void testEmbedded() throws IOException {
final Metadata metadata;
try (Decoder input = ChannelDecoderTest.createChannelDecoder(NCEP)) {
- metadata = new MetadataReader(null, input).read();
+ metadata = new MetadataReader(input).read();
}
compareToExpected(metadata);
}
@@ -68,7 +68,7 @@ public final strictfp class MetadataRead
public void testUCAR() throws IOException {
final Metadata metadata;
try (Decoder input = new DecoderWrapper(null, new
NetcdfDataset(open(NCEP)))) {
- metadata = new MetadataReader(null, input).read();
+ metadata = new MetadataReader(input).read();
}
compareToExpected(metadata);
}
Added:
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=1487913&view=auto
==============================================================================
---
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java
(added)
+++
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java
[UTF-8] Thu May 30 16:17:57 2013
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.storage;
+
+import java.util.logging.Logger;
+import java.util.logging.LogRecord;
+import java.util.NoSuchElementException;
+import org.apache.sis.util.ArgumentChecks;
+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.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.3
+ * @version 0.3
+ * @module
+ */
+public final class WarningConsumer<T> extends WarningProducer {
+ /**
+ * 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.
+ */
+ private final Logger logger;
+
+ /**
+ * 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;
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Invoked when a new warning has been emitted. This method notifies the
listeners if any,
+ * or log the warning otherwise.
+ */
+ @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);
+ }
+ }
+
+ /**
+ * Adds a listener to be notified when a warning occurred while reading
from or writing to the storage.
+ *
+ * @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 {
+ ArgumentChecks.ensureNonNull("listener", listener);
+ final WarningListener<? super T>[] 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];
+ for (int i=0; i<length; i++) {
+ final WarningListener<? super T> c = current[i];
+ if (c == listener) {
+ throw new
IllegalArgumentException(Errors.format(Errors.Keys.ElementAlreadyPresent_1,
listener));
+ }
+ copy[i] = c;
+ }
+ copy[length] = listener;
+ listeners = copy;
+ }
+
+ /**
+ * Removes a previously registered listener.
+ *
+ * @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;
+ if (current != null) {
+ for (int i=0; i<current.length; i++) {
+ if (current[i] == listener) {
+ if (current.length == 1) {
+ listeners = null;
+ } else {
+ @SuppressWarnings({"unchecked", "rawtypes"}) //
Generic array creation.
+ final WarningListener<? super T>[] 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;
+ }
+ return;
+ }
+ }
+ }
+ throw new
NoSuchElementException(Errors.format(Errors.Keys.NoSuchElement_1, listener));
+ }
+}
Propchange:
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningConsumer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Copied:
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningProducer.java
(from r1487611,
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/WarningProducer.java)
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningProducer.java?p2=sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningProducer.java&p1=sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/WarningProducer.java&r1=1487611&r2=1487913&rev=1487913&view=diff
==============================================================================
---
sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/WarningProducer.java
[UTF-8] (original)
+++
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/WarningProducer.java
[UTF-8] Thu May 30 16:17:57 2013
@@ -14,17 +14,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.internal.netcdf;
+package org.apache.sis.internal.storage;
import java.util.logging.Level;
-import java.util.logging.Logger;
import java.util.logging.LogRecord;
import org.apache.sis.util.Exceptions;
import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.logging.WarningListener;
/**
- * Base class of NetCDF classes which may produce warnings.
+ * Base class of storage classes which may produce warnings. Warnings are
emitted by invoking one of the
+ * {@code warning(…)} methods and encapsulated in {@link LogRecord} instances.
All warnings ultimately
+ * go through the {@link #sendWarning(LogRecord)} method, thus providing a
single method to override if
+ * some additional handling is needed. When a warning is emitted, there is a
choice:
+ *
+ * <ul>
+ * <li>If this {@code WarningProducer} is part of a larger process
represented by an other {@code WarningProducer}
+ * instance (i.e. if this instance has a non-null {@link #sink}), then
the {@link #sendWarning(LogRecord)}
+ * method will delegate its work to that other {@code WarningProducer}
instance (the sink).</li>
+ *
+ * <li>Otherwise, if there is any {@link WarningListener}, then those
listeners are notified and the warning is
+ * <strong>not</strong> logged. This case is actually implemented by the
{@link WarningConsumer} subclass.</li>
+ *
+ * <li>Otherwise the warning is logged to the logger given to the {@link
WarningConsumer} constructor.</li>
+ * </ul>
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3 (derived from geotk-3.08)
@@ -33,45 +47,56 @@ import org.apache.sis.util.logging.Loggi
*/
public class WarningProducer {
/**
- * Where to send the warnings, or {@code null} if none.
+ * Where to send the warnings, or {@code null} if none. This field is
always {@code null} for
+ * {@link WarningConsumer}, since the later will redirect warnings to the
listeners (if any).
*/
- private final WarningProducer parent;
+ public final WarningProducer sink;
/**
- * Creates a new instance.
+ * Creates a new instance which will send the warnings to the given object.
*
- * @param parent Where to send the warnings, or {@code null} if none.
+ * @param sink Where to send the warnings, or {@code null} if none.
*/
- protected WarningProducer(final WarningProducer parent) {
- this.parent = parent;
+ protected WarningProducer(final WarningProducer sink) {
+ this.sink = sink;
}
/**
- * Reports a warning represented by the given log record. The current
implementation just logs the warning.
- * However if we want to implement a listener mechanism in a future
version, this could be done here.
+ * Reports a warning represented by the given log record. The default
implementation delegates to the
+ * {@link #sink} if any, or logs the message to a default logger
otherwise. The {@link WarningConsumer}
+ * subclass overrides this method in order to notify listeners or use a
different logger.
*
* @param record The warning as a log record.
*/
- private void warning(final LogRecord record) {
- if (parent != null) {
- parent.warning(record);
+ void sendWarning(final LogRecord record) {
+ if (sink != null) {
+ sink.sendWarning(record);
} else {
- final Logger logger = Logging.getLogger(WarningProducer.class);
- record.setLoggerName(logger.getName());
- logger.log(record);
+ record.setLoggerName("org.apache.sis.storage");
+ Logging.getLogger("org.apache.sis.storage").log(record);
}
}
/**
+ * Reports a warning represented by the given message.
+ *
+ * @param methodName The name of the method in which the warning occurred.
+ * @param message The message to log.
+ */
+ protected final void warning(final String methodName, final String
message) {
+ final LogRecord record = new LogRecord(Level.WARNING, message);
+ record.setSourceClassName(getClass().getCanonicalName());
+ record.setSourceMethodName(methodName);
+ sendWarning(record);
+ }
+
+ /**
* Reports a warning represented by the given exception.
*
* @param methodName The name of the method in which the warning occurred.
* @param exception The exception to log.
*/
protected final void warning(final String methodName, final Exception
exception) {
- final LogRecord record = new LogRecord(Level.WARNING,
Exceptions.formatChainedMessages(null, null, exception));
- record.setSourceClassName(getClass().getCanonicalName());
- record.setSourceMethodName(methodName);
- warning(record);
+ warning(methodName, Exceptions.formatChainedMessages(null, null,
exception));
}
}
Modified:
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java?rev=1487913&r1=1487912&r2=1487913&view=diff
==============================================================================
---
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
[UTF-8] (original)
+++
sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
[UTF-8] Thu May 30 16:17:57 2013
@@ -16,7 +16,9 @@
*/
package org.apache.sis.storage;
+import java.util.NoSuchElementException;
import org.opengis.metadata.Metadata;
+import org.apache.sis.util.logging.WarningListener;
/**
@@ -40,6 +42,42 @@ public interface DataStore extends AutoC
Metadata getMetadata() throws DataStoreException;
/**
+ * Adds a listener to be notified when a warning occurred while reading
from or writing to the storage.
+ * When a warning occurs, there is a choice:
+ *
+ * <ul>
+ * <li>If this data store has no warning listener, then the warning is
logged at
+ * {@link java.util.logging.Level#WARNING}.</li>
+ * <li>If this data store has at least one warning listener, then all
listeners are notified
+ * and the warning is <strong>not</strong> logged by this data store
instance.</li>
+ * </ul>
+ *
+ * Consider invoking this method in a {@code try} … {@code finally} block
if the {@code DataStore}
+ * lifetime is longer than the listener lifetime, as below:
+ *
+ * {@preformat java
+ * datastore.addWarningListener(listener);
+ * try {
+ * // Do some work...
+ * } finally {
+ * datastore.removeWarningListener(listener);
+ * }
+ * }
+ *
+ * @param listener The listener to add.
+ * @throws IllegalArgumentException If the given listener is already
registered in this data store.
+ */
+ void addWarningListener(WarningListener<? super DataStore> listener)
throws IllegalArgumentException;
+
+ /**
+ * Removes a previously registered listener.
+ *
+ * @param listener The listener to remove.
+ * @throws NoSuchElementException If the given listener is not registered
in this data store.
+ */
+ void removeWarningListener(WarningListener<? super DataStore> listener)
throws NoSuchElementException;
+
+ /**
* Closes this data store and releases any underlying resources.
*
* @throws DataStoreException If an error occurred while closing this data
store.