sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1726677 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/referencing/factory/ test/java/org/apache/sis/referencing/factory/
Date Mon, 25 Jan 2016 20:05:43 GMT
Author: desruisseaux
Date: Mon Jan 25 20:05:43 2016
New Revision: 1726677

URL: http://svn.apache.org/viewvc?rev=1726677&view=rev
Log:
Implement MultiAuthoritiesFactory.newIdentifiedObjectFinder().

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/AuthorityFactoryMock.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java?rev=1726677&r1=1726676&r2=1726677&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
[UTF-8] Mon Jan 25 20:05:43 2016
@@ -1785,19 +1785,6 @@ public abstract class ConcurrentAuthorit
         }
 
         /**
-         * Returns the authority of the factory examined by this finder.
-         */
-        @Override
-        public synchronized Citation getAuthority() throws FactoryException {
-            try {
-                acquire();
-                return finder.getAuthority();
-            } finally {
-                release();
-            }
-        }
-
-        /**
          * Returns a set of authority codes that <strong>may</strong> identify
the same
          * object than the specified one. This method delegates to the data access object.
          */

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java?rev=1726677&r1=1726676&r2=1726677&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
[UTF-8] Mon Jan 25 20:05:43 2016
@@ -23,15 +23,14 @@ import java.util.LinkedHashSet;
 import org.opengis.util.GenericName;
 import org.opengis.util.FactoryException;
 import org.opengis.metadata.Identifier;
-import org.opengis.metadata.citation.Citation;
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.AuthorityFactory;
 import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.referencing.IdentifiedObjects;
-import org.apache.sis.internal.util.Citations;
 import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.collection.BackingStoreException;
