svn - r33505 - in trunk/modules/unsupported/app-schema/app-schema/src: main/java/org/geotools/data/complex main/java/org/geotools/data/complex/filter test/java/org/geotools/data/complex test/resources/test-data

1 message Options
Embed this post
Permalink
svn_geotools

svn - r33505 - in trunk/modules/unsupported/app-schema/app-schema/src: main/java/org/geotools/data/complex main/java/org/geotools/data/complex/filter test/java/org/geotools/data/complex test/resources/test-data

Reply Threaded More More options
Print post
Permalink
Author: ang05a
Date: 2009-07-07 03:42:11 -0400 (Tue, 07 Jul 2009)
New Revision: 33505

Modified:
   trunk/modules/unsupported/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingFeatureIterator.java
   trunk/modules/unsupported/app-schema/app-schema/src/main/java/org/geotools/data/complex/filter/XPath.java
   trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/AppSchemaDataAccessIntegrationTest.java
   trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/DataAccessIntegrationTest.java
   trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/FeatureChainingTest.java
   trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/GeologicUnitTest.java
   trunk/modules/unsupported/app-schema/app-schema/src/test/resources/test-data/EarthResourceToGeologicUnit.xml
Log:
- tidy up feature chaining tests
- make sure all instances of multi-valued properties are mapped from a non-app-schema data access to app-schema data access

Modified: trunk/modules/unsupported/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingFeatureIterator.java
===================================================================
--- trunk/modules/unsupported/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingFeatureIterator.java 2009-07-07 06:16:23 UTC (rev 33504)
+++ trunk/modules/unsupported/app-schema/app-schema/src/main/java/org/geotools/data/complex/MappingFeatureIterator.java 2009-07-07 07:42:11 UTC (rev 33505)
@@ -253,9 +253,10 @@
         return value;
     }
 
