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 2021/09/28 17:03:52 UTC
[sis] branch geoapi-4.0 updated (56d681c -> 5a19844)
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a change to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git.
from 56d681c Port tests written by Alexis Manin.
new c0c2b4f Clarification about the changes allowed on feature types.
new d23de41 Remove references to Java Native Interfaces (JNI) that do not apply anymore after removal of "sis-gdal" module.
new e1bf431 Skip a test if the EPSG geodetic dataset is not present.
new 5a19844 Move into a new class (`OptionalInstallations`) part of the `ResourceDownloader` code asking if user agrees with EPSG terms of use. The intend is to allow to reuse this code in JavaFX application in addition of console application.
The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
application/sis-console/pom.xml | 10 +-
.../sis-console/src/main/artifact/lib/README | 5 -
.../src/main/artifact/lib/darwin/content.txt | 2 -
.../src/main/artifact/lib/linux/content.txt | 2 -
.../src/main/artifact/lib/windows/content.txt | 2 -
.../apache/sis/console/ResourcesDownloader.java | 234 ++++---------------
.../sis/referencing/EPSGFactoryFallback.java | 2 +-
.../sis/referencing/factory/sql/EPSGInstaller.java | 2 +-
.../factory/sql/InstallationScriptProvider.java | 2 +-
.../test/integration/CoordinateOperationTest.java | 3 +
.../org/apache/sis/internal/system}/Fallback.java | 4 +-
.../apache/sis/setup/InstallationResources.java | 3 +-
.../apache/sis/setup/OptionalInstallations.java | 251 +++++++++++----------
ide-project/NetBeans/build.xml | 7 +
.../sis/internal/sql/feature/SchemaModifier.java | 5 +-
15 files changed, 197 insertions(+), 337 deletions(-)
delete mode 100644 application/sis-console/src/main/artifact/lib/darwin/content.txt
delete mode 100644 application/sis-console/src/main/artifact/lib/linux/content.txt
delete mode 100644 application/sis-console/src/main/artifact/lib/windows/content.txt
rename core/{sis-referencing/src/main/java/org/apache/sis/internal/referencing => sis-utility/src/main/java/org/apache/sis/internal/system}/Fallback.java (96%)
copy application/sis-console/src/main/java/org/apache/sis/console/ResourcesDownloader.java => core/sis-utility/src/main/java/org/apache/sis/setup/OptionalInstallations.java (54%)
[sis] 01/04: Clarification about the changes allowed on feature
types.
Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
commit c0c2b4f6220abdfcf14b5d7f669b06db1d36b92c
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue Sep 28 10:40:19 2021 +0200
Clarification about the changes allowed on feature types.
---
.../java/org/apache/sis/internal/sql/feature/SchemaModifier.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SchemaModifier.java b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SchemaModifier.java
index 8902ce3..f648721 100644
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SchemaModifier.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SchemaModifier.java
@@ -28,6 +28,8 @@ import org.opengis.feature.FeatureType;
* Modifies the feature types inferred from database analysis.
*
* @todo May move to public API (in revised form) in a future version.
+ * It could be specified for each {@code ResourceDefinition},
+ * in which case the {@link TableReference} argument is no longer necessary.
*
* @author Martin Desruisseaux (Geomatys)
* @version 1.1
@@ -38,7 +40,8 @@ public interface SchemaModifier {
/**
* Invoked after analysis of a table for allowing modifications of the inferred feature type.
* The given builder is initialized with all properties inferred from the table definition.
- * Implementation of this method can add, remove or modify properties.
+ * Implementation of this method can add properties (e.g. operations) but should not remove
+ * or rename properties. It is okay to add or remove characteristics on properties.
*
* <p>The default implementation returns {@code feature.build()} without making any change.</p>
*
[sis] 04/04: Move into a new class (`OptionalInstallations`) part
of the `ResourceDownloader` code asking if user agrees with EPSG terms of
use. The intend is to allow to reuse this code in JavaFX application in
addition of console application.
Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
commit 5a19844897bd10536c38d5c8166af958af7c9b95
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue Sep 28 12:23:05 2021 +0200
Move into a new class (`OptionalInstallations`) part of the `ResourceDownloader` code asking if user agrees with EPSG terms of use.
The intend is to allow to reuse this code in JavaFX application in addition of console application.
---
application/sis-console/pom.xml | 10 +-
.../apache/sis/console/ResourcesDownloader.java | 234 ++++---------------
.../sis/referencing/EPSGFactoryFallback.java | 2 +-
.../sis/referencing/factory/sql/EPSGInstaller.java | 2 +-
.../factory/sql/InstallationScriptProvider.java | 2 +-
.../org/apache/sis/internal/system}/Fallback.java | 4 +-
.../apache/sis/setup/InstallationResources.java | 3 +-
.../apache/sis/setup/OptionalInstallations.java | 251 +++++++++++----------
ide-project/NetBeans/build.xml | 7 +
9 files changed, 190 insertions(+), 325 deletions(-)
diff --git a/application/sis-console/pom.xml b/application/sis-console/pom.xml
index bdf2bda..7dece05 100644
--- a/application/sis-console/pom.xml
+++ b/application/sis-console/pom.xml
@@ -139,6 +139,11 @@
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derby</artifactId>
+ <scope>runtime</scope>
+ </dependency>
<!-- Test dependencies -->
<dependency>
@@ -160,11 +165,6 @@
<artifactId>jaxb-runtime</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.apache.derby</groupId>
- <artifactId>derby</artifactId>
- <scope>test</scope>
- </dependency>
</dependencies>
</project>
diff --git a/application/sis-console/src/main/java/org/apache/sis/console/ResourcesDownloader.java b/application/sis-console/src/main/java/org/apache/sis/console/ResourcesDownloader.java
index c00a7c9..5f230bc 100644
--- a/application/sis-console/src/main/java/org/apache/sis/console/ResourcesDownloader.java
+++ b/application/sis-console/src/main/java/org/apache/sis/console/ResourcesDownloader.java
@@ -22,23 +22,11 @@ import java.util.HashMap;
import java.util.Collections;
import java.util.Locale;
import java.util.ResourceBundle;
-import java.util.ServiceLoader;
-import java.net.URLClassLoader;
-import java.net.URL;
import java.io.Console;
-import java.io.IOException;
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.nio.file.AccessDeniedException;
-import java.nio.file.Path;
-import java.sql.Connection; // For javadoc.
-import org.apache.sis.internal.system.DataDirectory;
-import org.apache.sis.util.resources.Errors;
import org.apache.sis.internal.util.X364;
-import org.apache.sis.internal.referencing.Fallback;
-import org.apache.sis.setup.InstallationResources;
+import org.apache.sis.internal.system.Fallback;
+import org.apache.sis.setup.OptionalInstallations;
-import static org.apache.sis.internal.util.Constants.EPSG;
/**
@@ -51,23 +39,12 @@ import static org.apache.sis.internal.util.Constants.EPSG;
* </ul>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.1
* @since 0.7
* @module
*/
@Fallback
-public class ResourcesDownloader extends InstallationResources {
- /**
- * Where to download the EPSG scripts after user has approved the terms of use.
- */
- private static final String DOWNLOAD_URL = "http://repo1.maven.org/maven2/org/apache/sis/non-free/sis-epsg/1.0/sis-epsg-1.0.jar";
-
- /**
- * Estimation of the EPSG database size after installation, in mega-bytes.
- * This is for information purpose only.
- */
- private static final int DATABASE_SIZE = 20;
-
+public class ResourcesDownloader extends OptionalInstallations {
/**
* The console to use for printing EPSG terms of use and asking for agreement, or {@code null} if none.
*/
@@ -84,31 +61,16 @@ public class ResourcesDownloader extends InstallationResources {
private final boolean colors;
/**
- * The provider to use for fetching the actual licensed data after we got user's agreement.
- */
- private InstallationResources provider;
-
- /**
- * The target directory where to install the database.
- */
- private final Path directory;
-
- /**
* The localized answers expected from the users. Keys are words like "Yes" or "No"
* and boolean values are the meaning of the keys.
*/
private final Map<String,Boolean> answers = new HashMap<>();
/**
- * {@code true} if the user has accepted the EPSG terms of use, {@code false} if (s)he refused,
- * or {@code null} if (s)he did not yet answered that question.
- */
- private Boolean accepted;
-
- /**
* Creates a new installation scripts provider.
*/
public ResourcesDownloader() {
+ super("text/plain");
final CommandRunner command = CommandRunner.instance;
if (command != null) {
locale = command.locale;
@@ -117,8 +79,17 @@ public class ResourcesDownloader extends InstallationResources {
locale = Locale.getDefault();
colors = false;
}
- console = System.console();
- directory = DataDirectory.DATABASES.getDirectory();
+ console = System.console();
+ }
+
+ /**
+ * Returns the locale to use for messages shown to the user.
+ *
+ * @return the locale of messages shown to the user.
+ */
+ @Override
+ public Locale getLocale() {
+ return locale;
}
/**
@@ -131,38 +102,21 @@ public class ResourcesDownloader extends InstallationResources {
*/
@Override
public Set<String> getAuthorities() {
- return (console != null && directory != null) ? Collections.singleton(EPSG) : Collections.emptySet();
- }
-
- /**
- * Downloads the provider to use for fetching the actual licensed data after we got user's agreement.
- */
- private static InstallationResources download() throws IOException {
- for (final InstallationResources c : ServiceLoader.load(InstallationResources.class,
- new URLClassLoader(new URL[] {new URL(DOWNLOAD_URL)})))
- {
- if (!c.getClass().isAnnotationPresent(Fallback.class) && c.getAuthorities().contains(EPSG)) {
- return c;
- }
- }
- throw new FileNotFoundException(); // Should not happen.
+ return (console != null) ? super.getAuthorities() : Collections.emptySet();
}
/**
- * Returns the provider to use for fetching the actual licensed data after we got user's agreement.
- * This method asks for user's agreement when first invoked.
- *
- * @param requireAgreement {@code true} if license agreement is required.
- * @throws AccessDeniedException if the user does not accept to install the EPSG dataset.
- * @throws IOException if an error occurred while reading the {@link #DOWNLOAD_URL}.
+ * Asks to the user if (s)he agree to download and install the resource for the given authority.
+ * This method may be invoked twice for the same {@code authority} argument:
+ * first with a null {@code license} argument for asking if the user agrees to download the data,
+ * then with a non-null {@code license} argument for asking if the user agrees with the license terms.
*/
- private synchronized InstallationResources provider(final String authority, final boolean requireAgreement)
- throws IOException
- {
- if (!EPSG.equals(authority)) {
- throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "authority", authority));
+ @Override
+ protected boolean askUserAgreement(final String authority, final String license) {
+ if (console == null) {
+ return false;
}
- final ResourceBundle resources = ResourceBundle.getBundle("org.apache.sis.console.Messages", locale);
+ final ResourceBundle resources = ResourceBundle.getBundle("org.apache.sis.console.Messages", getLocale());
if (answers.isEmpty()) {
for (final String r : resources.getString("yes").split("\\|")) answers.put(r, Boolean.TRUE);
for (final String r : resources.getString("no" ).split("\\|")) answers.put(r, Boolean.FALSE);
@@ -178,130 +132,32 @@ public class ResourcesDownloader extends InstallationResources {
textColor = linkColor = linkOff = actionColor = resetColor = "";
}
/*
- * Start the download if the user accepts. We need to begin the download in order to get the
- * license text bundled in the JAR file. We will not necessarily ask for user agreement here.
+ * Show the question.
*/
- if (provider == null) {
- if (console == null) {
- throw new IllegalStateException();
- }
- console.format(resources.getString("install"), textColor, DATABASE_SIZE, linkColor, directory, linkOff, resetColor);
- if (!accept(resources.getString("download"), textColor, resetColor)) {
- console.format("%n");
- throw new AccessDeniedException(null);
- }
- console.format(resources.getString("downloading"), actionColor, resetColor);
- provider = download();
+ final String prompt, action;
+ if (license == null) {
+ prompt = "download";
+ action = "downloading";
+ console.format(resources.getString("install"), textColor, getSpaceRequirement(authority),
+ linkColor, destinationDirectory, linkOff, resetColor);
+ } else {
+ prompt = "accept";
+ action = "installing";
+ console.format("%n").writer().write(license);
+ console.format("%n");
}
/*
- * If there is a need to ask for user agreement and we didn't asked yet, ask now.
+ * Ask user agreement.
*/
- if (requireAgreement && accepted == null) {
- final String license = getLicense(authority, locale, "text/plain");
- if (license == null) {
- accepted = Boolean.TRUE;
- } else {
- console.format("%n").writer().write(license);
- console.format("%n");
- accepted = accept(resources.getString("accept"), textColor, resetColor);
- if (accepted) {
- console.format(resources.getString("installing"), actionColor, resetColor);
- }
- }
- }
- if (accepted != null && !accepted) {
- throw new AccessDeniedException(null);
- }
- return provider;
- }
-
- /**
- * Asks the user to answer by "Yes" or "No". Callers is responsible for ensuring
- * that the {@link #answers} map is non-empty before to invoke this method.
- *
- * @param prompt message to show to the user.
- * @return the user's answer.
- */
- private boolean accept(final String prompt, final Object... arguments) {
Boolean answer;
do {
- answer = answers.get(console.readLine(prompt, arguments).toLowerCase(locale));
+ answer = answers.get(console.readLine(resources.getString(prompt), textColor, resetColor).toLowerCase(getLocale()));
} while (answer == null);
+ if (answer) {
+ console.format(resources.getString(action), actionColor, resetColor);
+ } else {
+ console.format("%n");
+ }
return answer;
}
-
- /**
- * Returns the terms of use of the dataset provided by the given authority, or {@code null} if none.
- * The terms of use can be returned in either plain text or HTML.
- *
- * @param authority one of the values returned by {@link #getAuthorities()}.
- * @param mimeType either {@code "text/plain"} or {@code "text/html"}.
- * @return the terms of use in plain text or HTML, or {@code null} if none.
- * @throws IllegalArgumentException if the given {@code authority} argument is not one of the expected values.
- * @throws IOException if an error occurred while reading the license file.
- */
- @Override
- public String getLicense(String authority, Locale locale, String mimeType) throws IOException {
- return provider(authority, false).getLicense(authority, locale, mimeType);
- }
-
- /**
- * Returns the names of installation scripts provided by the given authority.
- * This method is invoked by {@link org.apache.sis.referencing.factory.sql.EPSGFactory#install(Connection)}
- * for listing the SQL scripts to execute during EPSG dataset installation.
- *
- * <p>If that question has not already been asked, this method asks to the user if (s)he accepts
- * EPSG terms of use. If (s)he refuses, an {@link AccessDeniedException} will be thrown.</p>
- *
- * @param authority one of the values returned by {@link #getAuthorities()}.
- * @return the names of all SQL scripts to execute.
- * @throws IllegalArgumentException if the given {@code authority} argument is not one of the expected values.
- * @throws IOException if an error occurred while fetching the script names.
- */
- @Override
- public String[] getResourceNames(final String authority) throws IOException {
- return provider(authority, true).getResourceNames(authority);
- }
-
- /**
- * Returns an installation resource for the given authority.
- * If that question has not already been asked, this method asks to the user if (s)he accepts
- * EPSG terms of use. If (s)he refuses, an {@link AccessDeniedException} will be thrown.
- *
- * @param authority one of the values returned by {@link #getAuthorities()}.
- * @param index index of the resource to get, from 0 inclusive to
- * <code>{@linkplain #getResourceNames(String) getResourceNames}(authority).length</code> exclusive.
- * @return the resource as an URL or any other type, at implementation choice.
- * @throws IllegalArgumentException if the given {@code authority} argument is not one of the expected values.
- * @throws IndexOutOfBoundsException if the given {@code resource} argument is out of bounds.
- * @throws IOException if an error occurred while fetching the resource.
- *
- * @since 0.8
- */
- @Override
- public Object getResource(final String authority, final int index) throws IOException {
- return provider(authority, true).getResource(authority, index);
- }
-
- /**
- * Returns a reader for the installation script at the given index.
- * This method is invoked by {@link org.apache.sis.referencing.factory.sql.EPSGFactory#install(Connection)}
- * for getting the SQL scripts to execute during EPSG dataset installation.
- *
- * <p>If that question has not already been asked, this method asks to the user if (s)he accepts
- * EPSG terms of use. If (s)he refuses, an {@link AccessDeniedException} will be thrown.</p>
- *
- * @param authority one of the values returned by {@link #getAuthorities()}.
- * @param resource index of the script to open, from 0 inclusive to
- * <code>{@linkplain #getResourceNames(String) getResourceNames}(authority).length</code> exclusive.
- * @return a reader for the installation script content.
- * @throws IllegalArgumentException if the given {@code authority} argument is not one of the expected values.
- * @throws IndexOutOfBoundsException if the given {@code resource} argument is out of bounds.
- * @throws FileNotFoundException if the SQL script of the given name has not been found.
- * @throws IOException if an error occurred while creating the reader.
- */
- @Override
- public BufferedReader openScript(final String authority, final int resource) throws IOException {
- return provider(authority, true).openScript(authority, resource);
- }
}
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java
index 5366ead..273fa46 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java
@@ -46,7 +46,7 @@ import org.apache.sis.metadata.iso.citation.DefaultCitation;
import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
import org.apache.sis.internal.referencing.provider.TransverseMercator;
import org.apache.sis.internal.referencing.Resources;
-import org.apache.sis.internal.referencing.Fallback;
+import org.apache.sis.internal.system.Fallback;
import org.apache.sis.internal.util.Constants;
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.CharSequences;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
index 520fe75..2817846 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
@@ -31,7 +31,7 @@ import org.apache.sis.internal.metadata.sql.ScriptRunner;
import org.apache.sis.internal.metadata.sql.SQLUtilities;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.util.StandardDateFormat;
-import org.apache.sis.internal.referencing.Fallback;
+import org.apache.sis.internal.system.Fallback;
import org.apache.sis.util.Exceptions;
import org.apache.sis.util.resources.Messages;
import org.apache.sis.util.logging.PerformanceLevel;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
index 1c4f99e..3dc678e 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
@@ -37,7 +37,7 @@ import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.setup.InstallationResources;
import org.apache.sis.internal.referencing.Resources;
-import org.apache.sis.internal.referencing.Fallback;
+import org.apache.sis.internal.system.Fallback;
import org.apache.sis.internal.system.DataDirectory;
import org.apache.sis.internal.system.Loggers;
import org.apache.sis.internal.util.CollectionsExt;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Fallback.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/Fallback.java
similarity index 96%
rename from core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Fallback.java
rename to core/sis-utility/src/main/java/org/apache/sis/internal/system/Fallback.java
index 06be827..bcf7db9 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Fallback.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/system/Fallback.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.internal.referencing;
+package org.apache.sis.internal.system;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -34,7 +34,7 @@ import java.lang.annotation.Target;
* The way Apache SIS selects its preferred service provider may change in any future version.</p>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 1.1
* @since 0.7
* @module
*/
diff --git a/core/sis-utility/src/main/java/org/apache/sis/setup/InstallationResources.java b/core/sis-utility/src/main/java/org/apache/sis/setup/InstallationResources.java
index 1f64183..9143e5b 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/setup/InstallationResources.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/setup/InstallationResources.java
@@ -153,7 +153,8 @@ public abstract class InstallationResources {
/**
* Returns an installation resource for the given authority, or {@code null} if not available.
* The return value may be an instance of any type, at implementation choice.
- * This may be for example a {@link java.net.URL} referencing the actual resource.
+ * This may be for example a {@link java.net.URL} referencing the actual resource,
+ * or a {@link javax.sql.DataSource} for an embedded database.
*
* <p>The default implementation returns {@code null}. A null value means that the resource is fetched by
* {@link #openScript(String, int)} instead of this method. We do not return {@link java.net.URL} to text
diff --git a/application/sis-console/src/main/java/org/apache/sis/console/ResourcesDownloader.java b/core/sis-utility/src/main/java/org/apache/sis/setup/OptionalInstallations.java
similarity index 54%
copy from application/sis-console/src/main/java/org/apache/sis/console/ResourcesDownloader.java
copy to core/sis-utility/src/main/java/org/apache/sis/setup/OptionalInstallations.java
index c00a7c9..f2be4de 100644
--- a/application/sis-console/src/main/java/org/apache/sis/console/ResourcesDownloader.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/setup/OptionalInstallations.java
@@ -14,74 +14,65 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.console;
+package org.apache.sis.setup;
import java.util.Set;
-import java.util.Map;
-import java.util.HashMap;
import java.util.Collections;
import java.util.Locale;
-import java.util.ResourceBundle;
import java.util.ServiceLoader;
-import java.net.URLClassLoader;
import java.net.URL;
-import java.io.Console;
+import java.net.URLClassLoader;
+import java.nio.file.Path;
+import java.nio.file.AccessDeniedException;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
-import java.nio.file.AccessDeniedException;
-import java.nio.file.Path;
-import java.sql.Connection; // For javadoc.
-import org.apache.sis.internal.system.DataDirectory;
+import org.apache.sis.util.Localized;
+import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.resources.Errors;
-import org.apache.sis.internal.util.X364;
-import org.apache.sis.internal.referencing.Fallback;
-import org.apache.sis.setup.InstallationResources;
+import org.apache.sis.internal.system.Fallback;
+import org.apache.sis.internal.system.DataDirectory;
import static org.apache.sis.internal.util.Constants.EPSG;
/**
- * A provider for data licensed under different terms of use than the Apache license.
- * This class is in charge of downloading the data if necessary and asking user's agreement
- * before to install them. Authorities managed by the current implementation are:
+ * A predefined set of data important to Apache SIS but not redistributed for space or licensing reasons.
+ * This class is in charge of downloading the data if necessary and asking user's agreement before to install them.
+ * Authorities managed by the current implementation are:
*
* <ul>
* <li>{@code "EPSG"} for the EPSG geodetic dataset.</li>
* </ul>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since 0.7
+ * @version 1.1
+ * @since 1.1
* @module
*/
-@Fallback
-public class ResourcesDownloader extends InstallationResources {
+public abstract class OptionalInstallations extends InstallationResources implements Localized {
/**
* Where to download the EPSG scripts after user has approved the terms of use.
*/
private static final String DOWNLOAD_URL = "http://repo1.maven.org/maven2/org/apache/sis/non-free/sis-epsg/1.0/sis-epsg-1.0.jar";
/**
- * Estimation of the EPSG database size after installation, in mega-bytes.
+ * Estimation of the EPSG database size after installation, in megabytes.
* This is for information purpose only.
*/
- private static final int DATABASE_SIZE = 20;
-
- /**
- * The console to use for printing EPSG terms of use and asking for agreement, or {@code null} if none.
- */
- private final Console console;
+ private static final int DATABASE_SIZE = 26;
/**
- * The locale to use for text display.
+ * The MIME type to use for fetching license texts.
+ * Value can be {@code "text/plain"} or {@code "text/html"}.
*/
- private final Locale locale;
+ private final String licenseMimeType;
/**
- * {@code true} if colors can be applied for ANSI X3.64 compliant terminal.
+ * The target directory where to install the resources, or {@code null} if none.
+ * This is the directory specified by the {@code SIS_DATA} environment variable.
*/
- private final boolean colors;
+ protected final Path destinationDirectory;
/**
* The provider to use for fetching the actual licensed data after we got user's agreement.
@@ -89,63 +80,117 @@ public class ResourcesDownloader extends InstallationResources {
private InstallationResources provider;
/**
- * The target directory where to install the database.
+ * {@code true} if the user has accepted the EPSG terms of use, {@code false} if (s)he refused,
+ * or {@code null} if (s)he did not yet answered that question.
*/
- private final Path directory;
+ private Boolean accepted;
/**
- * The localized answers expected from the users. Keys are words like "Yes" or "No"
- * and boolean values are the meaning of the keys.
+ * Creates a new installation resources downloader.
+ *
+ * @param licenseMimeType either {@code "text/plain"} or {@code "text/html"}.
*/
- private final Map<String,Boolean> answers = new HashMap<>();
+ protected OptionalInstallations(final String licenseMimeType) {
+ ArgumentChecks.ensureNonEmpty("licenseMimeType", licenseMimeType);
+ this.licenseMimeType = licenseMimeType;
+ destinationDirectory = DataDirectory.DATABASES.getDirectory();
+ }
/**
- * {@code true} if the user has accepted the EPSG terms of use, {@code false} if (s)he refused,
- * or {@code null} if (s)he did not yet answered that question.
+ * Asks to the user if (s)he agree to download and install the resource for the given authority.
+ * This method may be invoked twice for the same {@code authority} argument:
+ *
+ * <ol>
+ * <li>With a null {@code license} argument for asking if the user agrees to download the data.</li>
+ * <li>With a non-null {@code license} argument for asking if the user agrees with the license terms.</li>
+ * </ol>
+ *
+ * <div class="note"><b>Design note:</b>
+ * the download action needs to be initiated before to ask for license agreement
+ * because the license text is bundled in the resource to download.</div>
+ *
+ * @param authority one of the authorities returned by {@link #getAuthorities()}.
+ * @param license the license, or {@code null} for asking if the user wants to download the data.
+ * @return whether user accepted.
*/
- private Boolean accepted;
+ protected abstract boolean askUserAgreement(final String authority, final String license);
/**
- * Creates a new installation scripts provider.
+ * Returns the locale to use for messages shown to the user.
+ * The default implementation returns the system default locale.
+ *
+ * @return the locale of messages shown to the user.
*/
- public ResourcesDownloader() {
- final CommandRunner command = CommandRunner.instance;
- if (command != null) {
- locale = command.locale;
- colors = command.colors;
- } else {
- locale = Locale.getDefault();
- colors = false;
- }
- console = System.console();
- directory = DataDirectory.DATABASES.getDirectory();
+ @Override
+ public Locale getLocale() {
+ return Locale.getDefault();
}
/**
- * Returns the name of the authority who provides data under non-Apache terms of use.
- * If this {@code ResourcesDownloader} can not ask user's agreement because there is
- * no {@link Console} attached to the current Java virtual machine, then this method
- * returns an empty set.
+ * Returns the names of the authorities providing data that can be installed.
+ * The default implementation returns the authorities listed in class javadoc,
+ * or a subset of those authorities if some of them can not be installed
+ * (for example because the {@code SIS_DATA} environment variable is not set).
*
- * @return {@code "EPSG"} or an empty set.
+ * @return authorities of data that can be installed (may be an empty set).
*/
@Override
public Set<String> getAuthorities() {
- return (console != null && directory != null) ? Collections.singleton(EPSG) : Collections.emptySet();
+ return (destinationDirectory != null) ? Collections.singleton(EPSG) : Collections.emptySet();
+ }
+
+ /**
+ * Returns the exception to throw for an unsupported authority.
+ */
+ private IllegalArgumentException unsupported(final String authority) {
+ return new IllegalArgumentException(Errors.getResources(getLocale())
+ .getString(Errors.Keys.IllegalArgumentValue_2, "authority", authority));
+ }
+
+ /**
+ * Returns an estimation of the space required on the host computer after download and installation.
+ * This information can be shown to the user before to ask for confirmation.
+ *
+ * @param authority one of the authorities returned by {@link #getAuthorities()}.
+ * @return an estimation of space requirement in megabytes.
+ * @throws IllegalArgumentException if the given {@code authority} argument is not one of the expected values.
+ */
+ public int getSpaceRequirement(final String authority) {
+ switch (authority) {
+ case EPSG: return DATABASE_SIZE;
+ default: throw unsupported(authority); // More authorities may be added in the future.
+ }
+ }
+
+ /**
+ * Returns the URL from where to download data for the specified authority.
+ */
+ private String getDownloadURL(final String authority) {
+ switch (authority) {
+ case EPSG: return DOWNLOAD_URL;
+ default: throw unsupported(authority); // More authorities may be added in the future.
+ }
}
/**
* Downloads the provider to use for fetching the actual licensed data after we got user's agreement.
+ *
+ * @param authority one of the authorities returned by {@link #getAuthorities()}.
+ * @return the actual provider for the given authority.
+ * @throws IllegalArgumentException if the given {@code authority} argument is not one of the expected values.
+ * @throws IOException if an error occurred while downloading the provider.
+ * @throws IllegalArgumentException if the specified authority is not recognized.
*/
- private static InstallationResources download() throws IOException {
- for (final InstallationResources c : ServiceLoader.load(InstallationResources.class,
- new URLClassLoader(new URL[] {new URL(DOWNLOAD_URL)})))
- {
- if (!c.getClass().isAnnotationPresent(Fallback.class) && c.getAuthorities().contains(EPSG)) {
+ private InstallationResources download(final String authority) throws IOException {
+ final String source = getDownloadURL(authority);
+ final URLClassLoader loader = new URLClassLoader(new URL[] {new URL(source)});
+ for (final InstallationResources c : ServiceLoader.load(InstallationResources.class, loader)) {
+ if (!c.getClass().isAnnotationPresent(Fallback.class) && c.getAuthorities().contains(authority)) {
return c;
}
}
- throw new FileNotFoundException(); // Should not happen.
+ // Should not happen.
+ throw new FileNotFoundException(Errors.getResources(getLocale()).getString(Errors.Keys.FileNotFound_1, source));
}
/**
@@ -153,84 +198,42 @@ public class ResourcesDownloader extends InstallationResources {
* This method asks for user's agreement when first invoked.
*
* @param requireAgreement {@code true} if license agreement is required.
- * @throws AccessDeniedException if the user does not accept to install the EPSG dataset.
- * @throws IOException if an error occurred while reading the {@link #DOWNLOAD_URL}.
+ * @throws IllegalArgumentException if the given {@code authority} argument is not one of the expected values.
+ * @throws AccessDeniedException if the user does not accept to install the licensed resource.
+ * @throws IOException if an error occurred while downloading the resource.
*/
private synchronized InstallationResources provider(final String authority, final boolean requireAgreement)
throws IOException
{
if (!EPSG.equals(authority)) {
- throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "authority", authority));
- }
- final ResourceBundle resources = ResourceBundle.getBundle("org.apache.sis.console.Messages", locale);
- if (answers.isEmpty()) {
- for (final String r : resources.getString("yes").split("\\|")) answers.put(r, Boolean.TRUE);
- for (final String r : resources.getString("no" ).split("\\|")) answers.put(r, Boolean.FALSE);
- }
- final String textColor, linkColor, linkOff, actionColor, resetColor;
- if (colors) {
- textColor = X364.FOREGROUND_YELLOW .sequence();
- linkColor = X364.UNDERLINE .sequence();
- linkOff = X364.NO_UNDERLINE .sequence();
- actionColor = X364.FOREGROUND_GREEN .sequence();
- resetColor = X364.FOREGROUND_DEFAULT.sequence();
- } else {
- textColor = linkColor = linkOff = actionColor = resetColor = "";
+ throw unsupported(authority);
}
/*
* Start the download if the user accepts. We need to begin the download in order to get the
- * license text bundled in the JAR file. We will not necessarily ask for user agreement here.
+ * license text bundled in the JAR file. Agreement with license terms will be asked later.
*/
if (provider == null) {
- if (console == null) {
- throw new IllegalStateException();
+ if (!askUserAgreement(authority, null)) {
+ throw new AccessDeniedException(getDownloadURL(authority));
}
- console.format(resources.getString("install"), textColor, DATABASE_SIZE, linkColor, directory, linkOff, resetColor);
- if (!accept(resources.getString("download"), textColor, resetColor)) {
- console.format("%n");
- throw new AccessDeniedException(null);
- }
- console.format(resources.getString("downloading"), actionColor, resetColor);
- provider = download();
+ provider = download(authority);
}
/*
* If there is a need to ask for user agreement and we didn't asked yet, ask now.
*/
- if (requireAgreement && accepted == null) {
- final String license = getLicense(authority, locale, "text/plain");
- if (license == null) {
- accepted = Boolean.TRUE;
- } else {
- console.format("%n").writer().write(license);
- console.format("%n");
- accepted = accept(resources.getString("accept"), textColor, resetColor);
- if (accepted) {
- console.format(resources.getString("installing"), actionColor, resetColor);
- }
+ if (requireAgreement) {
+ if (accepted == null) {
+ final String license = getLicense(authority, getLocale(), licenseMimeType);
+ accepted = (license == null) || askUserAgreement(authority, license);
+ }
+ if (!accepted) {
+ throw new AccessDeniedException(getDownloadURL(authority));
}
- }
- if (accepted != null && !accepted) {
- throw new AccessDeniedException(null);
}
return provider;
}
/**
- * Asks the user to answer by "Yes" or "No". Callers is responsible for ensuring
- * that the {@link #answers} map is non-empty before to invoke this method.
- *
- * @param prompt message to show to the user.
- * @return the user's answer.
- */
- private boolean accept(final String prompt, final Object... arguments) {
- Boolean answer;
- do {
- answer = answers.get(console.readLine(prompt, arguments).toLowerCase(locale));
- } while (answer == null);
- return answer;
- }
-
- /**
* Returns the terms of use of the dataset provided by the given authority, or {@code null} if none.
* The terms of use can be returned in either plain text or HTML.
*
@@ -251,7 +254,7 @@ public class ResourcesDownloader extends InstallationResources {
* for listing the SQL scripts to execute during EPSG dataset installation.
*
* <p>If that question has not already been asked, this method asks to the user if (s)he accepts
- * EPSG terms of use. If (s)he refuses, an {@link AccessDeniedException} will be thrown.</p>
+ * EPSG terms of use. If (s)he refuses, then an {@link AccessDeniedException} will be thrown.</p>
*
* @param authority one of the values returned by {@link #getAuthorities()}.
* @return the names of all SQL scripts to execute.
@@ -266,7 +269,7 @@ public class ResourcesDownloader extends InstallationResources {
/**
* Returns an installation resource for the given authority.
* If that question has not already been asked, this method asks to the user if (s)he accepts
- * EPSG terms of use. If (s)he refuses, an {@link AccessDeniedException} will be thrown.
+ * EPSG terms of use. If (s)he refuses, then an {@link AccessDeniedException} will be thrown.
*
* @param authority one of the values returned by {@link #getAuthorities()}.
* @param index index of the resource to get, from 0 inclusive to
@@ -275,8 +278,6 @@ public class ResourcesDownloader extends InstallationResources {
* @throws IllegalArgumentException if the given {@code authority} argument is not one of the expected values.
* @throws IndexOutOfBoundsException if the given {@code resource} argument is out of bounds.
* @throws IOException if an error occurred while fetching the resource.
- *
- * @since 0.8
*/
@Override
public Object getResource(final String authority, final int index) throws IOException {
@@ -289,7 +290,7 @@ public class ResourcesDownloader extends InstallationResources {
* for getting the SQL scripts to execute during EPSG dataset installation.
*
* <p>If that question has not already been asked, this method asks to the user if (s)he accepts
- * EPSG terms of use. If (s)he refuses, an {@link AccessDeniedException} will be thrown.</p>
+ * EPSG terms of use. If (s)he refuses, then an {@link AccessDeniedException} will be thrown.</p>
*
* @param authority one of the values returned by {@link #getAuthorities()}.
* @param resource index of the script to open, from 0 inclusive to
diff --git a/ide-project/NetBeans/build.xml b/ide-project/NetBeans/build.xml
index b76f00a..77b1f64 100644
--- a/ide-project/NetBeans/build.xml
+++ b/ide-project/NetBeans/build.xml
@@ -229,6 +229,13 @@
</fileset>
</concat>
+ <!-- InstallationResources implementations to be loaded by ServiceLoader. -->
+ <concat destfile="${build.classes.dir}/META-INF/services/org.apache.sis.setup.InstallationResources" encoding="UTF-8" fixlastline="yes">
+ <fileset dir="${project.root}">
+ <include name="*/*/src/main/resources/META-INF/services/org.apache.sis.setup.InstallationResources"/>
+ </fileset>
+ </concat>
+
<!-- DataStoreProvider implementations to be loaded by ServiceLoader. -->
<concat destfile="${build.classes.dir}/META-INF/services/org.apache.sis.storage.DataStoreProvider" encoding="UTF-8" fixlastline="yes">
<fileset dir="${project.root}">
[sis] 02/04: Remove references to Java Native Interfaces (JNI) that
do not apply anymore after removal of "sis-gdal" module.
Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
commit d23de413697df0720cb17f06f7535a8a682bf672
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue Sep 28 14:36:20 2021 +0200
Remove references to Java Native Interfaces (JNI) that do not apply anymore after removal of "sis-gdal" module.
---
application/sis-console/src/main/artifact/lib/README | 5 -----
application/sis-console/src/main/artifact/lib/darwin/content.txt | 2 --
application/sis-console/src/main/artifact/lib/linux/content.txt | 2 --
application/sis-console/src/main/artifact/lib/windows/content.txt | 2 --
4 files changed, 11 deletions(-)
diff --git a/application/sis-console/src/main/artifact/lib/README b/application/sis-console/src/main/artifact/lib/README
index aeb28ea..6b4930b 100644
--- a/application/sis-console/src/main/artifact/lib/README
+++ b/application/sis-console/src/main/artifact/lib/README
@@ -6,8 +6,3 @@ Recognized optional dependencies are:
- UCAR netCDF library
- ESRI Geometry API
- Java Topology Suite
-
-The "linux", "darwin" and "windows" sub-directories contain bridges to Proj.4
-and other libraries through Java Native Interfaces (JNI). They do not contain
-the actual libraries however; Apache SIS uses the libraries installed on host
-computer by packages manager, if any. Those libraries are optional.
diff --git a/application/sis-console/src/main/artifact/lib/darwin/content.txt b/application/sis-console/src/main/artifact/lib/darwin/content.txt
deleted file mode 100644
index 0eea7d7..0000000
--- a/application/sis-console/src/main/artifact/lib/darwin/content.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Placeholder for MacOS "*.so" files to be copied by the
-org.apache.sis.core:sis-build-helper:dist Maven plugin.
diff --git a/application/sis-console/src/main/artifact/lib/linux/content.txt b/application/sis-console/src/main/artifact/lib/linux/content.txt
deleted file mode 100644
index 0b6923e..0000000
--- a/application/sis-console/src/main/artifact/lib/linux/content.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Placeholder for Linux "*.so" files to be copied by the
-org.apache.sis.core:sis-build-helper:dist Maven plugin.
diff --git a/application/sis-console/src/main/artifact/lib/windows/content.txt b/application/sis-console/src/main/artifact/lib/windows/content.txt
deleted file mode 100644
index 771ad9e..0000000
--- a/application/sis-console/src/main/artifact/lib/windows/content.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Placeholder for Windows "*.dll" files to be copied by the
-org.apache.sis.core:sis-build-helper:dist Maven plugin.
[sis] 03/04: Skip a test if the EPSG geodetic dataset is not
present.
Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
commit e1bf4318ef23e1b078f2485da68bfe505a6eeaec
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue Sep 28 14:21:44 2021 +0200
Skip a test if the EPSG geodetic dataset is not present.
---
.../java/org/apache/sis/test/integration/CoordinateOperationTest.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/test/integration/CoordinateOperationTest.java b/core/sis-referencing/src/test/java/org/apache/sis/test/integration/CoordinateOperationTest.java
index 4d4fd7f..faa7d6c 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/test/integration/CoordinateOperationTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/test/integration/CoordinateOperationTest.java
@@ -40,6 +40,7 @@ import org.apache.sis.geometry.DirectPosition2D;
import org.apache.sis.test.DependsOn;
import org.junit.Test;
+import static org.junit.Assume.assumeTrue;
import static org.apache.sis.test.Assert.*;
@@ -191,6 +192,8 @@ public final strictfp class CoordinateOperationTest extends MathTransformTestCas
final double expectedY = 175688.20;
CRSAuthorityFactory crsFactory = CRS.getAuthorityFactory("EPSG");
+ assumeTrue("EPSG authority factory is required for this test.",
+ crsFactory instanceof CoordinateOperationAuthorityFactory);
CoordinateOperationAuthorityFactory opFactory = (CoordinateOperationAuthorityFactory) crsFactory;
// MGI (Ferro) to WGS 84 (1)