+import org.apache.sis.util.iso.DefaultNameSpace;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ComparisonMode;
@@ -154,6 +153,13 @@ public class IdentifiedObjectFinder {
     private boolean ignoreAxes;
 
     /**
+     * {@code true} if the search should ignore names, aliases and identifiers. This is set
to {@code true}
+     * only when this finder is wrapped by a {@link MultiAuthoritiesFactory} finder, which
performs it own
+     * search based on identifiers.
+     */
+    boolean ignoreIdentifiers;
+
+    /**
      * Creates a finder using the specified factory.
      *
      * <div class="note"><b>Design note:</b>
@@ -186,17 +192,6 @@ public class IdentifiedObjectFinder {
     }
 
     /**
-     * Returns the authority of the factory used by this finder.
-     * The default implementation delegates to {@link GeodeticAuthorityFactory#getAuthority()}.
-     *
-     * @return The authority of the factory used for the searches, or {@code null} if unknown.
-     * @throws FactoryException If an error occurred while fetching the authority.
-     */
-    public Citation getAuthority() throws FactoryException {
-        return factory.getAuthority();
-    }
-
-    /**
      * Returns the domain of the search (for example whether to include deprecated objects
in the search).
      * If {@code DECLARATION}, only a fast lookup based on embedded identifiers and names
will be performed.
      * Otherwise an exhaustive full scan against all registered objects will be performed
(may be slow).
@@ -305,23 +300,25 @@ public class IdentifiedObjectFinder {
             final AuthorityFactoryProxy<?> previous = proxy;
             proxy = AuthorityFactoryProxy.getInstance(object.getClass());
             try {
-                /*
-                 * First check if one of the identifiers can be used to find directly an
identified object.
-                 * Verify that the object that we found is actually equal to given one; we
do not blindly
-                 * trust the identifiers in the user object.
-                 */
-                IdentifiedObject candidate = createFromIdentifiers(object);
-                if (candidate != null) {
-                    return Collections.singleton(candidate);    // Not worth to cache.
-                }
-                /*
-                 * We are unable to find the object from its identifiers. Try a quick name
lookup.
-                 * Some implementations like the one backed by the EPSG database are capable
to find
-                 * an object from its name.
-                 */
-                candidate = createFromNames(object);
-                if (candidate != null) {
-                    return Collections.singleton(candidate);    // Not worth to cache.
+                if (!ignoreIdentifiers) {
+                    /*
+                     * First check if one of the identifiers can be used to find directly
an identified object.
+                     * Verify that the object that we found is actually equal to given one;
we do not blindly
+                     * trust the identifiers in the user object.
+                     */
+                    IdentifiedObject candidate = createFromIdentifiers(object);
+                    if (candidate != null) {
+                        return Collections.singleton(candidate);    // Not worth to cache.
+                    }
+                    /*
+                     * We are unable to find the object from its identifiers. Try a quick
name lookup.
+                     * Some implementations like the one backed by the EPSG database are
capable to find
+                     * an object from its name.
+                     */
+                    candidate = createFromNames(object);
+                    if (candidate != null) {
+                        return Collections.singleton(candidate);    // Not worth to cache.
+                    }
                 }
                 /*
                  * Here we exhausted the quick paths.
@@ -385,10 +382,15 @@ public class IdentifiedObjectFinder {
      * @see #createFromNames(IdentifiedObject)
      */
     private IdentifiedObject createFromIdentifiers(final IdentifiedObject object) throws
FactoryException {
-        final Citation authority = getAuthority();
         for (final Identifier id : object.getIdentifiers()) {
-            if (Citations.identifierMatches(authority, id.getAuthority())) {
-                final String code = IdentifiedObjects.toString(id);
+            final String code = IdentifiedObjects.toString(id);
+            /*
+             * We will process only codes with a namespace (e.g. "AUTHORITY:CODE") for avoiding
ambiguity.
+             * We do not try to check by ourselves if the identifier is in the namespace
of the factory,
+             * because calling factory.getAuthorityCodes() or factory.getCodeSpaces() may
be costly for
+             * some implementations.
+             */
+            if (code.indexOf(DefaultNameSpace.DEFAULT_SEPARATOR) >= 0) {
                 final IdentifiedObject candidate;
                 try {
                     candidate = create(code);
@@ -458,11 +460,11 @@ public class IdentifiedObjectFinder {
     /**
      * Creates an object equals (optionally ignoring metadata), to the specified object.
      * This method scans the {@linkplain #getCodeCandidates(IdentifiedObject) authority codes},
-     * create the objects and returns the first one which is equal to the specified object
in
+     * creates the objects and returns the first one which is equal to the specified object
in
      * the sense of {@link Utilities#deepEquals(Object, Object, ComparisonMode)}.
      *
-     * <p>This method may be used in order to get a fully {@linkplain AbstractIdentifiedObject
identified
-     * object} from an object without {@linkplain AbstractIdentifiedObject#getIdentifiers()
identifiers}.</p>
+     * <p>This method may be used in order to get a fully {@linkplain AbstractIdentifiedObject
identified object}
+     * from an object without {@linkplain AbstractIdentifiedObject#getIdentifiers() identifiers}.</p>
      *
      * <p>Scanning the whole set of authority codes may be slow. Users should try
      * <code>{@linkplain #createFromIdentifiers createFromIdentifiers}(object)</code>
and/or
@@ -476,7 +478,7 @@ public class IdentifiedObjectFinder {
      * @see #createFromIdentifiers(IdentifiedObject)
      * @see #createFromNames(IdentifiedObject)
      */
-    private Set<IdentifiedObject> createFromCodes(final IdentifiedObject object) throws
FactoryException {
+    Set<IdentifiedObject> createFromCodes(final IdentifiedObject object) throws FactoryException
{
         final Set<IdentifiedObject> result = new LinkedHashSet<>();     // We
need to preserve order.
         for (final String code : getCodeCandidates(object)) {
             final IdentifiedObject candidate;
@@ -536,6 +538,6 @@ public class IdentifiedObjectFinder {
      * Invoked when an exception occurred during the creation of a candidate from a code.
      */
     private static void exceptionOccurred(final FactoryException exception) {
-        Logging.recoverableException(Logging.getLogger(Loggers.CRS_FACTORY), IdentifiedObjectFinder.class,
"fine", exception);
+        Logging.recoverableException(Logging.getLogger(Loggers.CRS_FACTORY), IdentifiedObjectFinder.class,
"find", exception);
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java?rev=1726677&r1=1726676&r2=1726677&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
[UTF-8] Mon Jan 25 20:05:43 2016
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.facto
 import java.util.ServiceLoader;
 import java.util.Collections;
 import java.util.Collection;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Set;
 import java.util.Map;
@@ -1361,13 +1362,109 @@ public class MultiAuthoritiesFactory ext
     }
 
     /**
-     * Clears the cache and notifies all factories need to be fetched again from the providers
given at
-     * construction time. All providers that are instances of {@link ServiceLoader} will
have their
-     * {@link ServiceLoader#reload() reload()} method invoked.
+     * Returns a finder which can be used for looking up unidentified objects.
+     * The default implementation delegates the lookups to the underlying factories.
+     *
+     * @return A finder to use for looking up unidentified objects.
+     * @throws FactoryException if the finder can not be created.
+     */
+    @Override
+    public IdentifiedObjectFinder newIdentifiedObjectFinder() throws FactoryException {
+        return new Finder(this);
+    }
+
+    /**
+     * A {@link IdentifiedObjectFinder} which tests every factories declared in the
+     * {@linkplain MultiAuthoritiesFactory#getAllFactories() collection of factories}.
+     */
+    private static class Finder extends IdentifiedObjectFinder {
+        /**
+         * The finders of all factories, or {@code null} if not yet fetched.
+         * We will create this array only when first needed in order to avoid instantiating
the factories
+         * before needed (for example we may be able to find an object using only its code).
However if we
+         * need to create this array, then we will create it fully (for all factories at
once).
+         */
+        private IdentifiedObjectFinder[] finders;
+
+        /**
+         * Creates a new finder.
+         */
+        protected Finder(final MultiAuthoritiesFactory factory) throws FactoryException {
+            super(factory);
+        }
+
+        /**
+         * Sets the domain of the search (for example whether to include deprecated objects
in the search).
+         */
+        @Override
+        public void setSearchDomain(final Domain domain) {
+            super.setSearchDomain(domain);
+            if (finders != null) {
+                for (final IdentifiedObjectFinder finder : finders) {
+                    finder.setSearchDomain(domain);
+                }
+            }
+        }
+
+        /**
+         * Sets whether the search should ignore coordinate system axes.
+         */
+        @Override
+        public void setIgnoringAxes(final boolean ignore) {
+            super.setIgnoringAxes(ignore);
+            if (finders != null) {
+                for (final IdentifiedObjectFinder finder : finders) {
+                    finder.setIgnoringAxes(ignore);
+                }
+            }
+        }
+
+        /**
+         * Delegates to every factories registered in the enclosing {@link MultiAuthoritiesFactory},
+         * in iteration order. This method is invoked only if the parent class failed to
find the
+         * object by its identifiers and by its name. At this point, as a last resource,
we will
+         * scan over the objects in the database.
+         *
+         * <p>This method shall <strong>not</strong> delegate the job to
the parent class, as the default
+         * implementation in the parent class is very inefficient. We need to delegate to
the finders of
+         * all factories, so we can leverage their potentially more efficient algorithms.</p>
+         */
+        @Override
+        final Set<IdentifiedObject> createFromCodes(final IdentifiedObject object)
throws FactoryException {
+            if (finders == null) try {
+                final ArrayList<IdentifiedObjectFinder> list = new ArrayList<>();
+                final Map<AuthorityFactory,Boolean> unique = new IdentityHashMap<>();
+                final Iterator<AuthorityFactory> it = ((MultiAuthoritiesFactory) factory).getAllFactories();
+                while (it.hasNext()) {
+                    final AuthorityFactory candidate = it.next();
+                    if (candidate instanceof GeodeticAuthorityFactory && unique.put(candidate,
Boolean.TRUE) == null) {
+                        IdentifiedObjectFinder finder = ((GeodeticAuthorityFactory) candidate).newIdentifiedObjectFinder();
+                        if (finder != null) {   // Should never be null according method
contract, but we are paranoiac.
+                            finder.ignoreIdentifiers = true;
+                            finder.setWrapper(this);
+                            list.add(finder);
+                        }
+                    }
+                }
+                finders = list.toArray(new IdentifiedObjectFinder[list.size()]);
+            } catch (BackingStoreException e) {
+                throw e.unwrapOrRethrow(FactoryException.class);
+            }
+            final Set<IdentifiedObject> found = new LinkedHashSet<>();
+            for (final IdentifiedObjectFinder finder : finders) {
+                found.addAll(finder.find(object));
+            }
+            return found;
+        }
+    }
+
+    /**
+     * Clears the cache and notifies this {@code MultiAuthoritiesFactory} that all factories
will need to
+     * be fetched again from the providers given at construction time. In addition, all providers
that are
+     * instances of {@link ServiceLoader} will have their {@link ServiceLoader#reload() reload()}
method invoked.
      *
      * <p>This method is intended for use in situations in which new factories can
be installed into a running
-     * Java virtual machine. This method invocation will happen automatically if Apache SIS
is running in a
-     * servlet or OSGi container.</p>
+     * Java virtual machine.</p>
      */
     public void reload() {
         for (int type=0; type < providers.length; type++) {

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/AuthorityFactoryMock.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/AuthorityFactoryMock.java?rev=1726677&r1=1726676&r2=1726677&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/AuthorityFactoryMock.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/AuthorityFactoryMock.java
[UTF-8] Mon Jan 25 20:05:43 2016
@@ -116,7 +116,13 @@ public final strictfp class AuthorityFac
      */
     @Override
     public IdentifiedObject createObject(final String code) throws NoSuchAuthorityCodeException
{
-        switch (Integer.parseInt(trimNamespace(code))) {
+        final int n;
+        try {
+            n = Integer.parseInt(trimNamespace(code));
+        } catch (NumberFormatException e) {
+            throw new NoSuchAuthorityCodeException(e.toString(), "MOCK", code);
+        }
+        switch (n) {
             case   84: return HardCodedCRS.WGS84;
             case 4326: return HardCodedCRS.WGS84_φλ;
             case 4979: return HardCodedCRS.GEOCENTRIC;
@@ -144,7 +150,13 @@ public final strictfp class AuthorityFac
      */
     @Override
     public Unit<?> createUnit(final String code) throws NoSuchAuthorityCodeException
{
-        final Unit<?> unit = Units.valueOfEPSG(Integer.parseInt(trimNamespace(code)));
+        final int n;
+        try {
+            n = Integer.parseInt(trimNamespace(code));
+        } catch (NumberFormatException e) {
+            throw new NoSuchAuthorityCodeException(e.toString(), "MOCK", code);
+        }
+        final Unit<?> unit = Units.valueOfEPSG(n);
         if (unit == null) {
             throw new NoSuchAuthorityCodeException(code, authority.getTitle().toString(),
code);
         }
@@ -159,7 +171,13 @@ public final strictfp class AuthorityFac
      */
     @Override
     public Extent createExtent(final String code) throws NoSuchAuthorityCodeException {
-        switch (Integer.parseInt(trimNamespace(code))) {
+        final int n;
+        try {
+            n = Integer.parseInt(trimNamespace(code));
+        } catch (NumberFormatException e) {
+            throw new NoSuchAuthorityCodeException(e.toString(), "MOCK", code);
+        }
+        switch (n) {
             case 1262: return Extents.WORLD;
             default: throw new NoSuchAuthorityCodeException(code, authority.getTitle().toString(),
code);
         }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java?rev=1726677&r1=1726676&r2=1726677&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java
[UTF-8] Mon Jan 25 20:05:43 2016
@@ -307,4 +307,19 @@ public final strictfp class MultiAuthori
         assertFalse("isEmpty()", codes.isEmpty());
         assertArrayEquals(new String[] {"MOCK:4979", "MOCK:84", "MOCK:4326", "MOCK:5714",
"MOCK:9905"}, codes.toArray());
     }
+
+    /**
+     * Tests {@link MultiAuthoritiesFactory#newIdentifiedObjectFinder()}.
+     *
+     * @throws FactoryException if an error occurred while creating the finder.
+     */
+    @Test
+    public void testNewIdentifiedObjectFinder() throws FactoryException {
+        final List<AuthorityFactoryMock> mock = Arrays.asList(
+                new AuthorityFactoryMock("MOCK", null),
+                new AuthorityFactoryMock("MOCK", "2.3"));
+        final MultiAuthoritiesFactory factory = new MultiAuthoritiesFactory(mock, null, mock,
null);
+        final IdentifiedObjectFinder finder = factory.newIdentifiedObjectFinder();
+        assertSame(HardCodedDatum.WGS72, finder.findSingleton(HardCodedDatum.WGS72));
+    }
 }



Mime
View raw message