You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2018/06/02 17:50:15 UTC
svn commit: r1832743 - in /sis/branches/JDK8/core:
sis-metadata/src/main/java/org/apache/sis/internal/metadata/
sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/
sis-metadata/src/main/java/org/apache/sis/metadata/
sis-metadata/src/main/j...
Author: desruisseaux
Date: Sat Jun 2 17:50:14 2018
New Revision: 1832743
URL: http://svn.apache.org/viewvc?rev=1832743&view=rev
Log:
SQL metadaat: fix an "ID column not found" error on PostgreSQL, more compact identifiers, and replace CRS WKT by EPSG codes.
Added:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/TableHierarchy.java (with props)
Modified:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLBuilder.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1832743&r1=1832742&r2=1832743&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -67,7 +67,7 @@ import org.apache.sis.util.Deprecable;
* <cite>"referencing by coordinates"</cite> but needed by metadata.</p>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
* @since 0.3
* @module
*/
@@ -286,6 +286,20 @@ public class ReferencingServices extends
throw moduleNotFound();
}
+ /**
+ * Returns an identifier for the given object, giving precedence to EPSG identifier if available.
+ * The returned string should be of the form {@code "AUTHORITY:CODE"} if possible (no guarantees).
+ *
+ * @param object the object for which to get an identifier.
+ * @return an identifier for the given object, with preference given to EPSG codes.
+ * @throws FactoryException if an error occurred while searching for the EPSG code.
+ *
+ * @since 1.0
+ */
+ public String getPreferredIdentifier(final IdentifiedObject object) throws FactoryException {
+ throw moduleNotFound();
+ }
+
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLBuilder.java?rev=1832743&r1=1832742&r2=1832743&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLBuilder.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLBuilder.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -19,6 +19,9 @@ package org.apache.sis.internal.metadata
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.StringTokenizer;
+import org.opengis.util.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.apache.sis.internal.metadata.ReferencingServices;
/**
@@ -26,7 +29,7 @@ import java.util.StringTokenizer;
* This class is for internal purpose only and may change or be removed in any future SIS version.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
* @since 0.8
* @module
*/
@@ -181,8 +184,9 @@ public class SQLBuilder {
*
* @param value the value to append, or {@code null}.
* @return this builder, for method call chaining.
+ * @throws FactoryException if an error occurred while using the geodetic database.
*/
- public final SQLBuilder appendCondition(final Object value) {
+ public final SQLBuilder appendCondition(final Object value) throws FactoryException {
if (value == null) {
buffer.append(" IS NULL");
return this;
@@ -196,8 +200,9 @@ public class SQLBuilder {
*
* @param value the value to append, or {@code null}.
* @return this builder, for method call chaining.
+ * @throws FactoryException if an error occurred while using the geodetic database.
*/
- public final SQLBuilder appendValue(final Object value) {
+ public final SQLBuilder appendValue(Object value) throws FactoryException {
if (value == null) {
buffer.append("NULL");
} else if (value instanceof Boolean) {
@@ -205,6 +210,9 @@ public class SQLBuilder {
} else if (value instanceof Number) {
buffer.append(value);
} else {
+ if (value instanceof IdentifiedObject) {
+ value = ReferencingServices.getInstance().getPreferredIdentifier((IdentifiedObject) value);
+ }
buffer.append('\'').append(doubleQuotes(value)).append('\'');
}
return this;
@@ -297,7 +305,7 @@ public class SQLBuilder {
final String name = buffer.append(table).append('_').append(column).append("_fkey").toString();
return clear().append("ALTER TABLE ").appendIdentifier(schema, table).append(" ADD CONSTRAINT ")
.appendIdentifier(name).append(" FOREIGN KEY(").appendIdentifier(column).append(") REFERENCES ")
- .appendIdentifier(schema, target).append(" (").append(primaryKey)
+ .appendIdentifier(schema, target).append(" (").appendIdentifier(primaryKey)
.append(") ON UPDATE ").append(cascade ? "CASCADE" : "RESTRICT")
.append(" ON DELETE RESTRICT").toString();
}
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1832743&r1=1832742&r2=1832743&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -354,6 +354,10 @@ class PropertyAccessor {
Class<?> elementType = getter.getReturnType();
if (Collection.class.isAssignableFrom(elementType)) {
elementType = Classes.boundOfParameterizedProperty(getter);
+ if (elementType == null) {
+ // Subclass has erased parameterized type. Use method declared in the interface.
+ elementType = Classes.boundOfParameterizedProperty(getters[i]);
+ }
}
elementTypes[i] = Numbers.primitiveToWrapper(elementType);
}
@@ -1238,7 +1242,7 @@ class PropertyAccessor {
}
Object copy = copier.copies.get(metadata);
if (copy == null) {
- copy = implementation.newInstance();
+ copy = implementation.getConstructor().newInstance();
copier.copies.put(metadata, copy); // Need to be first in case of cyclic graphs.
final Object[] arguments = new Object[1];
for (int i=0; i<allCount; i++) {
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java?rev=1832743&r1=1832742&r2=1832743&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -70,6 +70,7 @@ import org.apache.sis.internal.jaxb.lan.
import org.apache.sis.internal.jaxb.LegacyNamespaces;
import org.apache.sis.internal.jaxb.FilterByVersion;
import org.apache.sis.internal.jaxb.Context;
+import org.apache.sis.internal.jaxb.NonMarshalledAuthority;
import org.apache.sis.internal.jaxb.metadata.CI_Citation;
import org.apache.sis.internal.jaxb.metadata.MD_Identifier;
@@ -191,11 +192,6 @@ public class DefaultMetadata extends ISO
private static final long serialVersionUID = -4935599812744534502L;
/**
- * Unique identifier for this metadata record, or {@code null} if none.
- */
- private Identifier metadataIdentifier;
-
- /**
* Language(s) used for documenting metadata.
*/
private Collection<Locale> languages;
@@ -347,7 +343,7 @@ public class DefaultMetadata extends ISO
public DefaultMetadata(final Metadata object) {
super(object);
if (object != null) {
- metadataIdentifier = object.getMetadataIdentifier();
+ identifiers = singleton(object.getMetadataIdentifier(), Identifier.class);
parentMetadata = object.getParentMetadata();
languages = copyCollection(object.getLanguages(), Locale.class);
characterSets = copyCollection(object.getCharacterSets(), Charset.class);
@@ -423,7 +419,7 @@ public class DefaultMetadata extends ISO
@XmlElement(name = "metadataIdentifier")
@XmlJavaTypeAdapter(MD_Identifier.Since2014.class)
public Identifier getMetadataIdentifier() {
- return metadataIdentifier;
+ return NonMarshalledAuthority.getMarshallable(identifiers);
}
/**
@@ -435,7 +431,8 @@ public class DefaultMetadata extends ISO
*/
public void setMetadataIdentifier(final Identifier newValue) {
checkWritePermission();
- metadataIdentifier = newValue;
+ identifiers = nonNullCollection(identifiers, Identifier.class);
+ NonMarshalledAuthority.setMarshallable(identifiers, newValue);
}
/**
@@ -467,7 +464,8 @@ public class DefaultMetadata extends ISO
*/
@Deprecated
public void setFileIdentifier(final String newValue) {
- DefaultIdentifier identifier = DefaultIdentifier.castOrCopy(metadataIdentifier); // See "Note about deprecated methods implementation"
+ // See "Note about deprecated methods implementation"
+ DefaultIdentifier identifier = DefaultIdentifier.castOrCopy(NonMarshalledAuthority.getMarshallable(identifiers));
if (identifier == null) {
if (newValue == null) return;
identifier = new DefaultIdentifier();
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java?rev=1832743&r1=1832742&r2=1832743&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -684,7 +684,7 @@ public final class Citations extends Sta
* or {@code null} if the given citation is null or does not have any Unicode identifier or title.
*
* @see org.apache.sis.metadata.iso.ImmutableIdentifier
- * @see org.apache.sis.referencing.IdentifiedObjects#getUnicodeIdentifier(IdentifiedObject)
+ * @see org.apache.sis.referencing.IdentifiedObjects#getSimpleNameOrIdentifier(IdentifiedObject)
* @see org.apache.sis.util.CharSequences#isUnicodeIdentifier(CharSequence)
*
* @since 0.6
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java?rev=1832743&r1=1832742&r2=1832743&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -47,6 +47,7 @@ import java.sql.PreparedStatement;
import org.opengis.annotation.UML;
import org.opengis.util.CodeList;
import org.opengis.util.ControlledVocabulary;
+import org.opengis.util.FactoryException;
import org.apache.sis.metadata.MetadataStandard;
import org.apache.sis.metadata.KeyNamePolicy;
import org.apache.sis.metadata.ValueExistencePolicy;
@@ -125,16 +126,6 @@ public class MetadataSource implements A
static final String ID_COLUMN = "ID";
/**
- * Delimiter characters for the table name in identifier. Table names are prefixed to identifiers only if
- * the type represented by the table is a subtype. For example since {@code CI_Organisation} is a subtype
- * of {@code CI_Party}, identifiers for organizations need to be prefixed by {@code {CI_Organisation}} in
- * order allow {@code MetadataSource} to know in which table to search for such party.
- *
- * @see MetadataWriter#isReservedChar(int)
- */
- static final char TYPE_OPEN = '{', TYPE_CLOSE = '}';
-
- /**
* The timeout before to close a prepared statement, in nanoseconds. This is set to 2 seconds,
* which is a bit short but should be okay if the {@link DataSource} creates pooled connections.
* In case there is no connection pool, then the mechanism defined in this package will hopefully
@@ -672,6 +663,8 @@ public class MetadataSource implements A
identifier = search(table, null, asMap, stmt, helper());
} catch (SQLException e) {
throw new MetadataStoreException(e.getLocalizedMessage(), Exceptions.unwrap(e));
+ } catch (FactoryException e) {
+ throw new MetadataStoreException(e.getLocalizedMessage(), e);
}
}
}
@@ -692,7 +685,7 @@ public class MetadataSource implements A
* @throws SQLException if an error occurred while searching in the database.
*/
final String search(final String table, Set<String> columns, final Map<String,Object> metadata,
- final Statement stmt, final SQLBuilder helper) throws SQLException
+ final Statement stmt, final SQLBuilder helper) throws SQLException, FactoryException
{
assert Thread.holdsLock(this);
helper.clear();
@@ -743,7 +736,7 @@ public class MetadataSource implements A
* Builds the SQL statement with the resolved value.
*/
if (helper.isEmpty()) {
- helper.append("SELECT ").append(ID_COLUMN).append(" FROM ")
+ helper.append("SELECT ").appendIdentifier(ID_COLUMN).append(" FROM ")
.appendIdentifier(schema, table).append(" WHERE ");
} else {
helper.append(" AND ");
@@ -811,25 +804,6 @@ public class MetadataSource implements A
}
/**
- * If the given identifier specifies a subtype of the given type, then returns that subtype.
- * For example if the given type is {@code Party.class} and the given identifier is
- * {@code "{CI_Organisation}EPSG"}, then this method returns {@code Organisation.class}.
- * Otherwise this method returns {@code type} unchanged.
- */
- private static Class<?> subType(Class<?> type, final String identifier) {
- if (identifier.charAt(0) == TYPE_OPEN) {
- final int i = identifier.indexOf(TYPE_CLOSE);
- if (i >= 0) {
- final Class<?> subType = Types.forStandardName(identifier.substring(1, i));
- if (subType != null && type.isAssignableFrom(subType)) {
- type = subType;
- }
- }
- }
- return type;
- }
-
- /**
* Returns an implementation of the specified metadata interface filled with the data referenced
* by the specified identifier. Alternatively, this method can also return a {@link CodeList} or
* {@link Enum} element.
@@ -871,7 +845,7 @@ public class MetadataSource implements A
*/
if (value == null) {
Method method = null;
- final Class<?> subType = subType(type, identifier);
+ final Class<?> subType = TableHierarchy.subType(type, identifier);
final Dispatcher toSearch = new Dispatcher(identifier, this);
try {
value = subType.getConstructor().newInstance();
@@ -927,7 +901,7 @@ public class MetadataSource implements A
* If the identifier is prefixed with a table name as in "{CI_Organisation}identifier",
* the name between bracket is a subtype of the given 'type' argument.
*/
- final Class<?> type = subType(info.getMetadataType(), toSearch.identifier);
+ final Class<?> type = TableHierarchy.subType(info.getMetadataType(), toSearch.identifier);
final Class<?> returnType = method.getReturnType();
final boolean wantCollection = Collection.class.isAssignableFrom(returnType);
final Class<?> elementType = wantCollection ? Classes.boundOfParameterizedProperty(method) : returnType;
@@ -951,7 +925,7 @@ public class MetadataSource implements A
final SQLBuilder helper = helper();
final String query = helper.clear().append("SELECT * FROM ")
.appendIdentifier(schema, tableName).append(" WHERE ")
- .append(ID_COLUMN).append("=?").toString();
+ .appendIdentifier(ID_COLUMN).append("=?").toString();
result = new CachedStatement(type, connection().prepareStatement(query), listeners);
}
value = result.getValue(toSearch.identifier, columnName);
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java?rev=1832743&r1=1832742&r2=1832743&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -22,6 +22,8 @@ import java.util.Iterator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.IdentityHashMap;
+import java.util.Collection;
+import java.util.Collections;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.sql.Statement;
@@ -33,6 +35,7 @@ import java.lang.reflect.Modifier;
import org.opengis.metadata.Identifier;
import org.opengis.metadata.citation.Citation;
+import org.opengis.util.FactoryException;
import org.apache.sis.util.Exceptions;
import org.apache.sis.util.ArgumentChecks;
@@ -48,6 +51,7 @@ import org.apache.sis.metadata.ValueExis
import org.apache.sis.metadata.TitleProperty;
import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.internal.metadata.sql.SQLBuilder;
+import org.apache.sis.xml.IdentifiedObject;
// Branch-dependent imports
import org.opengis.util.ControlledVocabulary;
@@ -106,7 +110,7 @@ import org.opengis.util.ControlledVocabu
* </table>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
* @since 0.8
* @module
*/
@@ -214,6 +218,8 @@ public class MetadataWriter extends Meta
* little bit simpler, keep only the root cause provided that the exception type is compatible.
*/
throw new MetadataStoreException(e.getLocalizedMessage(), Exceptions.unwrap(e));
+ } catch (FactoryException e) {
+ throw new MetadataStoreException(e.getLocalizedMessage(), e);
}
return identifier;
}
@@ -233,7 +239,7 @@ public class MetadataWriter extends Meta
* of the expected package.
*/
private String add(final Statement stmt, final Object metadata, final Map<Object,String> done,
- final String parent) throws ClassCastException, SQLException
+ final String parent) throws ClassCastException, SQLException, FactoryException
{
final SQLBuilder helper = helper();
/*
@@ -306,9 +312,9 @@ public class MetadataWriter extends Meta
}
}
/*
- * Determine the column data type. We infer that type from the method return value, not from the
- * actual value for in the given metadata object, since the value type for the same property may
- * be different in future calls to this method.
+ * Determine the column data type. We infer that type from the method return value, not from
+ * actual value of given metadata object, since the value type for the same property may be
+ * different in future calls to this method.
*/
int maxLength = maximumValueLength;
Class<?> rt = colTypes.get(column);
@@ -364,7 +370,7 @@ public class MetadataWriter extends Meta
*/
final int minimalIdentifierLength;
if (isChildTable) {
- identifier = TYPE_OPEN + table + TYPE_CLOSE + identifier;
+ identifier = TableHierarchy.encode(table, identifier);
minimalIdentifierLength = table.length() + 2;
} else {
minimalIdentifierLength = 0;
@@ -507,7 +513,7 @@ public class MetadataWriter extends Meta
/*
* Create the SQL statement which will insert the data.
*/
- helper.clear().append("INSERT INTO ").appendIdentifier(schema(), table).append(" (").append(ID_COLUMN);
+ helper.clear().append("INSERT INTO ").appendIdentifier(schema(), table).append(" (").appendIdentifier(ID_COLUMN);
for (final String column : asSingletons.keySet()) {
helper.append(", ").appendIdentifier(column);
}
@@ -601,7 +607,7 @@ public class MetadataWriter extends Meta
* not inherited, then we have to repeat the primary key creation in every child tables.
*/
helper.append("(CONSTRAINT ").appendIdentifier(table + "_pkey")
- .append(" PRIMARY KEY (").append(ID_COLUMN).append(")) ");
+ .append(" PRIMARY KEY (").appendIdentifier(ID_COLUMN).append(")) ");
}
inherits = new StringBuilder(helper.append(" INHERITS (").toString());
} else {
@@ -633,7 +639,7 @@ public class MetadataWriter extends Meta
*/
private String createTable(final String table, final String primaryKey) throws SQLException {
return helper().clear().append("CREATE TABLE ").appendIdentifier(schema(), table)
- .append(" (").append(primaryKey).append(" VARCHAR(").append(maximumIdentifierLength)
+ .append(" (").appendIdentifier(primaryKey).append(" VARCHAR(").append(maximumIdentifierLength)
.append(") NOT NULL PRIMARY KEY)").toString();
}
@@ -644,7 +650,7 @@ public class MetadataWriter extends Meta
* the native SQL {@code ENUM} type for making easier to add new values when a standard
* is updated.
*/
- private String addCode(final Statement stmt, final ControlledVocabulary code) throws SQLException {
+ private String addCode(final Statement stmt, final ControlledVocabulary code) throws SQLException, FactoryException {
assert Thread.holdsLock(this);
final String table = getTableName(code.getClass());
final Set<String> columns = getExistingColumns(table);
@@ -653,16 +659,16 @@ public class MetadataWriter extends Meta
columns.add(CODE_COLUMN);
}
final String identifier = Types.getCodeName(code);
- final String query = helper().clear().append("SELECT ").append(CODE_COLUMN)
+ final String query = helper().clear().append("SELECT ").appendIdentifier(CODE_COLUMN)
.append(" FROM ").appendIdentifier(schema(), table).append(" WHERE ")
- .append(CODE_COLUMN).appendCondition(identifier).toString();
+ .appendIdentifier(CODE_COLUMN).appendCondition(identifier).toString();
final boolean exists;
try (ResultSet rs = stmt.executeQuery(query)) {
exists = rs.next();
}
if (!exists) {
final String sql = helper().clear().append("INSERT INTO ").appendIdentifier(schema(), table)
- .append(" (").append(CODE_COLUMN).append(") VALUES (").appendValue(identifier)
+ .append(" (").appendIdentifier(CODE_COLUMN).append(") VALUES (").appendValue(identifier)
.append(')').toString();
if (stmt.executeUpdate(sql) != 1) {
throw new SQLException(Errors.format(Errors.Keys.DatabaseUpdateFailure_3, 0, table, identifier));
@@ -674,8 +680,8 @@ public class MetadataWriter extends Meta
/**
* Suggests an identifier (primary key) to be used for the given metadata. This method is invoked automatically
* when a new metadata is about to be inserted in the database. The default implementation uses heuristic rules
- * of a few "well known" metadata like {@link Identifier} and {@link Citation}. Subclasses can override this method
- * for implementing their own heuristic.
+ * for a few "well known" metadata like {@link Identifier} and {@link Citation}. Subclasses can override this
+ * method for implementing their own heuristic.
*
* <p>This method does not need to care about key collision.
* The caller will adds some suffix if this is necessary for differentiating otherwise identical identifiers.</p>
@@ -688,11 +694,22 @@ public class MetadataWriter extends Meta
*/
protected String suggestIdentifier(final Object metadata, final Map<String,Object> asValueMap) throws SQLException {
String identifier = null;
+ final Collection<? extends Identifier> identifiers;
if (metadata instanceof Identifier) {
- identifier = nonEmpty(((Identifier) metadata).getCode());
- final String cs = nonEmpty(((Identifier) metadata).getCodeSpace());
- if (cs != null) {
- identifier = (identifier != null) ? (cs + DefaultNameSpace.DEFAULT_SEPARATOR + identifier) : cs;
+ identifiers = Collections.singleton((Identifier) metadata);
+ } else if (metadata instanceof IdentifiedObject) {
+ identifiers = ((IdentifiedObject) metadata).getIdentifiers();
+ } else {
+ identifiers = Collections.emptySet();
+ }
+ for (final Identifier id : identifiers) {
+ identifier = nonEmpty(id.getCode());
+ if (identifier != null) {
+ final String cs = nonEmpty(id.getCodeSpace());
+ if (cs != null) {
+ identifier = cs + DefaultNameSpace.DEFAULT_SEPARATOR + identifier;
+ }
+ break;
}
}
if (identifier == null && metadata instanceof Citation) {
@@ -769,7 +786,7 @@ public class MetadataWriter extends Meta
* Returns {@code true} if the given code point is a reserved character.
*/
private static boolean isReservedChar(final int c) {
- return (c == TYPE_OPEN) || (c == TYPE_CLOSE);
+ return (c == TableHierarchy.TYPE_OPEN) || (c == TableHierarchy.TYPE_CLOSE);
}
/**
Added: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/TableHierarchy.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/TableHierarchy.java?rev=1832743&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/TableHierarchy.java (added)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/TableHierarchy.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.metadata.sql;
+
+import java.util.Map;
+import java.util.HashMap;
+import org.apache.sis.util.iso.Types;
+
+
+/**
+ * Utility methods for handling the inheritance between tables.
+ * This features is partially supported in PostgreSQL database.
+ *
+ * @author desruisseaux
+ */
+final class TableHierarchy {
+ /**
+ * Delimiter characters for the table name in identifier. Table names are prefixed to identifiers only if
+ * the type represented by the table is a subtype. For example since {@code CI_Organisation} is a subtype
+ * of {@code CI_Party}, identifiers for organizations need to be prefixed by {@code {CI_Organisation}} in
+ * order allow {@code MetadataSource} to know in which table to search for such party.
+ *
+ * @see MetadataWriter#isReservedChar(int)
+ */
+ static final char TYPE_OPEN = '{', TYPE_CLOSE = '}';
+
+ /**
+ * Abbreviations for commonly-used tables. We use those abbreviations because table names like
+ * {@code "MD_VectorSpatialRepresentation"} consume a lot of space, which leave few spaces left
+ * for actual identifiers when we want to limit the length to a relatively small value.
+ */
+ private static final Map<String,String> ABBREVIATIONS = new HashMap<>(16);
+
+ /**
+ * The reverse of {@link #ABBREVIATIONS}.
+ */
+ private static final Map<String,String> TABLES = new HashMap<>(16);
+ static {
+ add("MD_VectorSpatialRepresentation", "vec");
+ add("MD_GridSpatialRepresentation", "grd");
+ add("MD_Georectified", "rtf");
+ add("MD_Georeferenceable", "cbl");
+ add("MD_DataIdentification", "dat");
+ add("SV_ServiceIdentification", "srv");
+ add("MD_FeatureCatalogueDescription", "cat");
+ add("MD_CoverageDescription", "cov");
+ add("MD_ImageDescription", "img");
+ add("MD_SampleDimension", "sd");
+ add("MD_Band", "bd");
+ }
+
+ /**
+ * Adds an abbreviation. For class initialization only.
+ */
+ private static void add(final String table, final String abbreviation) {
+ ABBREVIATIONS.put(table, abbreviation);
+ TABLES.put(abbreviation, table);
+ }
+
+ /**
+ * Do not allow instantiation of this class.
+ */
+ private TableHierarchy() {
+ }
+
+ /**
+ * Encode table name in the given identifier.
+ */
+ static String encode(String table, final String identifier) {
+ table = ABBREVIATIONS.getOrDefault(table, table);
+ return TYPE_OPEN + table + TYPE_CLOSE + identifier;
+ }
+
+ /**
+ * If the given identifier specifies a subtype of the given type, then returns that subtype.
+ * For example if the given type is {@code Party.class} and the given identifier is
+ * {@code "{CI_Organisation}EPSG"}, then this method returns {@code Organisation.class}.
+ * Otherwise this method returns {@code type} unchanged.
+ */
+ static Class<?> subType(Class<?> type, final String identifier) {
+ if (identifier.charAt(0) == TYPE_OPEN) {
+ final int i = identifier.indexOf(TYPE_CLOSE);
+ if (i >= 0) {
+ String table = identifier.substring(1, i);
+ table = TABLES.getOrDefault(table, table);
+ final Class<?> subType = Types.forStandardName(table);
+ if (subType != null && type.isAssignableFrom(subType)) {
+ type = subType;
+ }
+ }
+ }
+ return type;
+ }
+}
Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/TableHierarchy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/TableHierarchy.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java?rev=1832743&r1=1832742&r2=1832743&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -53,6 +53,7 @@ import org.opengis.referencing.operation
import org.opengis.referencing.operation.SingleOperation;
import org.opengis.referencing.operation.CoordinateOperation;
import org.opengis.referencing.operation.CoordinateOperationFactory;
+import org.opengis.metadata.Identifier;
import org.opengis.metadata.citation.Citation;
import org.opengis.metadata.citation.OnLineFunction;
import org.opengis.metadata.citation.OnlineResource;
@@ -97,13 +98,14 @@ import org.apache.sis.util.resources.Voc
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.Exceptions;
import org.apache.sis.util.Utilities;
+import org.apache.sis.util.iso.DefaultNameSpace;
/**
* Implements the referencing services needed by the {@code "sis-metadata"} module.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
* @since 0.5
* @module
*/
@@ -411,6 +413,34 @@ public final class ServicesForMetadata e
return new DirectPosition2D(CommonCRS.defaultGeographic(), λ, φ);
}
+ /**
+ * Returns an identifier for the given object, giving precedence to EPSG identifier if available.
+ * The returned string should be of the form {@code "AUTHORITY:CODE"} if possible (no guarantees).
+ *
+ * @param object the object for which to get an identifier.
+ * @return an identifier for the given object, with preference given to EPSG codes.
+ * @throws FactoryException if an error occurred while searching for the EPSG code.
+ *
+ * @since 1.0
+ */
+ @Override
+ public String getPreferredIdentifier(final IdentifiedObject object) throws FactoryException {
+ final Integer code = IdentifiedObjects.lookupEPSG(object);
+ if (code != null) {
+ return Constants.EPSG + DefaultNameSpace.DEFAULT_SEPARATOR + code;
+ }
+ /*
+ * If above code did not found an EPSG code, discard EPSG codes that
+ * we may find in the loop below because they are probably invalid.
+ */
+ for (final Identifier id : object.getIdentifiers()) {
+ if (!Constants.EPSG.equalsIgnoreCase(id.getCodeSpace())) {
+ return IdentifiedObjects.toString(id);
+ }
+ }
+ return IdentifiedObjects.getSimpleNameOrIdentifier(object);
+ }
+
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java?rev=1832743&r1=1832742&r2=1832743&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -57,7 +57,7 @@ import static org.apache.sis.internal.ut
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @author Guilhem Legal (Geomatys)
- * @version 0.8
+ * @version 1.0
*
* @see CRS
* @see org.apache.sis.geometry.Envelopes
@@ -283,7 +283,7 @@ public final class IdentifiedObjects ext
final Iterator<? extends Identifier> it = iterator(object.getIdentifiers());
if (it != null) while (it.hasNext()) {
final Identifier identifier = it.next();
- if (identifier != null) { // Paranoiac check.
+ if (identifier != null) { // Paranoiac check.
if (authority == null || identifierMatches(authority, identifier.getAuthority())) {
return identifier;
}
@@ -319,12 +319,12 @@ public final class IdentifiedObjects ext
final Iterator<? extends Identifier> it = iterator(object.getIdentifiers());
if (it != null) while (it.hasNext()) {
final String code = toString(it.next());
- if (code != null) { // Paranoiac check.
+ if (code != null) { // Paranoiac check.
return code;
}
}
final String name = toString(object.getName());
- if (name != null) { // Paranoiac check.
+ if (name != null) { // Paranoiac check.
return name;
}
}
@@ -332,8 +332,8 @@ public final class IdentifiedObjects ext
}
/**
- * Returns the first name, alias or identifier which is a
- * {@linkplain CharSequences#isUnicodeIdentifier(CharSequence) valid Unicode identifier}.
+ * Returns the first name, alias or identifier which is a valid Unicode identifier. This method considers a
+ * name or identifier as valid if {@link CharSequences#isUnicodeIdentifier(CharSequence)} returns {@code true}.
* This method performs the search in the following order:
*
* <ul>
@@ -346,13 +346,15 @@ public final class IdentifiedObjects ext
* @return the first name, alias or identifier which is a valid Unicode identifier, or {@code null} if none.
*
* @see org.apache.sis.metadata.iso.ImmutableIdentifier
- * @see org.apache.sis.metadata.iso.citation.Citations#getUnicodeIdentifier(Citation)
- * @see org.apache.sis.util.CharSequences#isUnicodeIdentifier(CharSequence)
+ * @see Citations#getUnicodeIdentifier(Citation)
+ * @see CharSequences#isUnicodeIdentifier(CharSequence)
+ *
+ * @since 1.0
*/
- public static String getUnicodeIdentifier(final IdentifiedObject object) {
+ public static String getSimpleNameOrIdentifier(final IdentifiedObject object) {
if (object != null) {
Identifier identifier = object.getName();
- if (identifier != null) { // Paranoiac check.
+ if (identifier != null) { // Paranoiac check.
final String code = identifier.getCode();
if (CharSequences.isUnicodeIdentifier(code)) {
return code;
@@ -371,7 +373,7 @@ public final class IdentifiedObjects ext
final Iterator<? extends Identifier> id = iterator(object.getIdentifiers());
if (id != null) while (id.hasNext()) {
identifier = id.next();
- if (identifier != null) { // Paranoiac check.
+ if (identifier != null) { // Paranoiac check.
final String code = identifier.getCode();
if (CharSequences.isUnicodeIdentifier(code)) {
return code;
@@ -383,6 +385,14 @@ public final class IdentifiedObjects ext
}
/**
+ * @deprecated Renamed {@link #getSimpleNameOrIdentifier(IdentifiedObject)}.
+ */
+ @Deprecated
+ public static String getUnicodeIdentifier(final IdentifiedObject object) {
+ return getSimpleNameOrIdentifier(object);
+ }
+
+ /**
* Looks up a URN, such as {@code "urn:ogc:def:crs:EPSG:9.1:4326"}, of the specified object.
* This method searches in all {@linkplain org.apache.sis.referencing.factory.GeodeticAuthorityFactory geodetic
* authority factories} known to SIS for an object {@linkplain org.apache.sis.util.ComparisonMode#APPROXIMATIVE
@@ -764,7 +774,7 @@ public final class IdentifiedObjects ext
final String code = identifier.getCode();
String cs = identifier.getCodeSpace();
if (cs == null || cs.isEmpty()) {
- cs = org.apache.sis.internal.util.Citations.getIdentifier(identifier.getAuthority(), true);
+ cs = Citations.getUnicodeIdentifier(identifier.getAuthority());
}
if (cs != null) {
return cs + DefaultNameSpace.DEFAULT_SEPARATOR + code;
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java?rev=1832743&r1=1832742&r2=1832743&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -698,7 +698,7 @@ public class BursaWolfParameters extends
return WKTKeywords.ToWGS84;
}
formatter.setInvalidWKT(BursaWolfParameters.class, null);
- String name = IdentifiedObjects.getUnicodeIdentifier(getTargetDatum());
+ String name = IdentifiedObjects.getSimpleNameOrIdentifier(getTargetDatum());
if (name == null) {
name = "Unknown";
}
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java?rev=1832743&r1=1832742&r2=1832743&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -59,6 +59,7 @@ import org.apache.sis.referencing.factor
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.metadata.iso.citation.Citations;
import org.apache.sis.internal.referencing.CoordinateOperations;
import org.apache.sis.internal.referencing.DeferredCoordinateOperation;
import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
@@ -68,7 +69,6 @@ import org.apache.sis.internal.referenci
import org.apache.sis.internal.metadata.ReferencingServices;
import org.apache.sis.internal.system.Semaphores;
import org.apache.sis.internal.system.Loggers;
-import org.apache.sis.internal.util.Citations;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.Utilities;
@@ -148,7 +148,7 @@ class CoordinateOperationRegistry {
* Creates an identifier in the Apache SIS namespace for the given vocabulary key.
*/
private static Identifier createIdentifier(final short key) {
- return new NamedIdentifier(org.apache.sis.metadata.iso.citation.Citations.SIS, Vocabulary.formatInternational(key));
+ return new NamedIdentifier(Citations.SIS, Vocabulary.formatInternational(key));
}
/**
@@ -227,7 +227,7 @@ class CoordinateOperationRegistry {
if (registry instanceof GeodeticAuthorityFactory) {
codeFinder = ((GeodeticAuthorityFactory) registry).newIdentifiedObjectFinder();
} else try {
- codeFinder = IdentifiedObjects.newFinder(Citations.getIdentifier(registry.getAuthority(), false));
+ codeFinder = IdentifiedObjects.newFinder(Citations.getIdentifier(registry.getAuthority()));
} catch (NoSuchAuthorityFactoryException e) {
Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION),
CoordinateOperationRegistry.class, "<init>", e);
Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java?rev=1832743&r1=1832742&r2=1832743&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java [UTF-8] Sat Jun 2 17:50:14 2018
@@ -1538,7 +1538,7 @@ cmp: while (ia < lga) {
*
* @see org.apache.sis.metadata.iso.ImmutableIdentifier
* @see org.apache.sis.metadata.iso.citation.Citations#getUnicodeIdentifier(Citation)
- * @see org.apache.sis.referencing.IdentifiedObjects#getUnicodeIdentifier(IdentifiedObject)
+ * @see org.apache.sis.referencing.IdentifiedObjects#getSimpleNameOrIdentifier(IdentifiedObject)
*/
public static boolean isUnicodeIdentifier(final CharSequence identifier) {
final int length = length(identifier);