sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1796388 - in /sis/trunk: ./ core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/ core/sis-metadata/src/main/java/org/apache/sis/metadata/ core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/ core/sis-metadata/src/t...
Date Sat, 27 May 2017 11:58:34 GMT
Author: desruisseaux
Date: Sat May 27 11:58:34 2017
New Revision: 1796388

URL: http://svn.apache.org/viewvc?rev=1796388&view=rev
Log:
Merge from JDK7 branch. Include a fallback on Apache SIS implementation class when a GeoAPI
interface is missing.

Modified:
    sis/trunk/   (props changed)
    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/metadata/MetadataStandard.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataWriterTest.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java
    sis/trunk/ide-project/NetBeans/nbproject/project.properties

Propchange: sis/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat May 27 11:58:34 2017
@@ -1,5 +1,5 @@
 /sis/branches/Android:1430670-1480699
 /sis/branches/JDK6:1394364-1758914
-/sis/branches/JDK7:1394913-1796283
-/sis/branches/JDK8:1584960-1796282
+/sis/branches/JDK7:1394913-1796387
+/sis/branches/JDK8:1584960-1796385
 /sis/branches/JDK9:1773327-1789983

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=1796388&r1=1796387&r2=1796388&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] Sat May 27 11:58:34 2017
@@ -398,7 +398,10 @@ public abstract class Initializer {
                     if (home != null) {
                         final Path file = Paths.get(home).resolveSibling("db/lib/derby.jar");
                         if (Files.isRegularFile(file)) {
-                            javadbLoader = loader = new URLClassLoader(new URL[] {file.toUri().toURL()});
+                            javadbLoader = loader = new URLClassLoader(new URL[] {
+                                file.toUri().toURL(),
+                                file.resolveSibling("derbynet.jar").toUri().toURL()
+                            });
                         }
                     }
                 }

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java?rev=1796388&r1=1796387&r2=1796388&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
[UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
[UTF-8] Sat May 27 11:58:34 2017
@@ -600,6 +600,7 @@ public class MetadataStandard implements
      * Returns the implementation class for the given interface, or {@code null} if none.
      * If non-null, the returned class must have a public no-argument constructor and the
      * metadata instance created by that constructor must be initially empty (no default
value).
+     * That no-argument constructor should never throw any checked exception.
      *
      * <p>The default implementation returns {@code null} in every cases. Subclasses
shall
      * override this method in order to map GeoAPI interfaces to their implementation.</p>

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java?rev=1796388&r1=1796387&r2=1796388&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
[UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
[UTF-8] Sat May 27 11:58:34 2017
@@ -160,14 +160,7 @@ final class Dispatcher implements Invoca
                 try {
                     value = fetchValue(source.getLookupInfo(method.getDeclaringClass()),
method);
                 } catch (ReflectiveOperationException | SQLException | MetadataStoreException
e) {
-                    Class<?> returnType = method.getReturnType();
-                    if (Collection.class.isAssignableFrom(returnType)) {
-                        final Class<?> elementType = Classes.boundOfParameterizedProperty(method);
-                        if (elementType != null) {
-                            returnType = elementType;
-                        }
-                    }
-                    throw new BackingStoreException(Errors.format(Errors.Keys.DatabaseError_2,
returnType, identifier), e);
+                    throw new BackingStoreException(error(method), e);
                 }
                 /*
                  * At this point we got the metadata property value, which may be null.
@@ -294,6 +287,20 @@ final class Dispatcher implements Invoca
     }
 
     /**
+     * Returns the error message for a failure to query the database for the property identified
by the given method.
+     */
+    final String error(final Method method) {
+        Class<?> returnType = method.getReturnType();
+        if (Collection.class.isAssignableFrom(returnType)) {
+            final Class<?> elementType = Classes.boundOfParameterizedProperty(method);
+            if (elementType != null) {
+                returnType = elementType;
+            }
+        }
+        return Errors.format(Errors.Keys.DatabaseError_2, returnType, identifier);
+    }
+
+    /**
      * Returns a string representation of a metadata of the given type.
      */
     private String toString(final Class<?> type) {

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java?rev=1796388&r1=1796387&r2=1796388&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
[UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
[UTF-8] Sat May 27 11:58:34 2017
@@ -775,6 +775,25 @@ 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}
element.
      *
@@ -788,24 +807,54 @@ public class MetadataSource implements A
      */
     public <T> T lookup(final Class<T> type, final String identifier) throws
MetadataStoreException {
         ArgumentChecks.ensureNonNull("type", type);
-        ArgumentChecks.ensureNonNull("identifier", identifier);
-        /*
-         * IMPLEMENTATION NOTE: This method must not invoke any method which may access 'statements'.
-         * It is not allowed to acquire the lock on 'statements' neither.
-         */
+        ArgumentChecks.ensureNonEmpty("identifier", identifier);
         Object value;
         if (CodeList.class.isAssignableFrom(type)) {
             value = getCodeList(type, identifier);
         } else {
             final CacheKey key = new CacheKey(type, identifier);
+            /*
+             * IMPLEMENTATION NOTE: be careful to not invoke any method that may synchronize
on 'this'
+             * inside the block synchronized on 'pool'.
+             */
             synchronized (pool) {
                 value = pool.get(key);
-                if (value == null) {
+                if (value == null && type.isInterface()) {
                     value = Proxy.newProxyInstance(classloader,
                             new Class<?>[] {type, MetadataProxy.class}, new Dispatcher(identifier,
this));
                     pool.put(key, value);
                 }
             }
+            /*
+             * At this point, a null value means that the given type is a class rather than
an interface.
+             * This may happen when a new type defined by a standard has not yet been defined
in GeoAPI.
+             * In such case, we only have the implementation class in Apache SIS, not yet
the interface.
+             * Since we can not create a Proxy, we have to fetch all property values now.
This is not
+             * very efficient and may waste a little bit of memory, but it should not happen
too often.
+             */
+            if (value == null) {
+                Method method = null;
+                final Class<?> subType = subType(type, identifier);
+                final Dispatcher toSearch = new Dispatcher(identifier, this);
+                try {
+                    value = subType.newInstance();
+                    final LookupInfo info            = getLookupInfo(subType);
+                    final Map<String,Object> map     = asValueMap(value);
+                    final Map<String,String> methods = standard.asNameMap(subType,
NAME_POLICY, KeyNamePolicy.METHOD_NAME);
+                    for (final Map.Entry<String,Object> entry : map.entrySet()) {
+                        method = subType.getMethod(methods.get(entry.getKey()));
+                        info.setMetadataType(subType);
+                        final Object p = readColumn(info, method, toSearch);
+                        if (p != null) {
+                            entry.setValue(p);
+                        }
+                    }
+                } catch (ReflectiveOperationException e) {
+                    throw new MetadataStoreException(Errors.format(Errors.Keys.UnsupportedImplementation_1,
subType), e);
+                } catch (SQLException e) {
+                    throw new MetadataStoreException(toSearch.error(method), e);
+                }
+            }
         }
         return type.cast(value);
     }
@@ -841,16 +890,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.
          */
-        Class<?> type = info.getMetadataType();
-        if (toSearch.identifier.charAt(0) == TYPE_OPEN) {
-            final int i = toSearch.identifier.indexOf(TYPE_CLOSE);
-            if (i >= 0) {
-                final Class<?> subType = Types.forStandardName(toSearch.identifier.substring(1,
i));
-                if (subType != null && type.isAssignableFrom(subType)) {
-                    type = subType;
-                }
-            }
-        }
+        final Class<?> type           = 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;
@@ -938,8 +978,8 @@ public class MetadataSource implements A
     }
 
     /**
-     * Returns the code of the given type and name. This method is defined for avoiding the
warning message
-     * when the actual class is unknown (it must have been checked dynamically by the caller
however).
+     * Returns the code of the given type and name. This method is defined for avoiding the
compiler warning
+     * message when the actual class is unknown (it must have been checked dynamically by
the caller however).
      */
     @SuppressWarnings({"unchecked","rawtypes"})
     private static CodeList<?> getCodeList(final Class<?> type, final String
name) {

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java?rev=1796388&r1=1796387&r2=1796388&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java
[UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java
[UTF-8] Sat May 27 11:58:34 2017
@@ -528,6 +528,16 @@ public class MetadataWriter extends Meta
     }
 
     /**
+     * Returns the parent of the given type. Normally, {@code type} is an interface, in which
case the parent types are
+     * other interfaces that the given type extends. But in some cases (e.g. when Apache
SIS implements a new ISO 19115
+     * type not yet defined in GeoAPI), the given type is a class. In such cases we ignore
its interface (it usually do
+     * not implement any) and look for its parent class.
+     */
+    private static Class<?>[] getParentTypes(final Class<?> type) {
+        return type.isInterface() ? type.getInterfaces() : new Class<?>[] {type.getSuperclass()};
+    }
+
+    /**
      * Returns {@code true} if the given metadata type is a subtype of another metadata.
      * If true, then we will need to prefix the identifier by the metadata subtype.
      *
@@ -535,7 +545,7 @@ public class MetadataWriter extends Meta
      *         the result is nevertheless given as a {@code Boolean} wrapper for consistency
with {@code createTable(…)}.
      */
     private Boolean isChildTable(final Class<?> type) {
-        for (final Class<?> candidate : type.getInterfaces()) {
+        for (final Class<?> candidate : getParentTypes(type)) {
             if (standard.isMetadata(candidate)) {
                 return Boolean.TRUE;
             }
@@ -562,7 +572,7 @@ public class MetadataWriter extends Meta
         if (columns.isEmpty()) {
             isChildTable = Boolean.FALSE;
             StringBuilder inherits = null;
-            for (final Class<?> candidate : type.getInterfaces()) {
+            for (final Class<?> candidate : getParentTypes(type)) {
                 if (standard.isMetadata(candidate)) {
                     isChildTable = Boolean.TRUE;
                     final SQLBuilder helper = helper();

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java?rev=1796388&r1=1796387&r2=1796388&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java
[UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java
[UTF-8] Sat May 27 11:58:34 2017
@@ -30,6 +30,29 @@ import static org.junit.Assume.*;
  * Utility methods for creating temporary databases with Derby.
  * The databases are in-memory only.
  *
+ * <div class="section">Inspecting the database content in a debugger</div>
+ * Make sure that the classpath contains the {@code derbynet.jar} file in addition to {@code
derby.jar}.
+ * Then, specify the following options to the JVM (replace the 1527 port number by something
else if needed):
+ *
+ * {@preformat text
+ *   -Dderby.drda.startNetworkServer=true
+ *   -Dderby.drda.portNumber=1527
+ * }
+ *
+ * When the application is running, one can verify that the Derby server is listening:
+ *
+ * {@preformat text
+ *   netstat -an | grep "1527"
+ * }
+ *
+ * To connect to the in-memory database, use the {@code "jdbc:derby://localhost:1527/dbname"}
URL
+ * (replace {@code "dbname"} by the actual database name.
+ *
+ * <p><b>References:</b>
+ * <ul>
+ *   <li><a href="https://db.apache.org/derby/docs/10.2/adminguide/radminembeddedserverex.html">Embedded
server example</a></li>
+ * </ul>
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 0.7
  * @since   0.7

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataWriterTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataWriterTest.java?rev=1796388&r1=1796387&r2=1796388&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataWriterTest.java
[UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataWriterTest.java
[UTF-8] Sat May 27 11:58:34 2017
@@ -160,8 +160,7 @@ public final strictfp class MetadataWrit
         final ResponsibleParty responsible = TestUtilities.getSingleton(c.getCitedResponsibleParties());
         assertEquals(Role.PRINCIPAL_INVESTIGATOR, responsible.getRole());
 
-        org.junit.Assume.assumeTrue("TODO: needs to investigate why information are lost.",
false);
-        assertEquals("International Association of Oil & Gas Producers", responsible.getOrganisationName());
+        assertEquals("International Association of Oil & Gas Producers", responsible.getOrganisationName().toString());
 
         OnlineResource resource = responsible.getContactInfo().getOnlineResource();
         assertEquals("http://www.epsg.org", resource.getLinkage().toString());
@@ -202,6 +201,8 @@ public final strictfp class MetadataWrit
      */
     @SuppressWarnings("deprecation")
     private void readWriteDeprecated() throws MetadataStoreException {
+        org.junit.Assume.assumeTrue("TODO: needs to investigate why information are lost.",
false);
+
         final DefaultTelephone tel = new DefaultTelephone();
         tel.setVoices(Collections.singleton("01.02.03.04"));
         assertEquals("01.02.03.04", source.add(tel));

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java?rev=1796388&r1=1796387&r2=1796388&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java [UTF-8] Sat
May 27 11:58:34 2017
@@ -502,9 +502,9 @@ public final class Types extends Static
     }
 
     /**
-     * Returns the GeoAPI interface for the given ISO name, or {@code null} if none.
-     * The identifier argument shall be the value documented in the {@link UML#identifier()}
-     * annotation associated with the GeoAPI interface.
+     * Returns the Java type (usually a GeoAPI interface) for the given ISO name, or {@code
null} if none.
+     * The identifier argument shall be the value documented in the {@link UML#identifier()}
annotation on
+     * the Java type.
      *
      * <div class="note"><b>Examples:</b>
      * <ul>
@@ -513,8 +513,16 @@ public final class Types extends Static
      * </ul>
      * </div>
      *
-     * Only identifiers for the stable part of GeoAPI are recognized. This method does not
handle
-     * the identifiers for the {@code geoapi-pending} module.
+     * Only identifiers for the stable part of GeoAPI or for some Apache SIS classes are
recognized.
+     * This method does not handle the identifiers for interfaces in the {@code geoapi-pending}
module.
+     *
+     * <div class="note"><b>Future evolution:</b>
+     * when a new ISO type does not yet have a corresponding GeoAPI interface,
+     * this method may temporarily return an Apache SIS class instead until a future version
can use the interface.
+     * For example {@code forStandardName("CI_Individual")} returns
+     * <code>{@linkplain org.apache.sis.metadata.iso.citation.DefaultIndividual}.class</code>
in Apache SIS versions
+     * that depend on GeoAPI 3.0, but the return type may be changed to {@code Individual.class}
when Apache SIS will
+     * be upgraded to GeoAPI 3.1.</div>
      *
      * @param  identifier  the ISO {@linkplain UML} identifier, or {@code null}.
      * @return the GeoAPI interface, or {@code null} if the given identifier is {@code null}
or unknown.

Modified: sis/trunk/ide-project/NetBeans/nbproject/project.properties
URL: http://svn.apache.org/viewvc/sis/trunk/ide-project/NetBeans/nbproject/project.properties?rev=1796388&r1=1796387&r2=1796388&view=diff
==============================================================================
--- sis/trunk/ide-project/NetBeans/nbproject/project.properties [ISO-8859-1] (original)
+++ sis/trunk/ide-project/NetBeans/nbproject/project.properties [ISO-8859-1] Sat May 27 11:58:34
2017
@@ -38,8 +38,9 @@ source.encoding      = UTF-8
 javac.source         = 1.7
 javac.target         = 1.7
 platform.active      = default_platform
-run.jvmargs          = -ea -Dorg.apache.sis.test.verbose=true -Dorg.apache.sis.test.extensive=true
 junit.forkmode       = once
+run.jvmargs          = -ea -Dorg.apache.sis.test.verbose=true -Dorg.apache.sis.test.extensive=true
+#                      -Dderby.drda.startNetworkServer=true -Dderby.drda.portNumber=1527
 
 #
 # Source directories.



Mime
View raw message