Author: desruisseaux
Date: Mon Apr 25 20:30:40 2016
New Revision: 1740892
URL: http://svn.apache.org/viewvc?rev=1740892&view=rev
Log:
Merge from the JDK6 branch.
Added:
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/CRSCommand.java
- copied unchanged from r1740890,
sis/branches/JDK6/application/sis-console/src/main/java/org/apache/sis/console/CRSCommand.java
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java
- copied, changed from r1740890,
sis/branches/JDK6/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
- copied unchanged from r1740890,
sis/branches/JDK6/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
Removed:
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/IdentifierRow.java
Modified:
sis/trunk/ (props changed)
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Command.java
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/CommandRunner.java
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/HelpCommand.java
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/InvalidOptionException.java
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Option.java
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands.properties
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands_fr.properties
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties
sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/MetadataCommandTest.java
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
sis/trunk/core/sis-referencing/src/main/resources/org/apache/sis/referencing/factory/sql/EPSG_Finish.sql
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/IdentifiedObjectsTest.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
Propchange: sis/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Apr 25 20:30:40 2016
@@ -1,4 +1,4 @@
/sis/branches/Android:1430670-1480699
-/sis/branches/JDK6:1394364-1740421
-/sis/branches/JDK7:1394913-1740420
-/sis/branches/JDK8:1584960-1740419
+/sis/branches/JDK6:1394364-1740890
+/sis/branches/JDK7:1394913-1740886
+/sis/branches/JDK8:1584960-1740884
Modified:
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Command.java
URL:
http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Command.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Command.java
[UTF-8] (original)
+++
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Command.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -41,20 +41,23 @@ import org.apache.sis.util.logging.Monol
* <tr><td>{@code metadata} </td><td>Show metadata information for the given
file.</td></tr>
* <tr><td>{@code crs} </td><td>Show Coordinate Reference System
information for the given file or code.</td></tr>
* <tr><td>{@code identifier} </td><td>Show identifiers for metadata and
referencing systems in the given file.</td></tr>
+ * <tr><td>{@code transform} </td><td>Convert or transform coordinates from
given source CRS to target CRS.</td></tr>
* </table></blockquote>
*
- * Each command can accepts an arbitrary amount of the following options:
+ * Each command can accepts some of the following options:
*
* <blockquote><table class="compact" summary="Supported command-line
options.">
- * <tr><td>{@code --format} </td><td>The output format: {@code xml}, {@code
wkt}, {@code wkt1} or {@code text}.</td></tr>
- * <tr><td>{@code --locale} </td><td>The locale to use for the command
output.</td></tr>
- * <tr><td>{@code --timezone} </td><td>The timezone for the dates to be
formatted.</td></tr>
- * <tr><td>{@code --encoding} </td><td>The encoding to use for the command
output.</td></tr>
- * <tr><td>{@code --colors} </td><td>Whether colorized output shall be
enabled.</td></tr>
- * <tr><td>{@code --brief} </td><td>Whether the output should contains only
brief information.</td></tr>
- * <tr><td>{@code --verbose} </td><td>Whether the output should contains more
detailed information.</td></tr>
- * <tr><td>{@code --debug} </td><td>Prints full stack trace in case of
failure.</td></tr>
- * <tr><td>{@code --help} </td><td>Lists the options available for a
specific command.</td></tr>
+ * <tr><td>{@code --sourceCRS} </td><td>The Coordinate Reference System of
input data.</td></tr>
+ * <tr><td>{@code --targetCRS} </td><td>The Coordinate Reference System of
output data.</td></tr>
+ * <tr><td>{@code --format} </td><td>The output format: {@code xml}, {@code
wkt}, {@code wkt1} or {@code text}.</td></tr>
+ * <tr><td>{@code --locale} </td><td>The locale to use for the command
output.</td></tr>
+ * <tr><td>{@code --timezone} </td><td>The timezone for the dates to be
formatted.</td></tr>
+ * <tr><td>{@code --encoding} </td><td>The encoding to use for the command
output.</td></tr>
+ * <tr><td>{@code --colors} </td><td>Whether colorized output shall be
enabled.</td></tr>
+ * <tr><td>{@code --brief} </td><td>Whether the output should contains
only brief information.</td></tr>
+ * <tr><td>{@code --verbose} </td><td>Whether the output should contains
more detailed information.</td></tr>
+ * <tr><td>{@code --debug} </td><td>Prints full stack trace in case of
failure.</td></tr>
+ * <tr><td>{@code --help} </td><td>Lists the options available for a
specific command.</td></tr>
* </table></blockquote>
*
* The {@code --locale}, {@code --timezone} and {@code --encoding} options
apply to the command output sent
@@ -136,14 +139,9 @@ public final class Command {
final String arg = args[i];
if (arg.startsWith(Option.PREFIX)) {
final String name = arg.substring(Option.PREFIX.length());
- final Option option;
- try {
- option = Option.valueOf(name.toUpperCase(Locale.US));
- } catch (IllegalArgumentException e) {
- throw new
InvalidOptionException(Errors.format(Errors.Keys.UnknownOption_1, name), e,
name);
- }
+ final Option option = Option.forLabel(name);
if (option.hasValue) {
- i++; // Skip the next argument.
+ i++; // Skip the next argument.
}
} else {
// Takes the first non-argument option as the command name.
@@ -156,12 +154,13 @@ public final class Command {
command = new HelpCommand(-1, args);
} else {
commandName = commandName.toLowerCase(Locale.US);
- if (commandName.equals("help")) command = new
HelpCommand (commandIndex, args);
- else if (commandName.equals("about")) command = new
AboutCommand (commandIndex, args);
- else if (commandName.equals("mime-type")) command = new
MimeTypeCommand(commandIndex, args);
- else if (commandName.equals("identifier")) command = new
MetadataCommand(MetadataCommand.Info.IDENTIFIER, commandIndex, args);
- else if (commandName.equals("metadata")) command = new
MetadataCommand(MetadataCommand.Info.METADATA, commandIndex, args);
- else if (commandName.equals("crs")) command = new
MetadataCommand(MetadataCommand.Info.CRS, commandIndex, args);
+ if (commandName.equals("help")) command = new
HelpCommand (commandIndex, args);
+ else if (commandName.equals("about")) command = new
AboutCommand (commandIndex, args);
+ else if (commandName.equals("mime-type")) command = new
MimeTypeCommand (commandIndex, args);
+ else if (commandName.equals("metadata")) command = new
MetadataCommand (commandIndex, args);
+ else if (commandName.equals("crs")) command = new
CRSCommand (commandIndex, args);
+ else if (commandName.equals("identifier")) command = new
IdentifierCommand(commandIndex, args);
+ else if (commandName.equals("transform")) command = new
TransformCommand (commandIndex, args);
else throw new InvalidCommandException(Errors.format(
Errors.Keys.UnknownCommand_1, commandName),
commandName);
}
Modified:
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/CommandRunner.java
URL:
http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/CommandRunner.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/CommandRunner.java
[UTF-8] (original)
+++
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/CommandRunner.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -149,10 +149,10 @@ abstract class CommandRunner {
* The argument at index {@code commandIndex} is the name of this command,
and will be ignored except for
* the special {@value #TEST} value which is used only at JUnit testing
time.
*
- * @param commandIndex Index of the {@code args} element containing the
sub-command name.
- * @param arguments The command-line arguments provided by the user.
- * @param validOptions The command-line options allowed by this
sub-command.
- * @throws InvalidOptionException If an illegal option has been provided,
or the option has an illegal value.
+ * @param commandIndex index of the {@code args} element containing the
sub-command name.
+ * @param arguments the command-line arguments provided by the user.
+ * @param validOptions the command-line options allowed by this
sub-command.
+ * @throws InvalidOptionException if an illegal option has been provided,
or the option has an illegal value.
*/
@SuppressWarnings("UseOfSystemOutOrSystemErr")
protected CommandRunner(final int commandIndex, final String[] arguments,
final EnumSet<Option> validOptions)
@@ -170,12 +170,7 @@ abstract class CommandRunner {
}
if (arg.startsWith(Option.PREFIX)) {
final String name = arg.substring(Option.PREFIX.length());
- final Option option;
- try {
- option = Option.valueOf(name.toUpperCase(Locale.US));
- } catch (IllegalArgumentException e) {
- throw new
InvalidOptionException(Errors.format(Errors.Keys.UnknownOption_1, name), e,
name);
- }
+ final Option option = Option.forLabel(name);
if (!validOptions.contains(option)) {
throw new
InvalidOptionException(Errors.format(Errors.Keys.UnknownOption_1, name), name);
}
@@ -197,7 +192,7 @@ abstract class CommandRunner {
/*
* Process the --locale, --encoding and --colors options.
*/
- Option option = null; // In case of IllegalArgumentException.
+ Option option = null; // In
case of IllegalArgumentException.
String value = null;
final Console console;
final boolean explicitEncoding;
@@ -219,7 +214,7 @@ abstract class CommandRunner {
colors = (value != null) ? Option.COLORS.parseBoolean(value) :
(console != null) && X364.isAnsiSupported();
} catch (RuntimeException e) {
@SuppressWarnings("null") //
'option' has been assigned in 'get' argument.
- final String name = option.name().toLowerCase(Locale.US);
+ final String name = option.label();
throw new
InvalidOptionException(Errors.format(Errors.Keys.IllegalOptionValue_2, name,
value), name);
}
/*
@@ -254,7 +249,7 @@ abstract class CommandRunner {
*
* <p>An example of a pair of mutually exclusive options is {@code
--brief} and {@code --verbose}.</p>
*
- * @param exclusive Pairs of mutually exclusive options.
+ * @param exclusive pairs of mutually exclusive options.
* @return {@code true} if two mutually exclusive options exist.
*/
final boolean hasContradictoryOptions(final Option... exclusive) {
@@ -262,9 +257,7 @@ abstract class CommandRunner {
final Option o1 = exclusive[i++];
final Option o2 = exclusive[i++];
if (options.containsKey(o1) && options.containsKey(o2)) {
-
err.println(Errors.format(Errors.Keys.MutuallyExclusiveOptions_2,
- o1.name().toLowerCase(Locale.US),
- o2.name().toLowerCase(Locale.US)));
+
err.println(Errors.format(Errors.Keys.MutuallyExclusiveOptions_2, o1.label(),
o2.label()));
return true;
}
}
@@ -275,8 +268,8 @@ abstract class CommandRunner {
* Checks the size of the {@link #files} list. If the list has an
unexpected size,
* then this method prints an error message to {@link #err} and returns
{@code true}.
*
- * @param min Minimal number of files.
- * @param max Maximum number of files.
+ * @param min minimal number of files.
+ * @param max maximum number of files.
* @return {@code true} if the list size is not in the expected bounds.
*/
final boolean hasUnexpectedFileCount(final int min, final int max) {
@@ -306,8 +299,8 @@ abstract class CommandRunner {
/**
* Prints the <cite>"Can not open …"</cite> error message followed by the
message in the given exception.
*
- * @param fileIndex Index in the {@link #files} list of the file that can
not be opened.
- * @param e The exception which occurred.
+ * @param fileIndex index in the {@link #files} list of the file that can
not be opened.
+ * @param e the exception which occurred.
*/
final void canNotOpen(final int fileIndex, final Exception e) {
error(Errors.format(Errors.Keys.CanNotOpen_1, files.get(fileIndex)),
e);
@@ -316,8 +309,8 @@ abstract class CommandRunner {
/**
* Prints the given error message followed by the message in the given
exception.
*
- * @param message The message to print before the exception, or {@code
null}.
- * @param e The exception which occurred.
+ * @param message the message to print before the exception, or {@code
null}.
+ * @param e the exception which occurred.
*/
final void error(final String message, final Exception e) {
out.flush();
@@ -332,7 +325,7 @@ abstract class CommandRunner {
* Shows the help instructions for a specific command. This method is
invoked
* instead of {@link #run()} if the the user provided the {@code --help}
option.
*
- * @param commandName The command name converted to lower cases.
+ * @param commandName the command name converted to lower cases.
*/
protected void help(final String commandName) {
new HelpCommand(this).help(false, new String[] {commandName},
validOptions);
@@ -342,7 +335,7 @@ abstract class CommandRunner {
* Executes the sub-command.
*
* @return 0 on success, or an exit code if the command failed for a
reason other than a Java exception.
- * @throws Exception If an error occurred while executing the sub-command.
+ * @throws Exception if an error occurred while executing the sub-command.
*/
public abstract int run() throws Exception;
}
Modified:
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/HelpCommand.java
URL:
http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/HelpCommand.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/HelpCommand.java
[UTF-8] (original)
+++
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/HelpCommand.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -17,7 +17,6 @@
package org.apache.sis.console;
import java.util.EnumSet;
-import java.util.Locale;
import java.util.ResourceBundle;
import java.io.IOException;
import org.apache.sis.io.TableAppender;
@@ -42,7 +41,8 @@ final class HelpCommand extends CommandR
"mime-type",
"metadata",
"crs",
- "identifier"
+ "identifier",
+ "transform"
};
/**
@@ -110,7 +110,7 @@ final class HelpCommand extends CommandR
out.print(vocabulary.getString(Vocabulary.Keys.Options));
out.println(':');
for (final Option option : validOptions) {
- final String name = option.name().toLowerCase(Locale.US);
+ final String name = option.label();
table.append(" ").append(Option.PREFIX).append(name);
table.nextColumn();
table.append(options.getString(name));
Copied:
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java
(from r1740890,
sis/branches/JDK6/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java)
URL:
http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java?p2=sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java&p1=sis/branches/JDK6/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java&r1=1740890&r2=1740892&rev=1740892&view=diff
==============================================================================
---
sis/branches/JDK6/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java
[UTF-8] (original)
+++
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -38,6 +38,10 @@ import org.apache.sis.util.ComparisonMod
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.resources.Vocabulary;
+// Branch-dependent imports
+import org.apache.sis.metadata.iso.DefaultMetadata;
+import org.apache.sis.metadata.iso.DefaultIdentifier;
+
/**
* The "identifier" sub-command.
@@ -122,11 +126,11 @@ final class IdentifierCommand extends Me
}
if (metadata != null) {
final List<Row> rows;
- if (metadata instanceof Metadata) {
+ if (metadata instanceof DefaultMetadata) {
rows = new ArrayList<Row>();
- final Identifier id = ((Metadata)
metadata).getMetadataIdentifier();
- if (id != null) {
- CharSequence desc = id.getDescription();
+ final Identifier id = ((DefaultMetadata)
metadata).getMetadataIdentifier();
+ if (id instanceof DefaultIdentifier) {
+ CharSequence desc = ((DefaultIdentifier)
id).getDescription();
if (desc != null && !files.isEmpty()) desc = files.get(0);
rows.add(new Row(State.VALID,
IdentifiedObjects.toString(id), desc));
}
Modified:
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/InvalidOptionException.java
URL:
http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/InvalidOptionException.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/InvalidOptionException.java
[UTF-8] (original)
+++
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/InvalidOptionException.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -39,8 +39,8 @@ public class InvalidOptionException exte
/**
* Constructs an exception with the specified detail message.
*
- * @param message The detail message.
- * @param option The name of the invalid option.
+ * @param message the detail message.
+ * @param option the name of the invalid option.
*/
public InvalidOptionException(final String message, final String option) {
super(message);
@@ -50,9 +50,9 @@ public class InvalidOptionException exte
/**
* Constructs an exception with the specified detail message and cause.
*
- * @param message The detail message.
- * @param cause The cause of this exception.
- * @param option The name of the invalid option.
+ * @param message the detail message.
+ * @param cause the cause of this exception.
+ * @param option the name of the invalid option.
*/
public InvalidOptionException(final String message, final Throwable cause,
final String option) {
super(message, cause);
@@ -62,7 +62,7 @@ public class InvalidOptionException exte
/**
* Returns the name of the invalid option.
*
- * @return The name of the invalid option.
+ * @return the name of the invalid option.
*/
public String getOption() {
return option;
Modified:
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
URL:
http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
[UTF-8] (original)
+++
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -16,8 +16,6 @@
*/
package org.apache.sis.console;
-import java.util.List;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
@@ -28,18 +26,15 @@ import java.io.IOException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.JAXBException;
import org.opengis.metadata.Metadata;
-import org.opengis.metadata.Identifier;
-import org.opengis.util.FactoryException;
import org.opengis.referencing.ReferenceSystem;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.util.FactoryException;
import org.apache.sis.io.wkt.WKTFormat;
import org.apache.sis.io.wkt.Convention;
import org.apache.sis.io.wkt.Colors;
import org.apache.sis.metadata.MetadataStandard;
import org.apache.sis.metadata.ValueExistencePolicy;
-import org.apache.sis.metadata.iso.DefaultIdentifier;
import org.apache.sis.metadata.iso.DefaultMetadata;
-import org.apache.sis.referencing.IdentifiedObjects;
import org.apache.sis.referencing.CRS;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStores;
@@ -53,15 +48,15 @@ import org.apache.sis.xml.XML;
/**
- * The "metadata", "crs" and "identifier" subcommands.
- * CRS are considered as a kind of metadata here.
+ * The "metadata" sub-command. This class is also used as the base class of
other sub-commands
+ * that perform most of their work on the basis of metadata information.
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
* @version 0.7
* @module
*/
-final class MetadataCommand extends CommandRunner {
+class MetadataCommand extends CommandRunner {
/**
* The protocol part of the filename to be recognized as a CRS authority.
* In such case, this class will delegate to {@link CRS#forCode(String)}
@@ -75,98 +70,82 @@ final class MetadataCommand extends Comm
static final int MAX_AUTHORITY_LENGTH = 5;
/**
- * The desired information.
- */
- static enum Info {
- METADATA, CRS, IDENTIFIER
- }
-
- /**
* The output format.
*/
- private static enum Format {
+ static enum Format {
TEXT, WKT, XML
}
/**
- * The sub-command: {@code "metadata"}, {@code "crs"} or {@code
"identifier"}.
+ * The output format. Default value can be overridden by {@link
#parseArguments()}.
*/
- private final Info command;
+ Format outputFormat = Format.TEXT;
/**
- * The output format.
+ * The WKT convention, or {@code null} if it does not apply.
*/
- private Format outputFormat;
+ Convention convention;
/**
- * The WKT convention, or {@code null} if it does not apply.
+ * Sets to {@code true} by {@link #readMetadata()} if the users provided
an unexpected number of file arguments.
+ * In such case, the {@link #run()} should terminate with exit code {@link
Command#INVALID_ARGUMENT_EXIT_CODE}.
*/
- private Convention convention;
+ boolean hasUnexpectedFileCount;
/**
- * Creates the {@code "metadata"}, {@code "crs"} or {@code "identifier"}
sub-command.
+ * Creates the {@code "metadata"} sub-command.
*/
- MetadataCommand(final Info command, final int commandIndex, final
String... args) throws InvalidOptionException {
+ MetadataCommand(final int commandIndex, final String... args) throws
InvalidOptionException {
super(commandIndex, args, EnumSet.of(Option.FORMAT, Option.LOCALE,
Option.TIMEZONE, Option.ENCODING,
Option.COLORS, Option.HELP, Option.DEBUG));
- this.command = command;
+ }
+
+ /**
+ * Creates a new sub-command with the given command-line arguments.
+ * This constructor is for {@code MetadataCommand} subclasses only.
+ *
+ * @param commandIndex index of the {@code args} element containing the
sub-command name.
+ * @param arguments the command-line arguments provided by the user.
+ * @param validOptions the command-line options allowed by this
sub-command.
+ * @throws InvalidOptionException if an illegal option has been provided,
or the option has an illegal value.
+ */
+ MetadataCommand(final int commandIndex, final String[] args, final
EnumSet<Option> validOptions)
+ throws InvalidOptionException
+ {
+ super(commandIndex, args, validOptions);
}
/**
* Parses the command-line arguments and initializes the {@link
#outputFormat} and {@link #convention} fields
- * accordingly. This method verifies the parameter validity.
+ * accordingly.
*/
- private void parseArguments() throws InvalidOptionException {
+ final void parseArguments() throws InvalidOptionException {
/*
* Output format can be either "text" (the default) or "xml".
* In the case of "crs" sub-command, we accept also WKT variants.
*/
final String format = options.get(Option.FORMAT);
- if (format == null || format.equalsIgnoreCase("text")) {
- if (command == Info.CRS) {
+ if (format != null && !format.equalsIgnoreCase("text")) {
+ if (format.equalsIgnoreCase("wkt") ||
format.equalsIgnoreCase("wkt2")) {
outputFormat = Format.WKT;
- convention = Convention.WKT2_SIMPLIFIED;
+ convention = Convention.WKT2;
+ } else if (format.equalsIgnoreCase("wkt1")) {
+ outputFormat = Format.WKT;
+ convention = Convention.WKT1;
+ } else if (format.equalsIgnoreCase("xml")) {
+ outputFormat = Format.XML;
} else {
- outputFormat = Format.TEXT;
- }
- } else if (format.equalsIgnoreCase("wkt") ||
format.equalsIgnoreCase("wkt2")) {
- outputFormat = Format.WKT;
- convention = Convention.WKT2;
- } else if (format.equalsIgnoreCase("wkt1")) {
- outputFormat = Format.WKT;
- convention = Convention.WKT1;
- } else if (format.equalsIgnoreCase("xml")) {
- outputFormat = Format.XML;
- } else {
- throw new InvalidOptionException(Errors.format(
- Errors.Keys.IllegalOptionValue_2, "format", format),
format);
- }
- final boolean isFormatCompatible;
- switch (command) {
- case CRS: {
- isFormatCompatible = true;
- break;
- }
- case IDENTIFIER: {
- isFormatCompatible = (outputFormat == Format.TEXT);
- break;
- }
- default: {
- isFormatCompatible = (convention == null);
- break;
+ throw new InvalidOptionException(Errors.format(
+ Errors.Keys.IllegalOptionValue_2, "format", format),
format);
}
}
- if (!isFormatCompatible) {
- throw new
InvalidOptionException(Errors.format(Errors.Keys.IncompatibleFormat_2,
- command.name().toLowerCase(locale), format), format);
- }
}
/**
- * If the given argument begins with one of the known authorities ("URN",
"EPSG", "CRS", "AUTO", <i>etc.</i>),
- * delegates to {@link CRS#forCode(String)} and wraps in a metadata
object. Otherwise returns {@code null}.
+ * Returns {@code true} if the given argument begins with one of the known
authorities
+ * ("URN", "EPSG", "CRS", "AUTO", <i>etc.</i>).
*/
- private static Metadata fromDatabase(final String code) throws
FactoryException {
+ static boolean isAuthorityCode(final String code) {
final char[] authority = new char[MAX_AUTHORITY_LENGTH];
final int length = code.length();
int p = 0, i = 0;
@@ -176,9 +155,7 @@ final class MetadataCommand extends Comm
if (!AUTHORITIES.contains(new String(authority, 0, p))) {
break;
}
- final DefaultMetadata metadata = new DefaultMetadata();
-
metadata.setReferenceSystemInfo(Collections.singleton(CRS.forCode(code)));
- return metadata;
+ return true;
}
if (!Character.isWhitespace(c)) {
if (p >= MAX_AUTHORITY_LENGTH ||
!Character.isLetterOrDigit(c)) {
@@ -187,93 +164,87 @@ final class MetadataCommand extends Comm
/*
* Casting to char is okay because AUTHORITIES contains only
ASCII values.
* If 'c' was a supplemental Unicode value, then the result of
the cast
- * will not match any AUTHORITIES value anyway.
+ * would not match any AUTHORITIES value anyway.
*/
authority[p++] = (char) Character.toUpperCase(c);
}
i += Character.charCount(c);
}
- return null;
+ return false;
}
/**
- * Prints metadata or CRS information.
+ * If the given argument begins with one of the known authorities ("URN",
"EPSG", "CRS", "AUTO", <i>etc.</i>),
+ * delegates to {@link CRS#forCode(String)}. Otherwise reads the metadata
using a datastore.
*
- * @throws DataStoreException if an error occurred while reading the file.
- * @throws JAXBException if an error occurred while producing the XML
output.
- * @throws FactoryException if an error occurred while looking for a CRS
identifier.
- * @throws IOException should never happen, since we are appending to a
print writer.
+ * @return A {@link Metadata} or {@link CoordinateReferenceSystem}
instance, or {@code null} if none.
*/
- @Override
- @SuppressWarnings("UseOfSystemOutOrSystemErr")
- public int run() throws InvalidOptionException, DataStoreException,
JAXBException, FactoryException, IOException {
- parseArguments();
- /*
- * Read metadata from the data storage only after we verified that the
arguments are valid.
- * The input can be a file given on the command line, or the standard
input stream.
- */
- Metadata metadata;
+ final Object readMetadataOrCRS() throws DataStoreException,
FactoryException {
if (useStandardInput()) {
final DataStore store = DataStores.open(System.in);
try {
- metadata = store.getMetadata();
+ return store.getMetadata();
} finally {
store.close();
}
+ } else if (hasUnexpectedFileCount(1, 1)) {
+ hasUnexpectedFileCount = true;
+ return null;
} else {
- if (hasUnexpectedFileCount(1, 1)) {
- return Command.INVALID_ARGUMENT_EXIT_CODE;
- }
final String file = files.get(0);
- metadata = fromDatabase(file);
- if (metadata == null) {
+ if (isAuthorityCode(file)) {
+ return CRS.forCode(file);
+ } else {
final DataStore store = DataStores.open(file);
try {
- metadata = store.getMetadata();
+ return store.getMetadata();
} finally {
store.close();
}
}
}
- if (metadata == null) {
- return 0;
+ }
+
+ /**
+ * Prints metadata or CRS information.
+ *
+ * @throws DataStoreException if an error occurred while reading the file.
+ * @throws JAXBException if an error occurred while producing the XML
output.
+ * @throws FactoryException if an error occurred while looking for a CRS
identifier.
+ * @throws IOException should never happen, since we are appending to a
print writer.
+ */
+ @Override
+ public int run() throws Exception {
+ parseArguments();
+ if (convention != null) {
+ final String format = outputFormat.name();
+ throw new
InvalidOptionException(Errors.format(Errors.Keys.IncompatibleFormat_2,
"metadata", format), format);
}
/*
- * If we are executing the "identifier" sub-command, then show the
metadata identifier (if any)
- * and the identifier of all referencing systems found. Otherwise if
we are executing the "crs"
- * sub-command, extract only the first CRS. That CRS will be displayed
after the switch statement.
+ * Read metadata from the data storage only after we verified that the
arguments are valid.
+ * The input can be a file given on the command line, or the standard
input stream.
*/
- Object object = metadata;
-choice: switch (command) {
- case IDENTIFIER: {
- final List<IdentifierRow> rows = new
ArrayList<IdentifierRow>();
- if (metadata instanceof DefaultMetadata) {
- final Identifier id = ((DefaultMetadata)
metadata).getMetadataIdentifier();
- if (id instanceof DefaultIdentifier) {
- CharSequence desc = ((DefaultIdentifier)
id).getDescription();
- if (desc != null && !files.isEmpty()) desc =
files.get(0);
- rows.add(new IdentifierRow(IdentifierRow.State.VALID,
IdentifiedObjects.toString(id), desc));
- }
- }
- for (final ReferenceSystem rs :
metadata.getReferenceSystemInfo()) {
- rows.add(IdentifierRow.create(rs));
- }
- IdentifierRow.print(rows, out, locale, colors);
- return 0;
- }
- case CRS: {
- for (final ReferenceSystem rs :
metadata.getReferenceSystemInfo()) {
- if (rs instanceof CoordinateReferenceSystem) {
- object = rs;
- break choice;
- }
- }
- return 0;
+ Object metadata = readMetadataOrCRS();
+ if (hasUnexpectedFileCount) {
+ return Command.INVALID_ARGUMENT_EXIT_CODE;
+ }
+ if (metadata != null) {
+ if (!(metadata instanceof Metadata)) {
+ final DefaultMetadata md = new DefaultMetadata();
+
md.setReferenceSystemInfo(Collections.singleton((ReferenceSystem) metadata));
+ metadata = md;
}
+ format(metadata);
}
- /*
- * Format metadata to the standard output stream.
- */
+ return 0;
+ }
+
+ /**
+ * Format the given metadata or CRS object to the standard output stream.
+ * The format is determined by {@link #outputFormat} and (in WKT case
only) {@link #convention}.
+ */
+ @SuppressWarnings("UseOfSystemOutOrSystemErr")
+ final void format(final Object object) throws IOException, JAXBException {
switch (outputFormat) {
case TEXT: {
final TreeTable tree =
MetadataStandard.ISO_19115.asTreeTable(object, ValueExistencePolicy.NON_EMPTY);
@@ -313,7 +284,6 @@ choice: switch (command) {
}
}
out.flush();
- return 0;
}
/**
Modified:
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Option.java
URL:
http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Option.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Option.java
[UTF-8] (original)
+++
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Option.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -30,6 +30,16 @@ import org.apache.sis.util.resources.Err
*/
enum Option {
/**
+ * The Coordinate Reference System of input data.
+ */
+ SOURCE_CRS(true),
+
+ /**
+ * The Coordinate Reference System of input data.
+ */
+ TARGET_CRS(true),
+
+ /**
* The output format. Examples: {@code "xml"}, {@code "text"}.
*/
FORMAT(true),
@@ -95,6 +105,14 @@ enum Option {
};
/**
+ * The string representation of this option, as used on the command line.
+ * This is usually the lower-case version of {@link #name()}.
+ *
+ * @see #label()
+ */
+ private String label;
+
+ /**
* Whether this option expects a value.
*/
final boolean hasValue;
@@ -102,13 +120,43 @@ enum Option {
/**
* Creates a new option.
*
- * @param hasValue Whether this option expects a value.
+ * @param hasValue whether this option expects a value.
*/
private Option(final boolean hasValue) {
this.hasValue = hasValue;
}
/**
+ * Special case for which {@code label()} should not be only the
lower-case of enum name.
+ */
+ static {
+ SOURCE_CRS.label = "sourceCRS";
+ TARGET_CRS.label = "targetCRS";
+ }
+
+ /**
+ * Return the string representation as used on the command line.
+ */
+ String label() {
+ if (label == null) {
+ label = name().toLowerCase(Locale.US);
+ }
+ return label;
+ }
+
+ /**
+ * Returns the option for the given string.
+ */
+ static Option forLabel(final String label) throws InvalidOptionException {
+ for (final Option option : values()) {
+ if (label.equalsIgnoreCase(option.name().replace("_", ""))) {
+ return option;
+ }
+ }
+ throw new
InvalidOptionException(Errors.format(Errors.Keys.UnknownOption_1, label),
label);
+ }
+
+ /**
* Parses the given value as a boolean.
*
* @param value The value to parse.
Modified:
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands.properties
URL:
http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands.properties?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands.properties
[ISO-8859-1] (original)
+++
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands.properties
[ISO-8859-1] Mon Apr 25 20:30:40 2016
@@ -8,3 +8,4 @@ mime-type=Show MIME type for the given f
metadata=Show metadata information for the given file.
crs=Show Coordinate Reference System (CRS) information for the given file.
identifier=Show identifiers for metadata and referencing systems in the given
file.
+transform=Convert or transform coordinates from given source CRS to target CRS.
Modified:
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands_fr.properties
URL:
http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands_fr.properties?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands_fr.properties
[ISO-8859-1] (original)
+++
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands_fr.properties
[ISO-8859-1] Mon Apr 25 20:30:40 2016
@@ -8,3 +8,4 @@ mime-type=Affiche le type MIME du fichie
metadata=Affiche les méta-données du fichier spécifié.
crs=Affiche le système de référence des coordonnées du fichier spécifié.
identifier=Affiche les identifiants des méta-données et des systèmes de
références du fichier spécifié.
+transform=Transforme des coordonnées du système de référence source vers le
système destination donné.
Modified:
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties
URL:
http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties
[ISO-8859-1] (original)
+++
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties
[ISO-8859-1] Mon Apr 25 20:30:40 2016
@@ -1,4 +1,6 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.
+sourceCRS=The Coordinate Reference System of input data.
+targetCRS=The Coordinate Reference System of output data.
format=The output format: xml, wkt, wkt1 or text.
locale=The locale to use for the command output.
timezone=The timezone for the dates to be formatted.
Modified:
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties
URL:
http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties
[ISO-8859-1] (original)
+++
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties
[ISO-8859-1] Mon Apr 25 20:30:40 2016
@@ -1,4 +1,6 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.
+sourceCRS=Le système de référence des coordonnées source.
+targetCRS=Le système de référence des coordonnées destination.
format=Le format de sortie: xml, wkt, wkt1 ou text.
locale=Les paramètres régionaux à utiliser pour la sortie de la commande.
timezone=Le fuseau horaire des dates à écrire.
Modified:
sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/MetadataCommandTest.java
URL:
http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/MetadataCommandTest.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/MetadataCommandTest.java
[UTF-8] (original)
+++
sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/MetadataCommandTest.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -59,7 +59,7 @@ public final strictfp class MetadataComm
public void testNetCDF() throws Exception {
final URL url = MetadataCommandTest.class.getResource("NCEP-SST.nc");
assertNotNull("NCEP-SST.nc", url);
- final MetadataCommand test = new
MetadataCommand(MetadataCommand.Info.METADATA, 0, CommandRunner.TEST,
url.toString());
+ final MetadataCommand test = new MetadataCommand(0,
CommandRunner.TEST, url.toString());
test.run();
verifyNetCDF("Metadata", test.outputBuffer.toString());
}
@@ -86,8 +86,7 @@ public final strictfp class MetadataComm
@DependsOnMethod("testNetCDF")
public void testFormatXML() throws Exception {
final URL url = MetadataCommandTest.class.getResource("NCEP-SST.nc");
- final MetadataCommand test = new
MetadataCommand(MetadataCommand.Info.METADATA,
- 0, CommandRunner.TEST, url.toString(), "--format", "XML");
+ final MetadataCommand test = new MetadataCommand(0,
CommandRunner.TEST, url.toString(), "--format", "XML");
test.run();
verifyNetCDF("<?xml", test.outputBuffer.toString());
}
Modified:
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
[UTF-8] (original)
+++
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -431,6 +431,8 @@ public abstract class Initializer {
* @return {@code true} if the exception indicates a successful shutdown.
*/
static boolean isSuccessfulShutdown(final SQLException e) {
- return e.getErrorCode() == 45000 && "08006".equals(e.getSQLState());
+ final String state = e.getSQLState();
+ return "08006".equals(state) || // Database 'SpatialMetadata'
shutdown.
+ "XJ004".equals(state); // Database 'SpatialMetadata' not
found (may happen if we failed to open it in the first place).
}
}
Modified:
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
[UTF-8] (original)
+++
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -83,13 +83,6 @@ abstract class AbstractParser implements
static final int MANDATORY = 2;
/**
- * The logger to use for reporting warnings when this parser is used
through the {@link #createFromWKT(String)}.
- * This happen most often when the user invoke the {@link
org.apache.sis.referencing.CRS#fromWKT(String)}
- * convenience method.
- */
- private static final Logger LOGGER = Logging.getLogger(Loggers.WKT);
-
- /**
* The locale for error messages (not for number parsing), or {@code null}
for the system default.
*/
final Locale errorLocale;
@@ -196,6 +189,14 @@ abstract class AbstractParser implements
abstract String getPublicFacade();
/**
+ * Returns the name of the method invoked from {@link #getPublicFacade()}.
+ * This information is used for logging purpose only.
+ */
+ String getFacadeMethod() {
+ return "createFromWKT";
+ }
+
+ /**
* Creates the object from a string. This method is for implementation of
{@code createFromWKT(String)}
* method is SIS factories only.
*
@@ -220,16 +221,24 @@ abstract class AbstractParser implements
}
final Warnings warnings = getAndClearWarnings(value);
if (warnings != null) {
- final LogRecord record = new LogRecord(Level.WARNING,
warnings.toString());
- record.setSourceClassName(getPublicFacade());
- record.setSourceMethodName("createFromWKT");
- record.setLoggerName(LOGGER.getName());
- LOGGER.log(record);
+ log(new LogRecord(Level.WARNING, warnings.toString()));
}
return value;
}
/**
+ * Logs the given record. This is used only when we can not use the {@link
#warning warning methods},
+ * or when the information is not worth to report as a warning.
+ */
+ final void log(final LogRecord record) {
+ Logger logger = Logging.getLogger(Loggers.WKT);
+ record.setSourceClassName(getPublicFacade());
+ record.setSourceMethodName(getFacadeMethod());
+ record.setLoggerName(logger.getName());
+ logger.log(record);
+ }
+
+ /**
* Returns the index after the end of the fragment name starting at the
given index.
* Current implementation assumes that the fragment name is a Unicode
identifier.
*/
@@ -323,7 +332,7 @@ abstract class AbstractParser implements
/**
* Parses the given unit symbol.
*/
- final Unit<?> parseUnit(final String text) throws ParseException {
+ final Unit<?> parseUnit(final String text) throws ParseException,
IllegalArgumentException {
if (unitFormat == null) {
if (symbols.getLocale() == Locale.ROOT) {
return Units.valueOf(text); // Most common case,
avoid the convolved code below.
Modified:
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
[UTF-8] (original)
+++
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -696,7 +696,8 @@ public class Formatter implements Locali
info = ((GeneralParameterValue) object).getDescriptor();
}
if (info != null) {
- appendComplement(info, (stackDepth != 0) ?
enclosingElements.get(stackDepth - 1) : null);
+ appendComplement(info, (stackDepth >= 1) ?
enclosingElements.get(stackDepth - 1) : null,
+ (stackDepth >= 2) ?
enclosingElements.get(stackDepth - 2) : null);
}
buffer.appendCodePoint(symbols.getClosingBracket(0));
indent(-1);
@@ -711,9 +712,10 @@ public class Formatter implements Locali
* and have a special treatment: they are written by {@link
#append(FormattableObject)}
* after the {@code formatTo(Formatter)} method returned.
*
- * <p>The {@code ID[<name>,<code>,…]} element is written only for the root
element, unless the convention are
- * INTERNAL. If formatted, the ID element will be on the same line than
the enclosing one if no line separator
- * were requested (e.g. SPHEROID["Clarke 1866", …, ID["EPSG", 7008]]), or
on a new line otherwise. Example:</p>
+ * <p>The {@code ID[<name>,<code>,…]} element is normally written only for
the root element
+ * (unless the convention is {@code INTERNAL}), but there is various
exceptions to this rule.
+ * If formatted, the {@code ID} element will be by default on the same
line than the enclosing
+ * element (e.g. {@code SPHEROID["Clarke 1866", …, ID["EPSG", 7008]]}).
Other example:</p>
*
* {@preformat text
* PROJCS["NAD27 / Idaho Central",
@@ -734,7 +736,7 @@ public class Formatter implements Locali
* A {@code <remark>} can be included within the descriptions of source
and target CRS embedded within
* a coordinate transformation as well as within the coordinate
transformation itself.</blockquote>
*/
- private void appendComplement(final IdentifiedObject object, final
FormattableObject parent) {
+ private void appendComplement(final IdentifiedObject object, final
FormattableObject parent, final FormattableObject gp) {
isComplement = true;
final boolean showIDs; // Whether to format ID[…] elements.
final boolean filterID; // Whether we shall limit to a single
ID[…] element.
@@ -757,6 +759,9 @@ public class Formatter implements Locali
*/
if (parent == null || parent instanceof CompoundCRS) {
showIDs = true;
+ } else if (gp instanceof CoordinateOperation && !(parent
instanceof IdentifiedObject)) {
+ // "SourceCRS[…]" and "TargetCRS[…]" sub-elements in
CoordinateOperation.
+ showIDs = true;
} else if (convention == Convention.WKT2_SIMPLIFIED) {
showIDs = false;
} else {
@@ -773,7 +778,7 @@ public class Formatter implements Locali
showRemarks = showOthers;
} else if (object instanceof ReferenceSystem) {
showOthers = (parent == null);
- showRemarks = (parent == null) || (getEnclosingElement(2)
instanceof CoordinateOperation);
+ showRemarks = (parent == null) || (gp instanceof
CoordinateOperation);
} else {
showOthers = false; // Mandated by ISO 19162.
showRemarks = false;
Modified:
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
[UTF-8] (original)
+++
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -26,6 +26,8 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParsePosition;
@@ -38,6 +40,7 @@ import javax.measure.quantity.Angle;
import javax.measure.quantity.Length;
import javax.measure.quantity.Quantity;
import javax.measure.quantity.Duration;
+import javax.measure.converter.ConversionException;
import org.opengis.util.Factory;
import org.opengis.metadata.Identifier;
@@ -71,6 +74,7 @@ import org.apache.sis.internal.metadata.
import org.apache.sis.internal.metadata.TransformationAccuracy;
import org.apache.sis.internal.util.LocalizedParseException;
import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.internal.util.Numerics;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.iso.DefaultNameSpace;
@@ -92,7 +96,7 @@ import static java.util.Collections.sing
* @version 0.7
* @module
*/
-final class GeodeticObjectParser extends MathTransformParser implements
Comparator<CoordinateSystemAxis> {
+class GeodeticObjectParser extends MathTransformParser implements
Comparator<CoordinateSystemAxis> {
/**
* The names of the 7 parameters in a {@code TOWGS84[…]} element.
* Those names are derived from the <cite>Well Known Text</cite> (WKT)
version 1 specification.
@@ -277,7 +281,7 @@ final class GeodeticObjectParser extends
* @throws ParseException if the string can not be parsed.
*/
@Override
- public Object parseObject(final String text, final ParsePosition position)
throws ParseException {
+ public final Object parseObject(final String text, final ParsePosition
position) throws ParseException {
final Object object;
try {
object = super.parseObject(text, position);
@@ -321,7 +325,7 @@ final class GeodeticObjectParser extends
* @throws ParseException if the element can not be parsed.
*/
@Override
- Object parseObject(final Element element) throws ParseException {
+ final Object parseObject(final Element element) throws ParseException {
Object value = parseCoordinateReferenceSystem(element, false);
if (value != null) {
return value;
@@ -617,7 +621,7 @@ final class GeodeticObjectParser extends
* @return The {@code "UNIT"} element as an {@link Unit} object, or {@code
null} if none.
* @throws ParseException if the {@code "UNIT"} can not be parsed.
*
- * @todo Authority code is currently ignored. We may consider to create a
subclass of
+ * @todo Authority code is currently discarded after parsing. We may
consider to create a subclass of
* {@link Unit} which implements {@link IdentifiedObject} in a
future version.
*/
@SuppressWarnings("unchecked")
@@ -630,16 +634,48 @@ final class GeodeticObjectParser extends
}
final String name = element.pullString("name");
final double factor = element.pullDouble("factor");
- final Unit<?> unit = parseUnitID(element);
+ Unit<Q> unit = Units.multiply(baseUnit, factor);
+ Unit<?> verify = parseUnitID(element);
element.close(ignoredElements);
- if (unit != null) {
- if (baseUnit.toSI().equals(unit.toSI())) {
- return (Unit<Q>) unit;
+ /*
+ * Consider the following element: UNIT[“km”, 1000, ID[“EPSG”, “9036”]]
+ *
+ * - if the authority code (“9036”) refers to a unit incompatible
with 'baseUnit' (“metre”), log a warning.
+ * - otherwise: 1) unconditionally replace the parsed unit (“km”) by
the unit referenced by the authority code.
+ * 2) if the new unit is not equivalent to the old one
(i.e. different scale factor), log a warning.
+ */
+ if (verify != null) {
+ if (!baseUnit.toSI().equals(verify.toSI())) {
+ warning(parent, element,
Errors.formatInternational(Errors.Keys.InconsistentUnitsForCS_1, verify), null);
+ } else if (Math.abs(unit.getConverterTo(unit = (Unit<Q>)
verify).convert(1) - 1) > Numerics.COMPARISON_THRESHOLD) {
+ warning(parent, element,
Errors.formatInternational(Errors.Keys.UnexpectedScaleFactorForUnit_2, verify,
factor), null);
} else {
- warning(parent, element,
Errors.formatInternational(Errors.Keys.IllegalUnitFor_2, keyword, unit), null);
+ verify = null; //
Means to perform additional verifications.
+ }
+ }
+ /*
+ * Above block verified the ID[“EPSG”, “9036”] authority code. Now
verify the unit parsed from the “km” symbol.
+ * This is only a verification; we will not replace the unit by the
parsed one (i.e. authority code or scale
+ * factor have precedence over the unit symbol).
+ */
+ if (verify == null) {
+ try {
+ verify = parseUnit(name);
+ } catch (IllegalArgumentException e) {
+ log(new LogRecord(Level.FINE, e.toString()));
+ } catch (ParseException e) {
+ log(new LogRecord(Level.FINE, e.toString()));
+ }
+ if (verify != null) try {
+ if (Math.abs(verify.getConverterToAny(unit).convert(1) - 1) >
Numerics.COMPARISON_THRESHOLD) {
+ warning(parent, element,
Errors.formatInternational(Errors.Keys.UnexpectedScaleFactorForUnit_2, verify,
factor), null);
+ }
+ } catch (ConversionException e) {
+ throw (ParseException) new LocalizedParseException(errorLocale,
+ Errors.Keys.InconsistentUnitsForCS_1, new Object[]
{verify}, element.offset).initCause(e);
}
}
- return Units.multiply(baseUnit, factor);
+ return unit;
}
/**
@@ -1091,7 +1127,7 @@ final class GeodeticObjectParser extends
* 0 if undetermined (no axis order change).
*/
@Override
- public int compare(final CoordinateSystemAxis o1, final
CoordinateSystemAxis o2) {
+ public final int compare(final CoordinateSystemAxis o1, final
CoordinateSystemAxis o2) {
final Integer n1 = axisOrder.get(o1);
final Integer n2 = axisOrder.get(o2);
if (n1 != null) {
Modified:
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
[UTF-8] (original)
+++
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -245,7 +245,12 @@ class MathTransformParser extends Abstra
return Units.multiply(BASE_UNITS[index], factor);
}
// If we can not infer the base type, we have to rely on the name.
- return parseUnit(name);
+ try {
+ return parseUnit(name);
+ } catch (IllegalArgumentException e) {
+ throw (ParseException) new LocalizedParseException(errorLocale,
+ Errors.Keys.UnknownUnit_1, new Object[] {name},
element.offset).initCause(e);
+ }
}
/**
Modified:
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
[UTF-8] (original)
+++
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -708,7 +708,7 @@ public class WKTFormat extends CompoundF
private AbstractParser parser() {
AbstractParser parser = this.parser;
if (parser == null) {
- this.parser = parser = new GeodeticObjectParser(symbols,
fragments(),
+ this.parser = parser = new Parser(symbols, fragments(),
(NumberFormat) getFormat(Number.class),
(DateFormat) getFormat(Date.class),
(UnitFormat) getFormat(Unit.class),
@@ -721,6 +721,23 @@ public class WKTFormat extends CompoundF
}
/**
+ * The parser created by {@link #parser()}, identical to {@link
GeodeticObjectParser} except for
+ * the source of logging messages which is the enclosing {@code WKTParser}
instead than a factory.
+ */
+ private static final class Parser extends GeodeticObjectParser {
+ Parser(final Symbols symbols, final Map<String,Element> fragments,
+ final NumberFormat numberFormat, final DateFormat dateFormat,
final UnitFormat unitFormat,
+ final Convention convention, final Transliterator
transliterator, final Locale errorLocale,
+ final Map<Class<?>,Factory> factories)
+ {
+ super(symbols, fragments, numberFormat, dateFormat, unitFormat,
convention, transliterator, errorLocale, factories);
+ }
+
+ @Override String getPublicFacade() {return WKTFormat.class.getName();}
+ @Override String getFacadeMethod() {return "parse";}
+ }
+
+ /**
* Formats the specified object as a Well Know Text. The formatter accepts
at least the following types:
* {@link FormattableObject}, {@link IdentifiedObject},
* {@link org.opengis.referencing.operation.MathTransform},
Modified:
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
[UTF-8] (original)
+++
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -43,6 +43,7 @@ import org.apache.sis.internal.metadata.
import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.referencing.factory.IdentifiedObjectFinder;
import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
+import org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException;
import static org.apache.sis.internal.util.Citations.iterator;
import static org.apache.sis.internal.util.Citations.identifierMatches;
@@ -515,14 +516,17 @@ public final class IdentifiedObjects ext
* @param authority The authority of the objects to search (typically
{@code "EPSG"} or {@code "OGC"}),
* or {@code null} for searching among the objects created by all
authorities.
* @return A finder to use for looking up unidentified objects.
- * @throws FactoryException if the finder can not be created.
+ * @throws NoSuchAuthorityFactoryException if the given authority is not
found.
+ * @throws FactoryException if the finder can not be created for another
reason.
*
* @see #lookupEPSG(IdentifiedObject)
* @see #lookupURN(IdentifiedObject, Citation)
* @see
org.apache.sis.referencing.factory.GeodeticAuthorityFactory#newIdentifiedObjectFinder()
* @see IdentifiedObjectFinder#find(IdentifiedObject)
*/
- public static IdentifiedObjectFinder newFinder(final String authority)
throws FactoryException {
+ public static IdentifiedObjectFinder newFinder(final String authority)
+ throws NoSuchAuthorityFactoryException, FactoryException
+ {
final GeodeticAuthorityFactory factory;
if (authority == null) {
factory = AuthorityFactories.ALL;
Modified:
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
[UTF-8] (original)
+++
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -42,6 +42,7 @@ import org.opengis.referencing.cs.*;
import org.opengis.referencing.crs.*;
import org.opengis.referencing.datum.*;
import org.opengis.referencing.operation.*;
+import org.opengis.parameter.ParameterNotFoundException;
import org.apache.sis.referencing.cs.*;
import org.apache.sis.referencing.crs.*;
import org.apache.sis.referencing.datum.*;
@@ -1639,7 +1640,25 @@ public class GeodeticObjectFactory exten
} catch (Exception e) { // (ReflectiveOperationException) on JDK7
branch.
throw new FactoryException(e);
}
- final Object object = p.createFromWKT(text);
+ final Object object;
+ try {
+ object = p.createFromWKT(text);
+ } catch (FactoryException e) {
+ /*
+ * In the case of map projection, the parsing may fail because a
projection parameter is not known to SIS.
+ * If this happen, replace the generic exception thrown be the
parser (which is FactoryException) by a
+ * more specific one. Note that InvalidGeodeticParameterException
is defined only in this sis-referencing
+ * module, so we could not throw it from the sis-metadata module
that contain the parser.
+ */
+ Throwable cause = e.getCause();
+ while (cause != null) {
+ if (cause instanceof ParameterNotFoundException) {
+ throw new
InvalidGeodeticParameterException(e.getMessage(), cause); // More accurate
exception.
+ }
+ cause = cause.getCause();
+ }
+ throw e;
+ }
parser.set(p);
if (object instanceof CoordinateReferenceSystem) {
return (CoordinateReferenceSystem) object;
Modified:
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
[UTF-8] (original)
+++
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -17,7 +17,6 @@
package org.apache.sis.referencing.factory;
import java.util.Set;
-import java.util.Iterator;
import java.util.Collections;
import java.util.LinkedHashSet;
import org.opengis.util.GenericName;
@@ -338,11 +337,16 @@ public class IdentifiedObjectFinder {
/**
* Lookups only one object which is approximatively equal to the specified
object.
- * If the set returned by {@link #find(IdentifiedObject)} contains exactly
one element,
- * then that element is returned. Otherwise this method returns {@code
null}.
+ * This method invokes {@link #find(IdentifiedObject)}, then examine the
returned {@code Set} as below:
*
- * <p>This method returns {@code null} if there is more than one element
- * because in such case we consider that there is an ambiguity.</p>
+ * <ul>
+ * <li>If the set is empty, then this method returns {@code null}.</li>
+ * <li>If the set contains exactly one element, then this method returns
that element.</li>
+ * <li>If the set contains more than one element, but only one element
has the same axis order
+ * than {@code object} and all other elements have different axis
order,
+ * then this method returns the single element having the same axis
order.</li>
+ * <li>Otherwise this method considers that there is ambiguity and
returns {@code null}.</li>
+ * </ul>
*
* @param object The object looked up.
* @return The identified object, or {@code null} if none or ambiguous.
@@ -353,18 +357,25 @@ public class IdentifiedObjectFinder {
* Do not invoke Set.size() because it may be a costly operation if
the subclass
* implements a mechanism that create IdentifiedObject instances only
on demand.
*/
+ IdentifiedObject result = null;
+ boolean sameAxisOrder = false;
+ boolean ambiguous = false;
try {
- final Iterator<IdentifiedObject> it = find(object).iterator();
- if (it.hasNext()) {
- final IdentifiedObject candidate = it.next();
- if (!it.hasNext()) {
- return candidate;
+ for (final IdentifiedObject candidate : find(object)) {
+ final boolean so = !ignoreAxes ||
Utilities.deepEquals(candidate, object, COMPARISON_MODE);
+ if (result != null) {
+ ambiguous = true;
+ if (sameAxisOrder && so) {
+ return null; // Found two matches even when
taking in account axis order.
+ }
}
+ result = candidate;
+ sameAxisOrder = so;
}
} catch (BackingStoreException e) {
throw e.unwrapOrRethrow(FactoryException.class);
}
- return null;
+ return (sameAxisOrder || !ambiguous) ? result : null;
}
/**
Modified:
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
[UTF-8] (original)
+++
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -1435,13 +1435,14 @@ addURIs: for (int i=0; ; i++) {
* may be recreated every time a deprecated
ProjectedCRS is created, we temporarily
* shutdown the loggings in order to avoid the
same warning to be logged many time.
*/
+ final boolean old = quiet;
try {
quiet = true;
replaceDeprecatedCS = true;
baseCRS =
createCoordinateReferenceSystem(geoCode); // Do not cache that CRS.
} finally {
replaceDeprecatedCS = false;
- quiet = false;
+ quiet = old;
}
/*
* The crsFactory method calls will indirectly
create a parameterized MathTransform.
Modified:
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
[UTF-8] (original)
+++
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -929,6 +929,7 @@ check: for (int isTarget=0; ; isTar
return type;
}
});
+ formatter.newLine();
}
}
Modified:
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
[UTF-8] (original)
+++
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -581,8 +581,9 @@ public class CoordinateOperationFinder e
if (!(interpolationCS instanceof EllipsoidalCS)) {
final EllipsoidalCS cs =
CommonCRS.WGS84.geographic3D().getCoordinateSystem();
if (!equalsIgnoreMetadata(interpolationCS, cs)) {
- step1 = createOperation(sourceCRS, factorySIS.getCRSFactory()
- .createGeographicCRS(derivedFrom(sourceCRS),
sourceCRS.getDatum(), cs));
+ final GeographicCRS stepCRS = factorySIS.getCRSFactory()
+ .createGeographicCRS(derivedFrom(sourceCRS),
sourceCRS.getDatum(), cs);
+ step1 = createOperation(sourceCRS,
toAuthorityDefinition(GeographicCRS.class, stepCRS));
interpolationCRS = step1.getTargetCRS();
interpolationCS = interpolationCRS.getCoordinateSystem();
}
@@ -611,12 +612,13 @@ public class CoordinateOperationFinder e
heightCS = heightCRS.getCoordinateSystem();
isEllipsoidalHeight = equalsIgnoreMetadata(heightCS.getAxis(0),
expectedAxis);
if (!isEllipsoidalHeight) {
- heightCS =
factorySIS.getCSFactory().createVerticalCS(derivedFrom(heightCS), expectedAxis);
+ heightCS = toAuthorityDefinition(VerticalCS.class,
factorySIS.getCSFactory()
+ .createVerticalCS(derivedFrom(heightCS),
expectedAxis));
}
}
if (!isEllipsoidalHeight) { // 'false' if we need
to change datum, unit or axis direction.
- heightCRS = factorySIS.getCRSFactory()
- .createVerticalCRS(derivedFrom(heightCRS),
CommonCRS.Vertical.ELLIPSOIDAL.datum(), heightCS);
+ heightCRS = toAuthorityDefinition(VerticalCRS.class,
factorySIS.getCRSFactory()
+ .createVerticalCRS(derivedFrom(heightCRS),
CommonCRS.Vertical.ELLIPSOIDAL.datum(), heightCS));
}
if (heightCRS != targetCRS) {
step3 = createOperation(heightCRS, targetCRS); // May need
interpolationCRS for performing datum change.
@@ -787,7 +789,8 @@ public class CoordinateOperationFinder e
if (stepComponents.length == 1) {
stepSourceCRS = stepComponents[0]; // Slight optimization
of the next block (in the 'else' case).
} else {
- stepSourceCRS =
factorySIS.getCRSFactory().createCompoundCRS(derivedFrom(sourceCRS),
stepComponents);
+ stepSourceCRS =
toAuthorityDefinition(CoordinateReferenceSystem.class,
+
factorySIS.getCRSFactory().createCompoundCRS(derivedFrom(sourceCRS),
stepComponents));
}
operation = createFromAffineTransform(AXIS_CHANGES, sourceCRS,
stepSourceCRS, select);
}
@@ -818,8 +821,8 @@ public class CoordinateOperationFinder e
} else if (stepComponents.length == 1) {
stepTargetCRS = target; // Slight optimization
of the next block.
} else {
- stepTargetCRS =
ReferencingServices.getInstance().createCompoundCRS(
- factorySIS.getCRSFactory(), factorySIS.getCSFactory(),
derivedFrom(target), stepComponents);
+ stepTargetCRS =
toAuthorityDefinition(CoordinateReferenceSystem.class,
ReferencingServices.getInstance()
+ .createCompoundCRS(factorySIS.getCRSFactory(),
factorySIS.getCSFactory(), derivedFrom(target), stepComponents));
}
int delta = source.getCoordinateSystem().getDimension();
final int startAtDimension = endAtDimension;
Modified:
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
URL:
http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java?rev=1740892&r1=1740891&r2=1740892&view=diff
==============================================================================
---
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
[UTF-8] (original)
+++
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
[UTF-8] Mon Apr 25 20:30:40 2016
@@ -55,6 +55,7 @@ import org.apache.sis.referencing.factor
import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
import org.apache.sis.referencing.factory.MissingFactoryResourceException;
import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
+import org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException;
import org.apache.sis.metadata.iso.extent.Extents;
import org.apache.sis.internal.referencing.CoordinateOperations;
import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
@@ -151,7 +152,8 @@ class CoordinateOperationRegistry {
}
/**
- * The object to use for finding authority codes.
+ * The object to use for finding authority codes, or {@code null} if none.
+ * An instance is fetched at construction time from the {@link #registry}
if possible.
*/
private final IdentifiedObjectFinder codeFinder;
@@ -213,17 +215,21 @@ class CoordinateOperationRegistry {
this.factory = factory;
factorySIS = (factory instanceof DefaultCoordinateOperationFactory)
? (DefaultCoordinateOperationFactory) factory :
CoordinateOperations.factory();
+ IdentifiedObjectFinder codeFinder = null;
if (registry != null) {
if (registry instanceof GeodeticAuthorityFactory) {
codeFinder = ((GeodeticAuthorityFactory)
registry).newIdentifiedObjectFinder();
- } else {
+ } else try {
codeFinder =
IdentifiedObjects.newFinder(Citations.getIdentifier(registry.getAuthority(),
false));
+ } catch (NoSuchAuthorityFactoryException e) {
+
Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION),
+ CoordinateOperationRegistry.class, "<init>", e);
+ }
+ if (codeFinder != null) {
+ codeFinder.setIgnoringAxes(true);
}
-
codeFinder.setSearchDomain(IdentifiedObjectFinder.Domain.ALL_DATASET);
- codeFinder.setIgnoringAxes(true);
- } else {
- codeFinder = null;
}
+ this.codeFinder = codeFinder;
if (context != null) {
areaOfInterest = context.getAreaOfInterest();
desiredAccuracy = context.getDesiredAccuracy();
@@ -232,12 +238,36 @@ class CoordinateOperationRegistry {
}
/**
+ * If the authority defines an object equal, ignoring metadata, to the
given object, returns that authority object.
+ * Otherwise returns the given object unchanged. We do not invoke this
method for user-supplied CRS, but only for
+ * CRS or other objects created by {@code CoordinateOperationRegistry} as
intermediate step.
+ */
+ final <T extends IdentifiedObject> T toAuthorityDefinition(final Class<T>
type, final T object) throws FactoryException {
+ if (codeFinder != null) {
+ codeFinder.setIgnoringAxes(false);
+ final IdentifiedObject candidate =
codeFinder.findSingleton(object);
+ codeFinder.setIgnoringAxes(true);
+ if (Utilities.equalsIgnoreMetadata(object, candidate)) {
+ return type.cast(candidate);
+ }
+ }
+ return object;
+ }
+
+ /**
* Finds the authority code for the given coordinate reference system.
* This method does not trust the code given by the user in its CRS - we
verify it.
+ * This method may return a code even if the axis order does not match;
+ * it will be caller's responsibility to make necessary adjustments.
*/
private String findCode(final CoordinateReferenceSystem crs) throws
FactoryException {
- final Identifier identifier =
IdentifiedObjects.getIdentifier(codeFinder.findSingleton(crs), null);
- return (identifier != null) ? identifier.getCode() : null;
+ if (codeFinder != null) {
+ final Identifier identifier =
IdentifiedObjects.getIdentifier(codeFinder.findSingleton(crs), null);
+ if (identifier != null) {
+ return identifier.getCode();
+ }
+ }
+ return null;
}
/**
@@ -410,7 +440,7 @@ class CoordinateOperationRegistry {
} catch (NoninvertibleTransformException exception) {
// It may be a normal failure - the operation is not
required to be invertible.
Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION),
- CoordinateOperationRegistry.class, "search",
exception);
+ CoordinateOperationRegistry.class,
"createOperation", exception);
continue;
}
} catch (MissingFactoryResourceException e) {
@@ -872,10 +902,11 @@ class CoordinateOperationRegistry {
return candidate; // Keep the existing instance
since it may contain useful metadata.
}
}
- return ReferencingServices.getInstance().createCompoundCRS(
- factorySIS.getCRSFactory(),
- factorySIS.getCSFactory(),
- derivedFrom(crs), crs, CommonCRS.Vertical.ELLIPSOIDAL.crs());
+ return toAuthorityDefinition(CoordinateReferenceSystem.class,
+ ReferencingServices.getInstance().createCompoundCRS(
+ factorySIS.getCRSFactory(),
+ factorySIS.getCSFactory(),
+ derivedFrom(crs), crs,
CommonCRS.Vertical.ELLIPSOIDAL.crs()));
}
/**