Author: desruisseaux Date: Sat Sep 9 20:03:36 2017 New Revision: 1807924 URL: http://svn.apache.org/viewvc?rev=1807924&view=rev Log: Allow foreigner code to find Apache SIS CRSAuthorityFactory without any implementation-dependent code.
Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/EPSGFactoryProxy.java (with props) Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java sis/branches/JDK8/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AuthorityFactoriesTest.java sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/LazySet.java Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/EPSGFactoryProxy.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/EPSGFactoryProxy.java?rev=1807924&view=auto ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/EPSGFactoryProxy.java (added) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/EPSGFactoryProxy.java [UTF-8] Sat Sep 9 20:03:36 2017 @@ -0,0 +1,148 @@ +/* + * 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.internal.referencing; + +import java.util.Set; +import org.apache.sis.referencing.CRS; +import org.opengis.metadata.citation.Citation; +import org.opengis.referencing.IdentifiedObject; +import org.opengis.referencing.crs.CRSAuthorityFactory; +import org.opengis.referencing.crs.CompoundCRS; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.crs.DerivedCRS; +import org.opengis.referencing.crs.EngineeringCRS; +import org.opengis.referencing.crs.GeocentricCRS; +import org.opengis.referencing.crs.GeographicCRS; +import org.opengis.referencing.crs.ImageCRS; +import org.opengis.referencing.crs.ParametricCRS; +import org.opengis.referencing.crs.ProjectedCRS; +import org.opengis.referencing.crs.TemporalCRS; +import org.opengis.referencing.crs.VerticalCRS; +import org.opengis.util.FactoryException; +import org.opengis.util.InternationalString; + + +/** + * A factory that redirect all method to another factory. This factory is normally useless and not used by Apache SIS. + * The sole purpose of this factory is to give an access to the EPSG factory through {@link java.util.ServiceLoader}. + * We have to use this indirection level because the EPSG factory is managed in a special way by Apache SIS. + * + * <p>This class will be modified on the JDK9 branch in order to replace the proxy by a static {@code provider()} + * method. This will allow us to remove all the indirection level currently found in this class.</p> + */ +public final class EPSGFactoryProxy implements CRSAuthorityFactory { + private volatile CRSAuthorityFactory factory; + + public EPSGFactoryProxy() { + } + + private CRSAuthorityFactory factory() throws FactoryException { + CRSAuthorityFactory f = factory; + if (f == null) { + factory = f = CRS.getAuthorityFactory("EPSG"); + } + return f; + } + + @Override + public Citation getAuthority() { + try { + return factory().getAuthority(); + } catch (FactoryException e) { + throw new RuntimeException(e); + } + } + + @Override + public Citation getVendor() { + try { + return factory().getVendor(); + } catch (FactoryException e) { + throw new RuntimeException(e); + } + } + + @Override + public InternationalString getDescriptionText(String code) throws FactoryException { + return factory().getDescriptionText(code); + } + + @Override + public IdentifiedObject createObject(String code) throws FactoryException { + return factory().createObject(code); + } + + @Override + public CoordinateReferenceSystem createCoordinateReferenceSystem(String code) throws FactoryException { + return factory().createCoordinateReferenceSystem(code); + } + + @Override + public CompoundCRS createCompoundCRS(String code) throws FactoryException { + return factory().createCompoundCRS(code); + } + + @Override + public DerivedCRS createDerivedCRS(String code) throws FactoryException { + return factory().createDerivedCRS(code); + } + + @Override + public EngineeringCRS createEngineeringCRS(String code) throws FactoryException { + return factory().createEngineeringCRS(code); + } + + @Override + public GeographicCRS createGeographicCRS(String code) throws FactoryException { + return factory().createGeographicCRS(code); + } + + @Override + public GeocentricCRS createGeocentricCRS(String code) throws FactoryException { + return factory().createGeocentricCRS(code); + } + + @Override + public ImageCRS createImageCRS(String code) throws FactoryException { + return factory().createImageCRS(code); + } + + @Override + public ProjectedCRS createProjectedCRS(String code) throws FactoryException { + return factory().createProjectedCRS(code); + } + + @Override + public TemporalCRS createTemporalCRS(String code) throws FactoryException { + return factory().createTemporalCRS(code); + } + + @Override + public VerticalCRS createVerticalCRS(String code) throws FactoryException { + return factory().createVerticalCRS(code); + } + + @Override + public ParametricCRS createParametricCRS(String code) throws FactoryException { + return factory().createParametricCRS(code); + } + + @Override + public Set<String> getAuthorityCodes(Class<? extends IdentifiedObject> type) throws FactoryException { + return factory().getAuthorityCodes(type); + } +} Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/EPSGFactoryProxy.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/EPSGFactoryProxy.java ------------------------------------------------------------------------------ svn:mime-type = text/plain;charset=UTF-8 Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java?rev=1807924&r1=1807923&r2=1807924&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java [UTF-8] Sat Sep 9 20:03:36 2017 @@ -16,6 +16,7 @@ */ package org.apache.sis.referencing; +import java.util.Iterator; import java.util.ServiceLoader; import java.util.logging.Level; import java.util.logging.LogRecord; @@ -30,6 +31,7 @@ import org.apache.sis.internal.util.Lazy import org.apache.sis.internal.system.Loggers; import org.apache.sis.internal.system.Modules; import org.apache.sis.internal.system.SystemListener; +import org.apache.sis.internal.referencing.EPSGFactoryProxy; import org.apache.sis.referencing.factory.MultiAuthoritiesFactory; import org.apache.sis.referencing.factory.GeodeticAuthorityFactory; import org.apache.sis.referencing.factory.UnavailableFactoryException; @@ -58,7 +60,8 @@ final class AuthorityFactories<T extends /** * The unique system-wide authority factory instance that contains all factories found on the classpath, - * plus the EPSG factory. + * plus the EPSG factory. The {@link EPSGFactoryProxy} most be excluded from this list, since the EPSG + * factory is handled in a special way. */ static final MultiAuthoritiesFactory ALL = new MultiAuthoritiesFactory( new AuthorityFactories<>(CRSAuthorityFactory.class), @@ -211,4 +214,18 @@ final class AuthorityFactories<T extends EPSG(); // Force EPSGFactory instantiation if not already done. return (T[]) EPSG; } + + /** + * Invoked by {@link LazySet} for fetching the next element from the given iterator. + * Skips the {@link EPSGFactoryProxy} if possible, or returns {@code null} otherwise. + * Note that {@link MultiAuthoritiesFactory} is safe to null values. + */ + @Override + protected T next(final Iterator<? extends T> it) { + T e = it.next(); + if (e instanceof EPSGFactoryProxy) { + e = it.hasNext() ? it.next() : null; + } + return e; + } } Modified: sis/branches/JDK8/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory?rev=1807924&r1=1807923&r2=1807924&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory [UTF-8] Sat Sep 9 20:03:36 2017 @@ -1,2 +1,3 @@ # Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. +org.apache.sis.internal.referencing.EPSGFactoryProxy org.apache.sis.referencing.factory.CommonAuthorityFactory Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AuthorityFactoriesTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AuthorityFactoriesTest.java?rev=1807924&r1=1807923&r2=1807924&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AuthorityFactoriesTest.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AuthorityFactoriesTest.java [UTF-8] Sat Sep 9 20:03:36 2017 @@ -17,6 +17,7 @@ package org.apache.sis.referencing; import java.util.Collection; +import java.util.ServiceLoader; import org.opengis.util.FactoryException; import org.opengis.referencing.NoSuchAuthorityCodeException; import org.opengis.referencing.IdentifiedObject; @@ -26,7 +27,9 @@ import org.opengis.referencing.crs.Geogr import org.apache.sis.util.ComparisonMode; import org.apache.sis.internal.system.Loggers; import org.apache.sis.internal.util.Constants; +import org.apache.sis.internal.referencing.EPSGFactoryProxy; import org.apache.sis.referencing.crs.HardCodedCRS; +import org.apache.sis.referencing.factory.CommonAuthorityFactory; import org.apache.sis.referencing.factory.IdentifiedObjectFinder; import org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException; @@ -66,6 +69,28 @@ public final strictfp class AuthorityFac } /** + * Ensures that {@link EPSGFactoryProxy} is declared before {@link CommonAuthorityFactory}. + * This is preferable (but not mandatory) because of the way we implemented {@link AuthorityFactories}. + */ + @Test + public void testFactoryOrder() { + boolean foundProxy = false; + boolean foundCommon = false; + for (CRSAuthorityFactory factory : ServiceLoader.load(CRSAuthorityFactory.class, AuthorityFactories.class.getClassLoader())) { + if (factory instanceof CommonAuthorityFactory) { + foundCommon = true; + assertTrue("Should not have found EPSGFactoryProxy after CommonAuthorityFactory.", foundProxy); + } + if (factory instanceof EPSGFactoryProxy) { + foundProxy = true; + assertFalse("Should not have found EPSGFactoryProxy after CommonAuthorityFactory.", foundCommon); + } + } + assertTrue("Factory not found.", foundCommon); + assertTrue("Factory not found.", foundProxy); + } + + /** * Tests {@link CRSAuthorityFactory#getDescriptionText(String)}. * * @throws FactoryException if the EPSG:4326 name can not be obtained. Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/LazySet.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/LazySet.java?rev=1807924&r1=1807923&r2=1807924&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/LazySet.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/LazySet.java [UTF-8] Sat Sep 9 20:03:36 2017 @@ -184,7 +184,7 @@ public class LazySet<E> extends SetOfUnk public final int size() { if (canPullMore()) { while (sourceIterator.hasNext()) { - cache(sourceIterator.next()); + cache(next(sourceIterator)); } sourceIterator = null; } @@ -192,6 +192,19 @@ public class LazySet<E> extends SetOfUnk } /** + * Returns the next element from the given iterator. Default implementation returns {@link Iterator#next()}. + * Subclasses may override if they need to apply additional processing. For example this method can be used + * for skipping data, but this approach works only if we have the guarantee that another element exists after + * the skipped one (because {@code LazySet} will not invoke {@link Iterator#hasNext()} again). + * + * @param it the iterator from which to get a next value. + * @return the next value (may be {@code null}). + */ + protected E next(final Iterator<? extends E> it) { + return it.next(); + } + + /** * Caches a new element. Subclasses can override this method is they want to substitute the given value * by another value. * @@ -238,7 +251,7 @@ public class LazySet<E> extends SetOfUnk assert index <= numCached : index; if (index >= numCached) { if (canPullMore()) { - cache(sourceIterator.next()); + cache(next(sourceIterator)); } else { throw new NoSuchElementException(); }