-    protected Object getValues(Expression expression, ComplexAttribute sourceFeature,
-            boolean isNestedFeature) {
-        if (sourceFeature instanceof FeatureImpl && isNestedFeature) {
+    protected Object getValues(boolean isMultiValued, Expression expression,
+            ComplexAttribute sourceFeature) {
+        if (isMultiValued && sourceFeature instanceof FeatureImpl
+                && expression instanceof AttributeExpressionImpl) {
             // RA: Feature Chaining
             // complex features can have multiple nodes of the same attribute.. and if they are used
             // as input to an app-schema data access to be nested inside another feature type of a
@@ -273,7 +274,6 @@
             // </AttributeMapping>
             // As there can be multiple nodes of mo:composition in this case, we need to retrieve
             // all of them
-            assert expression instanceof AttributeExpressionImpl;
             AttributeExpressionImpl attribExpression = ((AttributeExpressionImpl) expression);
             String xpath = attribExpression.getPropertyName();
             StepList xpathSteps = XPath.steps(sourceFeature.getDescriptor(), xpath, namespaces);
@@ -313,7 +313,7 @@
         Map<Name, Expression> clientPropsMappings = attMapping.getClientProperties();
 
         boolean isNestedFeature = attMapping.isNestedAttribute();
-        Object value = getValues(sourceExpression, source, isNestedFeature);
+        Object value = getValues(attMapping.isMultiValued(), sourceExpression, source);
         boolean isHRefLink = isByReference(clientPropsMappings, isNestedFeature);
         if (isNestedFeature) {
             // get built feature based on link value
@@ -358,11 +358,13 @@
         }
         if (isNestedFeature) {
             assert (value instanceof Collection);
+        }
+        if (value instanceof Collection) {
             // nested feature type could have multiple instances as the whole purpose
             // of feature chaining is to cater for multi-valued properties
             for (Object singleVal : (Collection) value) {
-                ArrayList<Feature> valueList = new ArrayList<Feature>();
-                valueList.add((Feature) singleVal);
+                ArrayList<Property> valueList = new ArrayList<Property>();
+                valueList.add((Property) singleVal);
                 Attribute instance = xpathAttributeBuilder.set(target, xpath, valueList, id,
                         targetNodeType, false);
                 setClientProperties(instance, source, clientPropsMappings);

Modified: trunk/modules/unsupported/app-schema/app-schema/src/main/java/org/geotools/data/complex/filter/XPath.java
===================================================================
--- trunk/modules/unsupported/app-schema/app-schema/src/main/java/org/geotools/data/complex/filter/XPath.java 2009-07-07 06:16:23 UTC (rev 33504)
+++ trunk/modules/unsupported/app-schema/app-schema/src/main/java/org/geotools/data/complex/filter/XPath.java 2009-07-07 07:42:11 UTC (rev 33505)
@@ -713,7 +713,7 @@
         final AttributeType type = descriptor.getType();
         Class<?> binding = type.getBinding();
         if (type instanceof ComplexType && binding == Collection.class) {
-            if (isSimpleContentType(type)) {
+            if (!(value instanceof Collection) && isSimpleContentType(type)) {
                 ArrayList<Property> list = new ArrayList<Property>();
                 list.add(buildSimpleContent(type, value));
                 return list;

Modified: trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/AppSchemaDataAccessIntegrationTest.java
===================================================================
--- trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/AppSchemaDataAccessIntegrationTest.java 2009-07-07 06:16:23 UTC (rev 33504)
+++ trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/AppSchemaDataAccessIntegrationTest.java 2009-07-07 07:42:11 UTC (rev 33505)
@@ -97,7 +97,7 @@
         moParams.put("dbtype", "mo-data-access");
         moParams.put("directory", getClass().getResource(schemaBase));
         // get original non-app-schema data access
-        inputDataAccess = DataAccessFinder.getDataStore(moParams);
+        DataAccessFinder.getDataStore(moParams);
         super.setFilterFactory();
         // load app-schema data access instances
         loadDataAccesses("MappedFeatureAsOccurrence.xml");
@@ -109,7 +109,6 @@
     @Override
     protected void tearDown() {
         super.tearDown();
-        newGuDataAccess.dispose();
     }
 
     @Override
@@ -164,6 +163,10 @@
         AttributeDescriptor stringDescriptor = new AttributeDescriptorImpl(simpleContentType, name,
                 1, 1, true, (Object) null);
         Iterator<SimpleFeature> simpleFeatures = fCollection.iterator();
+        // gml:name descriptor
+        AttributeDescriptor nameDescriptor = (AttributeDescriptor) GMLSchema.ABSTRACTGMLTYPE_TYPE
+                .getDescriptor(Types.typeName(GMLNS, "name"));
+
         while (simpleFeatures.hasNext()) {
             SimpleFeature next = simpleFeatures.next();
             Collection<Property> properties = new ArrayList<Property>();
@@ -174,6 +177,18 @@
                     (AttributeDescriptor) earthResourceType.getDescriptor(Types.typeName(MO_URI,
                             "form")), null));
 
+            // gml:name[1]
+            ArrayList value = new ArrayList<Property>();
+            value.add(new AttributeImpl("gu." + next.getID(), stringDescriptor, null));
+            ComplexAttributeImpl name1 = new ComplexAttributeImpl(value, nameDescriptor, null);
+            properties.add(name1);
+
+            // gml:name[2]
+            value = new ArrayList<Property>();
+            value.add(new AttributeImpl("er." + next.getID(), stringDescriptor, null));
+            ComplexAttributeImpl name2 = new ComplexAttributeImpl(value, nameDescriptor, null);
+            properties.add(name2);
+
             // mo:classification
             propertyName = "CLASSIFICATION";
             ComplexAttributeImpl classification = new ComplexAttributeImpl(
@@ -185,7 +200,7 @@
             AttributeImpl mineralDepositGroup = new AttributeImpl(next.getProperty(propertyName)
                     .getValue(), (AttributeDescriptor) mineralDepositType
                     .getDescriptor(leafAttribute), null);
-            ArrayList<Property> value = new ArrayList<Property>();
+            value = new ArrayList<Property>();
             value.add(mineralDepositGroup);
 
             // mo:classification/mo:MineralDepositModel
@@ -281,7 +296,7 @@
         final String composition = "composition";
         final String occurrence = "occurence";
         final String commodity = "commodityDescription";
-        List<AttributeMapping> nonFeatureMappings = new ArrayList<AttributeMapping>();
+        List<AttributeMapping> otherMappings = new ArrayList<AttributeMapping>();
         AttributeMapping compositionMapping = null;
         AttributeMapping occurrenceMapping = null;
         for (AttributeMapping attMapping : guSchema.getAttributeMappings()) {
@@ -292,13 +307,13 @@
                 occurrenceMapping = attMapping;
             } else {
                 // normal inline attribute mappings (not chained)
-                nonFeatureMappings.add(attMapping);
+                otherMappings.add(attMapping);
             }
         }
         // make sure all the mappings are there
         assertNotNull(occurrenceMapping);
         assertNotNull(compositionMapping);
-        assertEquals(nonFeatureMappings.size(), guSchema.getAttributeMappings().size() - 2);
+        assertEquals(otherMappings.size(), guSchema.getAttributeMappings().size() - 2);
 
         int guCount = 0;
         ArrayList<Feature> guFeatures = new ArrayList<Feature>();
@@ -370,10 +385,22 @@
             // check the feature has the correct id
             assertEquals(mfIds.containsAll(nestedMfIds), true);
 
+            // check multi-valued properties are all mapped
+            // there should be 2 gml:name attributes, although only mapped once
+            // <AttributeMapping>
+            // <!-- All instances of gml:name should be mapped, how many is not known -->
+            // <targetAttribute>gml:name</targetAttribute>
+            // <sourceExpression>
+            // <inputAttribute>gml:name</inputAttribute>
+            // </sourceExpression>
+            // <isMultiple>true</isMultiple>
+            // </AttributeMapping>
+            assertEquals(next.getProperties("name").size(), 2);
+
             /**
              * Check normal in-line attribute mappings
              */
-            for (AttributeMapping attMapping : nonFeatureMappings) {
+            for (AttributeMapping attMapping : otherMappings) {
                 Expression sourceExpr = attMapping.getSourceExpression();
                 // make sure the mapping has the right values
                 if (!(sourceExpr instanceof AttributeExpressionImpl)) {
@@ -416,7 +443,7 @@
         FeatureSource<FeatureType, Feature> mfSource = mfDataAccess
                 .getFeatureSource(MAPPED_FEATURE);
         FeatureCollection<FeatureType, Feature> mfCollection = mfSource.getFeatures();
-        
+
         Iterator<Feature> mfIterator = mfCollection.iterator();
         while (mfIterator.hasNext()) {
             Feature mf = mfIterator.next();
@@ -496,7 +523,7 @@
     }
 
     /**
-     * Non app-schema data access factory producing min-occ XML output.
+     * Non app-schema data access factory producing min-occ XML output.
      */
     public static class MinOccDataAccessFactory extends InputDataAccessFactory {
         public DataAccess<? extends FeatureType, ? extends Feature> createDataStore(

Modified: trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/DataAccessIntegrationTest.java
===================================================================
--- trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/DataAccessIntegrationTest.java 2009-07-07 06:16:23 UTC (rev 33504)
+++ trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/DataAccessIntegrationTest.java 2009-07-07 07:42:11 UTC (rev 33505)
@@ -100,7 +100,7 @@
     static final Name COMPOSITION_PART_TYPE = Types.typeName(GSMLNS, "CompositionPartType");
 
     static final Name COMPOSITION_PART = Types.typeName(GSMLNS, "CompositionPart");
-    
+
     static final Name CONTROLLED_CONCEPT = Types.typeName(GSMLNS, "ControlledConcept");
 
     static final String schemaBase = "/test-data/";
@@ -116,16 +116,6 @@
     protected DataAccess<FeatureType, Feature> mfDataAccess;
 
     /**
-     * Composition Part data access in GSML form
-     */
-    protected DataAccess<FeatureType, Feature> cpDataAccess;
-
-    /**
-     * CGI Value data access in GSML Form
-     */
-    protected DataAccess<FeatureType, Feature> cgiDataAccess;
-
-    /**
      * GSML:geologicUnit feature source coming from the mapped data access
      */
     protected FeatureSource<FeatureType, Feature> guFeatureSource;
@@ -151,11 +141,6 @@
     static FilterFactory ff;
 
     /**
-     * The input data access in MO form
-     */
-    protected DataAccess<FeatureType, Feature> inputDataAccess;
-
-    /**
      * Create the input data access containing complex features of MO form.
      */
     protected void setUp() throws Exception {
@@ -351,7 +336,7 @@
     public void loadGeologicUnitDataAccess() throws IOException {
         Map<String, Serializable> moParams = new HashMap<String, Serializable>();
         moParams.put("dbtype", "input-data-access");
-        inputDataAccess = DataAccessFinder.getDataStore(moParams);
+        DataAccess<FeatureType, Feature> inputDataAccess = DataAccessFinder.getDataStore(moParams);
         guFeatureSource = inputDataAccess.getFeatureSource(GEOLOGIC_UNIT);
     }
 
@@ -400,7 +385,7 @@
 
         dsParams.put("dbtype", "app-schema");
         dsParams.put("url", url.toExternalForm());
-        cpDataAccess = DataAccessFinder.getDataStore(dsParams);
+        DataAccess<FeatureType, Feature> cpDataAccess = DataAccessFinder.getDataStore(dsParams);
         assertNotNull(cpDataAccess);
         FeatureSource<FeatureType, Feature> cpSource = cpDataAccess
                 .getFeatureSource(COMPOSITION_PART);
@@ -414,13 +399,14 @@
         assertNotNull(url);
 
         dsParams.put("url", url.toExternalForm());
-        cgiDataAccess = DataAccessFinder.getDataStore(dsParams);
+        DataAccess<FeatureType, Feature> cgiDataAccess = DataAccessFinder.getDataStore(dsParams);
         assertNotNull(cgiDataAccess);
 
         /**
          * Load Controlled Concept data access
          */
-        DataAccess<FeatureType, Feature> ccDataAccess = DataAccessRegistry.getDataAccess(CONTROLLED_CONCEPT);
+        DataAccess<FeatureType, Feature> ccDataAccess = DataAccessRegistry
+                .getDataAccess(CONTROLLED_CONCEPT);
         assertNotNull(ccDataAccess);
 
         cpFeatures = new ArrayList<Feature>();
@@ -436,10 +422,7 @@
      * Dispose all the data accesses so that there is no mapping conflicts for other tests
      */
     protected void tearDown() {
-        inputDataAccess.dispose();
-        mfDataAccess.dispose();
-        cpDataAccess.dispose();
-        cgiDataAccess.dispose();
+        DataAccessRegistry.unregisterAll();
     }
 
     /**

Modified: trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/FeatureChainingTest.java
===================================================================
--- trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/FeatureChainingTest.java 2009-07-07 06:16:23 UTC (rev 33504)
+++ trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/FeatureChainingTest.java 2009-07-07 07:42:11 UTC (rev 33505)
@@ -143,31 +143,11 @@
     private FeatureCollection<FeatureType, Feature> cpFeatures;
 
     /**
-     * Geological unit data access
+     * Generated controlled concept fake "features"
      */
-    private DataAccess<FeatureType, Feature> guDataAccess;
+    private FeatureCollection<FeatureType, Feature> ccFeatures;
 
     /**
-     * Compositional part data access
-     */
-    private DataAccess<FeatureType, Feature> cpDataAccess;
-
-    /**
-     * Mapped feature data access
-     */
-    private DataAccess<FeatureType, Feature> mfDataAccess;
-
-    /**
-     * CGI Term Value data access
-     */
-    private DataAccess<FeatureType, Feature> cgiDataAccess;
-
-    /**
-     * Controlled Concept data access
-     */
-    private DataAccess<?, Feature> ccDataAccess;
-
-    /**
      * Test that chaining works
      *
      * @throws Exception
@@ -280,7 +260,7 @@
         guFeatures.close(guIterator);
         cpFeatures.close(cpIterator);
 
-        disposeDataAccesses();
+        DataAccessRegistry.unregisterAll();
     }
 
     /**
@@ -294,14 +274,6 @@
 
         this.loadDataAccesses();
 
-        FeatureType ccType = ccDataAccess.getSchema(CONTROLLED_CONCEPT);
-        assertNotNull(ccType);
-
-        FeatureSource<FeatureType, Feature> ccSource = (FeatureSource<FeatureType, Feature>) ccDataAccess
-                .getFeatureSource(CONTROLLED_CONCEPT);
-        FeatureCollection<FeatureType, Feature> ccFeatures = (FeatureCollection<FeatureType, Feature>) ccSource
-                .getFeatures();
-
         final String LITHOLOGY = "lithology";
         final int EXPECTED_RESULT_COUNT = 2;
         // get controlled concept features on their own
@@ -345,8 +317,7 @@
                 assertEquals(lithologies.isEmpty(), true);
             }
         }
-
-        disposeDataAccesses();
+        DataAccessRegistry.unregisterAll();
     }
 
     /**
@@ -413,8 +384,7 @@
             assertEquals(realValues.size(), values.length);
             assertEquals(realValues.containsAll(Arrays.asList(values)), true);
         }
-        this.disposeDataAccesses();
-
+        DataAccessRegistry.unregisterAll();
         guFeatures.close(guIterator);
     }
 
@@ -515,7 +485,7 @@
         filteredResults = guSource.getFeatures(filter);
         assertEquals(getCount(filteredResults), 3);
 
-        this.disposeDataAccesses();
+        DataAccessRegistry.unregisterAll();
     }
 
     /**
@@ -668,7 +638,7 @@
 
         // clean ups
         guFeatures.close(guIterator);
-        this.disposeDataAccesses();
+        DataAccessRegistry.unregisterAll();
     }
 
     /**
@@ -687,7 +657,7 @@
 
         dsParams.put("dbtype", "app-schema");
         dsParams.put("url", url.toExternalForm());
-        mfDataAccess = DataAccessFinder.getDataStore(dsParams);
+        DataAccess<FeatureType, Feature> mfDataAccess = DataAccessFinder.getDataStore(dsParams);
         assertNotNull(mfDataAccess);
 
         FeatureType mappedFeatureType = mfDataAccess.getSchema(MAPPED_FEATURE);
@@ -703,7 +673,7 @@
         assertNotNull(url);
 
         dsParams.put("url", url.toExternalForm());
-        guDataAccess = DataAccessFinder.getDataStore(dsParams);
+        DataAccess<FeatureType, Feature> guDataAccess = DataAccessFinder.getDataStore(dsParams);
         assertNotNull(guDataAccess);
 
         FeatureType guType = guDataAccess.getSchema(GEOLOGIC_UNIT);
@@ -718,19 +688,12 @@
          * unit data access is created
          */
         // Composition Part
-        cpDataAccess = DataAccessRegistry.getDataAccess(COMPOSITION_PART);
-        FeatureSource<FeatureType, Feature> cpSource = cpDataAccess
-                .getFeatureSource(COMPOSITION_PART);
-        cpFeatures = (FeatureCollection<FeatureType, Feature>) cpSource.getFeatures();
+        cpFeatures = DataAccessRegistry.getFeatureSource(COMPOSITION_PART).getFeatures();
         // CGI TermValue
-        cgiDataAccess = DataAccessRegistry.getDataAccess(CGI_TERM_VALUE);
-        FeatureSource<FeatureType, Feature> cgiSource = cgiDataAccess
-                .getFeatureSource(CGI_TERM_VALUE);
-        FeatureCollection<FeatureType, Feature> cgiFeatures = (FeatureCollection<FeatureType, Feature>) cgiSource
-                .getFeatures();
+        FeatureCollection<FeatureType, Feature> cgiFeatures = DataAccessRegistry.getFeatureSource(
+                CGI_TERM_VALUE).getFeatures();
         // ControlledConcept
-        ccDataAccess = DataAccessRegistry.getDataAccess(CONTROLLED_CONCEPT);
-        assertNotNull(ccDataAccess);
+        ccFeatures = DataAccessRegistry.getFeatureSource(CONTROLLED_CONCEPT).getFeatures();
 
         int EXPECTED_RESULT_COUNT = 4;
 
@@ -749,22 +712,6 @@
         assertEquals(EXPECTED_RESULT_COUNT, resultCount);
     }
 
-    /**
-     * Dispose all data accesses
-     */
-    private void disposeDataAccesses() {
-        if (mfDataAccess == null || guDataAccess == null || cpDataAccess == null
-                || cgiDataAccess == null || ccDataAccess == null) {
-            throw new UnsupportedOperationException(
-                    "This is to be called after data accesses are created!");
-        }
-        mfDataAccess.dispose();
-        guDataAccess.dispose();
-        cgiDataAccess.dispose();
-        cpDataAccess.dispose();
-        ccDataAccess.dispose();
-    }
-
     protected static int getCount(FeatureCollection<FeatureType, Feature> features) {
         MappingFeatureIterator iterator = (MappingFeatureIterator) features.iterator();
         int count = 0;

Modified: trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/GeologicUnitTest.java
===================================================================
--- trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/GeologicUnitTest.java 2009-07-07 06:16:23 UTC (rev 33504)
+++ trunk/modules/unsupported/app-schema/app-schema/src/test/java/org/geotools/data/complex/GeologicUnitTest.java 2009-07-07 07:42:11 UTC (rev 33505)
@@ -25,8 +25,6 @@
 import java.util.Set;
 import junit.framework.TestCase;
 
-import org.apache.xml.resolver.Catalog;
-import org.apache.xml.resolver.tools.ResolvingXMLReader;
 import org.geotools.data.DataAccess;
 import org.geotools.data.DataAccessFinder;
 import org.geotools.data.FeatureSource;
@@ -74,6 +72,7 @@
      */
     protected void tearDown() throws Exception {
         super.tearDown();
+        DataAccessRegistry.unregisterAll();
     }
 
     /**
@@ -216,12 +215,6 @@
         resultCount = getCount(cgiFeatures);
 
         assertEquals(EXPECTED_RESULT_COUNT, resultCount);
-
-        // Dispose data stores
-        guDataStore.dispose();
-        cpDataStore.dispose();
-        cgiDataAccess.dispose();
-        ccDataAccess.dispose();
     }
 
     /**

Modified: trunk/modules/unsupported/app-schema/app-schema/src/test/resources/test-data/EarthResourceToGeologicUnit.xml
===================================================================
--- trunk/modules/unsupported/app-schema/app-schema/src/test/resources/test-data/EarthResourceToGeologicUnit.xml 2009-07-07 06:16:23 UTC (rev 33504)
+++ trunk/modules/unsupported/app-schema/app-schema/src/test/resources/test-data/EarthResourceToGeologicUnit.xml 2009-07-07 07:42:11 UTC (rev 33505)
@@ -55,10 +55,12 @@
  <targetAttribute>gsml:GeologicUnit</targetAttribute>
  </AttributeMapping>
  <AttributeMapping>
+    <!-- All instances of gml:name should be mapped, how many is not known -->
  <targetAttribute>gml:name</targetAttribute>
  <sourceExpression>
- <OCQL>strConcat('er.', getID())</OCQL>
+   <inputAttribute>gml:name</inputAttribute>
  </sourceExpression>
+ <isMultiple>true</isMultiple>
  </AttributeMapping>
  <AttributeMapping>
  <!--


------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize
details at: http://p.sf.net/sfu/blackberry
_______________________________________________
GeoTools-commits mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-commits