You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2018/05/22 16:35:40 UTC
svn commit: r1832046 - in /sis/branches/JDK8/core:
sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/
sis-metadata/src/main/java/org/apache/sis/metadata/sql/
sis-referencing-by-identifiers/
sis-referencing/src/main/java/org/apache/sis/ref...
Author: desruisseaux
Date: Tue May 22 16:35:40 2018
New Revision: 1832046
URL: http://svn.apache.org/viewvc?rev=1832046&view=rev
Log:
Reduce the amount of exceptions logged when the application can not connect to the spatial metadata database.
Added:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java (with props)
Modified:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
sis/branches/JDK8/core/sis-referencing-by-identifiers/pom.xml
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java?rev=1832046&r1=1832045&r2=1832046&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java [UTF-8] Tue May 22 16:35:40 2018
@@ -70,7 +70,7 @@ import org.apache.sis.util.logging.Loggi
* All other methods are related to getting the {@code DataSource} instance, through JNDI or otherwise.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
* @since 0.7
* @module
*/
@@ -422,9 +422,10 @@ public abstract class Initializer {
* This message can be used for constructing an exception when {@link #getDataSource()} returned {@code null}.
*
* @param locale the locale for the message to produce, or {@code null} for the default one.
+ * @param asLog {@code true} for returning the message as a {@link LogRecord}, {@code false} for a {@link String}.
* @return message for unspecified data source.
*/
- public static String unspecified(final Locale locale) {
+ public static Object unspecified(final Locale locale, final boolean asLog) {
final short key;
final String value;
if (hasJNDI()) {
@@ -434,7 +435,8 @@ public abstract class Initializer {
key = Messages.Keys.DataDirectoryNotSpecified_1;
value = DataDirectory.ENV;
}
- return Messages.getResources(locale).getString(key, value);
+ final Messages resources = Messages.getResources(locale);
+ return asLog ? resources.getLogRecord(Level.WARNING, key, value) : resources.getString(key, value);
}
/**
@@ -486,7 +488,7 @@ public abstract class Initializer {
*/
private static DataSource forJavaDB(final String path, final ClassLoader loader) throws Exception {
final Class<?> c = Class.forName("org.apache.derby.jdbc.EmbeddedDataSource", true, loader);
- final DataSource ds = (DataSource) c.newInstance();
+ final DataSource ds = (DataSource) c.getConstructor().newInstance();
final Class<?>[] args = {String.class};
c.getMethod("setDatabaseName", args).invoke(ds, path);
c.getMethod("setDataSourceName", args).invoke(ds, "Apache SIS spatial metadata");
Added: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java?rev=1832046&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java (added)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java [UTF-8] Tue May 22 16:35:40 2018
@@ -0,0 +1,101 @@
+/*
+ * 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.metadata.sql;
+
+import org.opengis.util.ControlledVocabulary;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.logging.WarningListener;
+import org.apache.sis.xml.NilReason;
+
+
+/**
+ * A fallback providing hard-coded values of metadata entities.
+ * Used when connection to the spatial metadata can not be established.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @version 1.0
+ * @since 1.0
+ * @module
+ */
+final class MetadataFallback extends MetadataSource {
+ /**
+ * The unique instance of this fallback.
+ */
+ static final MetadataFallback INSTANCE = new MetadataFallback();
+
+ /**
+ * Creates the singleton.
+ */
+ private MetadataFallback() {
+ }
+
+ /**
+ * Searches for the given metadata in the hard-coded list.
+ *
+ * @param metadata the metadata to search for.
+ * @return the identifier of the given metadata, or {@code null} if none.
+ */
+ @Override
+ public String search(final Object metadata) {
+ ArgumentChecks.ensureNonNull("metadata", metadata);
+ return null;
+ }
+
+ /**
+ * Returns a hard-coded metadata filled with the data referenced by the specified identifier.
+ * Alternatively, this method can also return a {@code CodeList} or {@code Enum} element.
+ *
+ * @param <T> the parameterized type of the {@code type} argument.
+ * @param type the interface to implement, or {@code CodeList} or some {@code Enum} types.
+ * @param identifier the identifier of hard-coded values for the metadata entity to be returned.
+ * @return an implementation of the required interface, or the code list element.
+ */
+ @Override
+ public <T> T lookup(final Class<T> type, final String identifier) {
+ ArgumentChecks.ensureNonNull("type", type);
+ ArgumentChecks.ensureNonEmpty("identifier", identifier);
+ Object value;
+ if (ControlledVocabulary.class.isAssignableFrom(type)) {
+ value = getCodeList(type, identifier);
+ } else {
+ // TODO: move some code from ServicesForUtility here.
+ return NilReason.MISSING.createNilObject(type);
+ }
+ return type.cast(value);
+ }
+
+ /**
+ * Ignored.
+ */
+ @Override
+ public void addWarningListener(WarningListener<? super MetadataSource> listener) {
+ }
+
+ /**
+ * Ignored.
+ */
+ @Override
+ public void removeWarningListener(WarningListener<? super MetadataSource> listener) {
+ }
+
+ /**
+ * Ignored.
+ */
+ @Override
+ public void close() {
+ }
+}
Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java?rev=1832046&r1=1832045&r2=1832046&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java [UTF-8] Tue May 22 16:35:40 2018
@@ -41,6 +41,7 @@ import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.SQLTransientException;
import java.sql.SQLNonTransientException;
import java.sql.PreparedStatement;
import org.opengis.annotation.UML;
@@ -106,7 +107,7 @@ import org.apache.sis.util.iso.Types;
*
* @author Touraïvane (IRD)
* @author Martin Desruisseaux (IRD, Geomatys)
- * @version 0.8
+ * @version 1.0
* @since 0.8
* @module
*/
@@ -285,12 +286,16 @@ public class MetadataSource implements A
/**
* The instance connected to the {@code "jdbc/SpatialMetadata"} database,
* created when first needed and cleared when the classpath change.
+ * May be {@link MetadataFallback#INSTANCE} if we failed to establish
+ * a connection to the database for a non-transient reason.
*/
- private static volatile MetadataSource instance;
+ private static MetadataSource instance;
static {
SystemListener.add(new SystemListener(Modules.METADATA) {
@Override protected void classpathChanged() {
- instance = null;
+ synchronized (MetadataSource.class) {
+ instance = null;
+ }
}
});
}
@@ -302,28 +307,51 @@ public class MetadataSource implements A
* citations} and {@linkplain org.apache.sis.metadata.iso.distribution.DefaultFormat formats}
* among others.
*
+ * <p>If connection to the metadata database can not be established, then this method returns
+ * a fallback with a few hard-coded values.</p>
+ *
* @return source of pre-defined metadata records from the {@code "jdbc/SpatialMetadata"} database.
- * @throws MetadataStoreException if this method can not connect to the database.
*/
- public static MetadataSource getProvided() throws MetadataStoreException {
+ public static synchronized MetadataSource getProvided() {
MetadataSource ms = instance;
if (ms == null) {
- final DataSource dataSource;
+ LogRecord warning = null;
+ boolean isTransient = false;
try {
- dataSource = Initializer.getDataSource();
- } catch (Exception e) {
- throw new MetadataStoreException(Errors.format(Errors.Keys.CanNotConnectTo_1, Initializer.JNDI), e);
- }
- if (dataSource == null) {
- throw new MetadataStoreException(Initializer.unspecified(null));
- }
- synchronized (MetadataSource.class) {
- ms = instance;
- if (ms == null) {
+ final DataSource dataSource = Initializer.getDataSource();
+ if (dataSource != null) {
ms = new MetadataSource(MetadataStandard.ISO_19115, dataSource, "metadata", null);
ms.install();
- instance = ms;
+ } else {
+ warning = (LogRecord) Initializer.unspecified(null, true);
+ ms = MetadataFallback.INSTANCE;
}
+ } catch (Exception e) {
+ ms = MetadataFallback.INSTANCE;
+ /*
+ * Derby sometime wraps SQLException into another SQLException. For making the stack strace a
+ * little bit simpler, keep only the root cause provided that the exception type is compatible.
+ */
+ warning = Errors.getResources((Locale) null).getLogRecord(Level.WARNING, Errors.Keys.CanNotConnectTo_1, Initializer.JNDI);
+ warning.setThrown(Exceptions.unwrap(e));
+ /*
+ * If the error is transient or has a transient cause, we will not save MetadataFallback.INSTANCE
+ * in the 'instance' field. The intent is to try again next time this method will be invoked, in
+ * case the transient error has disappeared.
+ */
+ for (Throwable cause = e; cause != null; cause = cause.getCause()) {
+ if (cause instanceof SQLTransientException) {
+ isTransient = true;
+ break;
+ }
+ }
+ }
+ if (warning != null) {
+ warning.setLoggerName(Loggers.SYSTEM);
+ Logging.log(MetadataSource.class, "getProvided", warning);
+ }
+ if (!isTransient) {
+ instance = ms;
}
}
return ms;
@@ -399,6 +427,21 @@ public class MetadataSource implements A
}
/**
+ * For {@link MetadataFallback} constructor only.
+ */
+ MetadataSource() {
+ standard = MetadataStandard.ISO_19115;
+ dataSource = null;
+ catalog = null;
+ statements = null;
+ tableColumns = null;
+ classloader = getClass().getClassLoader();
+ pool = null;
+ lastUsed = null;
+ listeners = null;
+ }
+
+ /**
* If the metadata schema does not exist in the database, creates it and inserts the pre-defined metadata values.
* The current implementation has the following restrictions:
*
@@ -410,32 +453,24 @@ public class MetadataSource implements A
* Maintenance note: this method is invoked by reflection in {@code non-free:sis-embedded-data} module.
* If we make this method public in a future Apache SIS version, then we can remove the reflection code.
*
- * @throws MetadataStoreException if an error occurred while inserting the metadata.
+ * @throws SQLException if an error occurred while inserting the metadata.
*/
- final synchronized void install() throws MetadataStoreException {
- try {
- final Connection connection = connection();
- final DatabaseMetaData md = connection.getMetaData();
- if (md.storesUpperCaseIdentifiers()) {
- schema = schema.toUpperCase(Locale.US);
- } else if (md.storesLowerCaseIdentifiers()) {
- schema = schema.toLowerCase(Locale.US);
- }
- quoteSchema = false;
- try (ResultSet result = md.getTables(catalog, schema, "CI_Citation", null)) {
- if (result.next()) {
- return;
- }
- }
- final Installer installer = new Installer(connection);
- installer.run();
- } catch (IOException | SQLException e) {
- /*
- * Derby sometime wraps SQLException into another SQLException. For making the stack strace a
- * little bit simpler, keep only the root cause provided that the exception type is compatible.
- */
- throw new MetadataStoreException(e.getLocalizedMessage(), Exceptions.unwrap(e));
+ final synchronized void install() throws IOException, SQLException {
+ final Connection connection = connection();
+ final DatabaseMetaData md = connection.getMetaData();
+ if (md.storesUpperCaseIdentifiers()) {
+ schema = schema.toUpperCase(Locale.US);
+ } else if (md.storesLowerCaseIdentifiers()) {
+ schema = schema.toLowerCase(Locale.US);
+ }
+ quoteSchema = false;
+ try (ResultSet result = md.getTables(catalog, schema, "CI_Citation", null)) {
+ if (result.next()) {
+ return;
+ }
}
+ final Installer installer = new Installer(connection);
+ installer.run();
}
/**
@@ -839,7 +874,7 @@ public class MetadataSource implements A
final Class<?> subType = subType(type, identifier);
final Dispatcher toSearch = new Dispatcher(identifier, this);
try {
- value = subType.newInstance();
+ value = subType.getConstructor().newInstance();
final LookupInfo info = getLookupInfo(subType);
final Map<String,Object> map = asValueMap(value);
final Map<String,String> methods = standard.asNameMap(subType, NAME_POLICY, KeyNamePolicy.METHOD_NAME);
@@ -984,7 +1019,7 @@ public class MetadataSource implements A
* message when the actual class is unknown (it must have been checked dynamically by the caller however).
*/
@SuppressWarnings("unchecked")
- private static ControlledVocabulary getCodeList(final Class<?> type, final String name) {
+ static ControlledVocabulary getCodeList(final Class<?> type, final String name) {
if (type.isEnum()) {
return (ControlledVocabulary) Types.forEnumName(type.asSubclass(Enum.class), name);
} else {
Modified: sis/branches/JDK8/core/sis-referencing-by-identifiers/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing-by-identifiers/pom.xml?rev=1832046&r1=1832045&r2=1832046&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing-by-identifiers/pom.xml (original)
+++ sis/branches/JDK8/core/sis-referencing-by-identifiers/pom.xml Tue May 22 16:35:40 2018
@@ -135,6 +135,11 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
+ <!-- dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derby</artifactId>
+ <scope>test</scope>
+ </dependency -->
</dependencies>
</project>
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java?rev=1832046&r1=1832045&r2=1832046&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java [UTF-8] Tue May 22 16:35:40 2018
@@ -268,7 +268,7 @@ public class EPSGFactory extends Concurr
if (ds == null) try {
ds = Initializer.getDataSource();
if (ds == null) {
- throw new UnavailableFactoryException(Initializer.unspecified(locale));
+ throw new UnavailableFactoryException(String.valueOf(Initializer.unspecified(locale, false)));
}
} catch (Exception e) {
throw new UnavailableFactoryException(canNotUse(e), e);
Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java?rev=1832046&r1=1832045&r2=1832046&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java [UTF-8] Tue May 22 16:35:40 2018
@@ -74,7 +74,7 @@ import static org.junit.Assert.*;
* after any upgrade of the EPSG dataset.</p>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 1.0
* @since 0.7
* @module
*/
@@ -480,7 +480,7 @@ public final strictfp class CoordinateRe
properties.setProperty("PRODUCT.URL", "http://sis.apache.org");
properties.setProperty("JAVADOC.GEOAPI", "http://www.geoapi.org/snapshot/javadoc");
properties.setProperty("FACTORY.NAME", "EPSG");
- properties.setProperty("FACTORY.VERSION", "9.1");
+ properties.setProperty("FACTORY.VERSION", "9.3");
properties.setProperty("FACTORY.VERSION.SUFFIX", ", together with other sources");
properties.setProperty("PRODUCT.VERSION.SUFFIX", " (provided that <a href=\"http://sis.apache.org/epsg.html\">a connection to an EPSG database exists</a>)");
properties.setProperty("DESCRIPTION", "<p><b>Notation:</b></p>\n" +