Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Updates for GeoTools FeatureCollection api changes (GEOS-5398) #61

Closed
wants to merge 1 commit into from

2 participants

@jdeolive
Owner

For more information the issue is here: http://jira.codehaus.org/browse/GEOS-5398

This pull request tracks the FeatureCollection cleanup proposal, removing deprecated methods from FeatureCollection.

@jodygarnett

There is a DataUtilities.close( iterator ) that aaime requested, it does allow you to avoid null checks

@jodygarnett

I have been doing the try / finally thing to ensure iterator is closed

@jodygarnett

This looks fine, if the security feature collection wrapper does not provide the add / addAll methods then the delegate is safe from unauthorised alteration

@jodygarnett
Owner

Looks like the comments showed up above - summary:

@jodygarnett
Owner

Looks like the comments showed up - summary:

  1. The changes were smoothly applied, did not see any major workarounds like in GeoTools or uDig 2 We could make use of some of those DataUtilities methods.
  2. I tend to do try / finally around each FeatureIterator
  3. The security feature collections were fine, I wanted to make sure there was no way to accidentally get to the delegate and "add" anything. And yes they are all wrapped up
@jodygarnett
Owner

Rebasing this branch locally and trying it out now that the FC geotools pull request is live.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 3, 2012
This page is out of date. Refresh to see the latest.
Showing with 166 additions and 461 deletions.
  1. +1 −1  src/extension/excel/src/main/java/org/geoserver/wfs/response/ExcelOutputFormat.java
  2. +4 −3 src/extension/imagemap/src/main/java/org/vfny/geoserver/wms/responses/map/htmlimagemap/HTMLImageMapWriter.java
  3. +7 −32 src/main/src/main/java/org/geoserver/feature/CompositeFeatureCollection.java
  4. +4 −21 src/main/src/main/java/org/geoserver/feature/ReprojectingFeatureCollection.java
  5. +8 −20 src/main/src/main/java/org/geoserver/feature/RetypingFeatureCollection.java
  6. +0 −5 src/main/src/main/java/org/geoserver/security/decorators/CheckAttributesFeatureCollection.java
  7. +0 −3  src/main/src/main/java/org/geoserver/security/decorators/DefaultSecureDataFactory.java
  8. +0 −137 src/main/src/main/java/org/geoserver/security/decorators/SecuredFeatureCollection.java
  9. +2 −0  src/main/src/main/java/org/geoserver/security/decorators/SecuredIterator.java
  10. +6 −1 src/main/src/main/java/org/geoserver/security/decorators/SecuredSimpleFeatureIterator.java
  11. +61 −83 src/main/src/test/java/org/geoserver/security/decorators/SecuredFeatureCollectionTest.java
  12. +2 −2 src/main/src/test/java/org/geoserver/template/FeatureWrapperTest.java
  13. +3 −2 src/web/demo/src/main/java/org/geoserver/web/crs/CRSAreaOfValidityMapBuilder.java
  14. +2 −2 src/wfs/src/main/java/org/geoserver/wfs/InsertElementHandler.java
  15. +4 −11 src/wfs/src/main/java/org/geoserver/wfs/LockFeature.java
  16. +3 −10 src/wfs/src/main/java/org/geoserver/wfs/UpdateElementHandler.java
  17. +1 −5 src/wfs/src/main/java/org/geoserver/wfs/response/CSVOutputFormat.java
  18. +1 −1  src/wfs/src/main/java/org/geoserver/wfs/response/GeoJSONOutputFormat.java
  19. +7 −23 src/wfs/src/main/java/org/geoserver/wfs/response/RemappingFeatureCollection.java
  20. +3 −2 src/wfs/src/test/java/org/geoserver/wfs/response/ShapeZipTest.java
  21. +5 −1 src/wfs/src/test/java/org/geoserver/wfs/v1_1/TransactionTest.java
  22. +32 −26 src/wms/src/main/java/org/geoserver/kml/KMLRasterTransformer.java
  23. +1 −1  src/wms/src/main/java/org/geoserver/kml/KMLVectorTransformer.java
  24. +0 −58 src/wms/src/main/java/org/geoserver/wms/featureinfo/FeatureCollectionDecorator.java
  25. +1 −1  src/wms/src/main/java/org/geoserver/wms/georss/AtomGeoRSSTransformer.java
  26. +1 −1  src/wms/src/main/java/org/geoserver/wms/georss/RSSGeoRSSTransformer.java
  27. +6 −8 src/wms/src/test/java/org/geoserver/wms/featureinfo/FeatureTemplateTest.java
  28. +1 −1  src/wms/src/test/java/org/geoserver/wms/featureinfo/FeatureTimeTemplateTest.java
View
2  src/extension/excel/src/main/java/org/geoserver/wfs/response/ExcelOutputFormat.java
@@ -167,7 +167,7 @@ protected void write(FeatureCollectionResponse featureCollection, OutputStream o
}
}
} finally {
- fc.close(i);
+ i.close();
}
}
View
7 ...p/src/main/java/org/vfny/geoserver/wms/responses/map/htmlimagemap/HTMLImageMapWriter.java
@@ -195,9 +195,10 @@ public void writeFeatures(SimpleFeatureCollection fColl, FeatureTypeStyle[] ftsL
} catch (NoSuchElementException ex) {
throw new DataSourceException(ex.getMessage(), ex);
} finally {
- if(iter!=null)
- //make sure we always close
- fColl.close(iter);
+ if(iter!=null) {
+ //make sure we always close
+ iter.close();
+ }
}
}
View
39 src/main/src/main/java/org/geoserver/feature/CompositeFeatureCollection.java
@@ -13,6 +13,7 @@
import org.geotools.data.DataUtilities;
import org.geotools.data.store.DataFeatureCollection;
import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.identity.FeatureId;
@@ -64,7 +65,7 @@ public int getCount() throws IOException {
class CompositeIterator implements Iterator {
int index;
- Iterator iterator;
+ FeatureIterator iterator;
public CompositeIterator() {
index = 0;
@@ -83,11 +84,11 @@ public boolean hasNext() {
while (index < collections.size()) {
//close current before we move to next
if (iterator != null) {
- ((FeatureCollection) collections.get(index - 1)).close(iterator);
+ iterator.close();
}
//grap next
- iterator = ((FeatureCollection) collections.get(index++)).iterator();
+ iterator = ((FeatureCollection) collections.get(index++)).features();
if (iterator.hasNext()) {
return true;
@@ -97,7 +98,7 @@ public boolean hasNext() {
//no more
if (iterator != null) {
//close the last iterator
- ((FeatureCollection) collections.get(collections.size() - 1)).close(iterator);
+ iterator.close();
}
return false;
@@ -108,43 +109,17 @@ public Object next() {
}
}
- public boolean addAll(Collection arg0) {
- throw new RuntimeException("Can't add to a composite featurecollection; you need to add to one of the constituent collections direclty.");
- }
-
- public boolean removeAll(Collection arg0) {
- Iterator it = collections.iterator();
- boolean result = false;
- while (it.hasNext()){
- FeatureCollection col = (FeatureCollection)it.next();
- result |= col.removeAll(arg0);
- }
- return result;
- }
-
- public boolean retainAll(Collection arg0) {
- boolean result = false;
-
- Iterator it = collections.iterator();
- while (it.hasNext()){
- FeatureCollection col = (FeatureCollection)it.next();
- result |= col.removeAll(arg0);
- }
-
- return result;
- }
-
public Object[] toArray(Object[] arg0) {
List list = new ArrayList();
Iterator it = collections.iterator();
while(it.hasNext()){
FeatureCollection col = (FeatureCollection)it.next();
- Iterator it2 = col.iterator();
+ FeatureIterator it2 = col.features();
while (it2.hasNext()){
list.add(it.next());
}
- col.close(it2);
+ it2.close();
}
return list.toArray(arg0);
View
25 src/main/src/main/java/org/geoserver/feature/ReprojectingFeatureCollection.java
@@ -120,7 +120,7 @@ public void accepts(FeatureVisitor visitor, ProgressListener progress) {
visitor.visit(it.next());
}
} finally {
- close(it);
+ it.close();
}
}
@@ -132,24 +132,6 @@ public SimpleFeatureIterator features() {
return new ReprojectingFeatureIterator(delegate.features());
}
- public Iterator iterator() {
- return new ReprojectingIterator(delegate.iterator());
- }
-
- public void close(SimpleFeatureIterator iterator) {
- if (iterator instanceof ReprojectingFeatureIterator) {
- delegate.close(((ReprojectingFeatureIterator) iterator).getDelegate());
- }
-
- iterator.close();
- }
-
- public void close(Iterator iterator) {
- if (iterator instanceof ReprojectingIterator) {
- delegate.close(((ReprojectingIterator) iterator).getDelegate());
- }
- }
-
public SimpleFeatureType getFeatureType() {
return schema;
}
@@ -218,7 +200,7 @@ public SimpleFeatureCollection subCollection(Filter filter) {
public ReferencedEnvelope getBounds() {
ReferencedEnvelope bounds = null;
- Iterator i = iterator();
+ SimpleFeatureIterator i = features();
try {
if (!i.hasNext()) {
@@ -237,7 +219,7 @@ public ReferencedEnvelope getBounds() {
return bounds;
} finally {
- close(i);
+ i.close();
}
}
@@ -339,6 +321,7 @@ public SimpleFeature next() throws NoSuchElementException {
}
public void close() {
+ if (delegate != null) delegate.close();
delegate = null;
}
}
View
28 src/main/src/main/java/org/geoserver/feature/RetypingFeatureCollection.java
@@ -12,6 +12,7 @@
import org.geotools.data.FeatureWriter;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.feature.FeatureIterator;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.collection.DelegateSimpleFeatureIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
@@ -40,22 +41,8 @@ public SimpleFeatureType getSchema() {
return target;
}
- public Iterator<SimpleFeature> iterator() {
- return new RetypingIterator(delegate.iterator(), target);
- }
-
- public void close(Iterator<SimpleFeature> iterator) {
- RetypingIterator retyping = (RetypingIterator) iterator;
- delegate.close(retyping.delegate);
- }
-
public SimpleFeatureIterator features() {
- return new DelegateSimpleFeatureIterator(this, iterator());
- }
-
- public void close(SimpleFeatureIterator iterator) {
- DelegateSimpleFeatureIterator delegate = (DelegateSimpleFeatureIterator) iterator;
- delegate.close();
+ return new RetypingIterator(delegate.features(), target);
}
static SimpleFeature retype(SimpleFeature source, SimpleFeatureBuilder builder)
@@ -102,11 +89,11 @@ public static FeatureId reTypeId(FeatureId sourceId, SimpleFeatureType original,
return sourceId;
}
- public static class RetypingIterator implements Iterator<SimpleFeature> {
+ public static class RetypingIterator implements SimpleFeatureIterator {
SimpleFeatureBuilder builder;
- Iterator<SimpleFeature> delegate;
+ SimpleFeatureIterator delegate;
- public RetypingIterator(Iterator<SimpleFeature> delegate, SimpleFeatureType target) {
+ public RetypingIterator(SimpleFeatureIterator delegate, SimpleFeatureType target) {
this.delegate = delegate;
this.builder = new SimpleFeatureBuilder(target);
}
@@ -123,8 +110,9 @@ public SimpleFeature next() {
}
}
- public void remove() {
- delegate.remove();
+ @Override
+ public void close() {
+ delegate.close();
}
}
View
5 ...ain/src/main/java/org/geoserver/security/decorators/CheckAttributesFeatureCollection.java
@@ -43,11 +43,6 @@ public SimpleFeatureIterator features() {
return new CheckAttributesFeatureIterator(delegate.features(), writableAttributes);
}
- @Override
- public Iterator iterator() {
- return new FeatureIteratorIterator<SimpleFeature>(features());
- }
-
public class CheckAttributesFeatureIterator implements SimpleFeatureIterator {
SimpleFeatureIterator delegate;
View
3  src/main/src/main/java/org/geoserver/security/decorators/DefaultSecureDataFactory.java
@@ -49,7 +49,6 @@ public boolean canSecure(Class clazz) {
|| FeatureStore.class.isAssignableFrom(clazz)
|| FeatureLocking.class.isAssignableFrom(clazz)
|| FeatureCollection.class.isAssignableFrom(clazz)
- || Iterator.class.isAssignableFrom(clazz)
|| FeatureIterator.class.isAssignableFrom(clazz)
|| AbstractGridCoverage2DReader.class.isAssignableFrom(clazz)
|| AbstractGridFormat.class.isAssignableFrom(clazz)
@@ -109,8 +108,6 @@ public Object secure(Object object, WrapperPolicy policy) {
return new SecuredSimpleFeatureCollection((SimpleFeatureCollection) object, policy);
} else if (FeatureCollection.class.isAssignableFrom(clazz)) {
return new SecuredFeatureCollection((FeatureCollection) object, policy);
- } else if (Iterator.class.isAssignableFrom(clazz)) {
- return new SecuredIterator((Iterator) object, policy);
} else if (SimpleFeatureIterator.class.isAssignableFrom(clazz)) {
return new SecuredSimpleFeatureIterator((SimpleFeatureIterator) object);
} else if (FeatureIterator.class.isAssignableFrom(clazz)) {
View
137 src/main/src/main/java/org/geoserver/security/decorators/SecuredFeatureCollection.java
@@ -48,10 +48,6 @@
this.policy = policy;
}
- public Iterator iterator() {
- return (Iterator) SecuredObjects.secure(delegate.iterator(), policy);
- }
-
@Override
public org.geotools.feature.FeatureIterator<F> features() {
return (FeatureIterator) SecuredObjects.secure(delegate.features(), policy);
@@ -73,137 +69,4 @@ public Iterator iterator() {
else
return (FeatureCollection) SecuredObjects.secure(fc, policy);
}
-
- @Override
- public void close(FeatureIterator<F> close) {
- if(close instanceof Wrapper && ((Wrapper) close).isWrapperFor(FeatureIterator.class))
- delegate.close(((Wrapper) close).unwrap(FeatureIterator.class));
- else
- delegate.close(close);
- }
-
- @Override
- public void close(Iterator<F> close) {
- if(close instanceof Wrapper && ((Wrapper) close).isWrapperFor(Iterator.class))
- delegate.close(((Wrapper) close).unwrap(Iterator.class));
- else
- delegate.close(close);
- }
-
- // ---------------------------------------------------------------------
- // Write related methods
- // ---------------------------------------------------------------------
-
- public boolean add(F o) {
- Query writeQuery = getWriteQuery(policy);
- final Filter filter = writeQuery.getFilter();
- if(filter == Filter.EXCLUDE) {
- throw unsupportedOperation();
- } else {
- if(filter.evaluate(o)) {
- if(writeQuery.getPropertyNames() == Query.ALL_NAMES) {
- return delegate.add(o);
- } else {
- // TODO: shave off attributes we cannot write
- LOGGER.log(Level.SEVERE, "Unfinished implementation, we need to shave off " +
- "the attributes one cannot write!");
- return add(o);
- }
- } else {
- return false;
- }
- }
- }
-
- public boolean addAll(Collection c) {
- Query writeQuery = getWriteQuery(policy);
- final Filter filter = writeQuery.getFilter();
- if(filter == Filter.EXCLUDE) {
- throw unsupportedOperation();
- } else {
- List filtered = filterCollection(c, writeQuery);
-
- return addAll(filtered);
- }
- }
-
- /**
- * Filters out all features that cannot be modified/removed
- * @param collection
- * @param writeQuery
- * @return
- */
- List filterCollection(Collection collection, Query writeQuery) {
- // warn about inability to shave off complex features
- if(writeQuery.getPropertyNames() != Query.ALL_NAMES) {
- LOGGER.log(Level.SEVERE, "Unfinished implementation, we need to shave off " +
- "the attributes one cannot write!");
- }
-
- // filter out anything we cannot write
- final Filter filter = writeQuery.getFilter();
- List filtered = new ArrayList();
- for (Object feature : collection) {
- if(filter.evaluate(feature)) {
- filtered.add(feature);
- }
- }
- return filtered;
- }
-
- public void clear() {
- Query writeQuery = getWriteQuery(policy);
- final Filter filter = writeQuery.getFilter();
- if(filter == Filter.EXCLUDE) {
- throw unsupportedOperation();
- } else {
- delegate.clear();
- }
- }
-
- public boolean remove(Object o) {
- Query writeQuery = getWriteQuery(policy);
- final Filter filter = writeQuery.getFilter();
- if(filter == Filter.EXCLUDE) {
- throw unsupportedOperation();
- } else {
- if(filter.evaluate(o)) {
- return delegate.remove(o);
- } else {
- return false;
- }
- }
- }
-
- public boolean removeAll(Collection c) {
- Query writeQuery = getWriteQuery(policy);
- final Filter filter = writeQuery.getFilter();
- if(filter == Filter.EXCLUDE) {
- throw unsupportedOperation();
- } else {
- List filtered = filterCollection(c, writeQuery);
-
- return removeAll(filtered);
- }
- }
-
- public boolean retainAll(Collection c) {
- // way too inefficient and fancy to implement, besides nothing in GS uses it and
- // even ContentFeatureCollection does not implement it, so just let it go, we'll
- // cross this bridge when necessary
- throw new UnsupportedOperationException("Sorry, not even ContentFeatureCollection implements this one");
- }
-
- /**
- * Notifies the caller the requested operation is not supported, using a plain {@link UnsupportedOperationException}
- * in case we have to conceal the fact the data is actually writable, using an Spring security exception otherwise
- * to force an authentication from the user
- */
- RuntimeException unsupportedOperation() {
- String typeName = getID();
- if(policy.response == Response.CHALLENGE) {
- return SecureCatalogImpl.unauthorizedAccess(typeName);
- } else
- return new UnsupportedOperationException("Feature type " + typeName + " is read only");
- }
}
View
2  src/main/src/main/java/org/geoserver/security/decorators/SecuredIterator.java
@@ -19,6 +19,8 @@
* Applies the write policy to removals
* @author Andrea Aime - GeoSolutions
*
+ * @deprecated This class is not longer used, {@link SecuredFeatureIterator} and
+ * {@ SecuredSimpleFeatureIterator} are used instead.
*/
public class SecuredIterator extends AbstractDecorator<Iterator> implements Iterator,FeatureIterator {
WrapperPolicy policy;
View
7 src/main/src/main/java/org/geoserver/security/decorators/SecuredSimpleFeatureIterator.java
@@ -1,5 +1,6 @@
package org.geoserver.security.decorators;
+import java.util.Iterator;
import java.util.NoSuchElementException;
import org.geotools.data.simple.SimpleFeatureIterator;
@@ -12,7 +13,7 @@
*
* @author Josh Vote, CSIRO Earth Science and Resource Engineering
*/
-public class SecuredSimpleFeatureIterator implements SimpleFeatureIterator {
+public class SecuredSimpleFeatureIterator implements SimpleFeatureIterator, Iterator<SimpleFeature> {
SimpleFeatureIterator wrapped;
@@ -32,4 +33,8 @@ public SimpleFeature next() throws NoSuchElementException {
return wrapped.next();
}
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
}
View
144 src/main/src/test/java/org/geoserver/security/decorators/SecuredFeatureCollectionTest.java
@@ -1,5 +1,6 @@
package org.geoserver.security.decorators;
+import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
@@ -10,102 +11,97 @@
import org.geoserver.security.WrapperPolicy;
import org.geoserver.security.impl.SecureObjectsTest;
+import org.geotools.data.FeatureStore;
+import org.geotools.data.Query;
+import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.feature.NameImpl;
+import org.geotools.filter.text.ecql.ECQL;
import org.junit.Before;
import org.junit.Test;
import org.opengis.feature.Feature;
+import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.Filter;
import org.opengis.filter.sort.SortBy;
public class SecuredFeatureCollectionTest extends SecureObjectsTest {
- private FeatureCollection fc;
+ private FeatureStore store;
- private Feature feature;
-
- private SortBy sort;
+ private SimpleFeature feature;
@Before
public void setUp() throws Exception {
- feature = createNiceMock(Feature.class);
- replay(feature);
- Iterator it = createNiceMock(Iterator.class);
- replay(it);
- sort = createNiceMock(SortBy.class);
- replay(sort);
SimpleFeatureType schema = createNiceMock(SimpleFeatureType.class);
expect(schema.getTypeName()).andReturn("testSchema").anyTimes();
+ expect(schema.getName()).andReturn(new NameImpl("testSchema")).anyTimes();
replay(schema);
- fc = createNiceMock(FeatureCollection.class);
- expect(fc.iterator()).andReturn(it).anyTimes();
+
+ feature = createNiceMock(SimpleFeature.class);
+ expect(feature.getID()).andReturn("testSchema.1").anyTimes();
+ expect(feature.getType()).andReturn(schema).anyTimes();
+ expect(feature.getFeatureType()).andReturn(schema).anyTimes();
+ replay(feature);
+
+ DefaultFeatureCollection fc = new DefaultFeatureCollection();
+ fc.add(feature);
+
+ store = createNiceMock(FeatureStore.class);
+ expect(store.getSchema()).andReturn(schema).anyTimes();
+ expect(store.getFeatures()).andReturn(fc).anyTimes();
+ expect(store.getFeatures((Filter)anyObject())).andReturn(fc).anyTimes();
+ expect(store.getFeatures((Query)anyObject())).andReturn(fc).anyTimes();
+ replay(store);
+ /*expect(fc.features()).andReturn(it).anyTimes();
expect(fc.sort(sort)).andReturn(fc).anyTimes();
expect(fc.subCollection(Filter.INCLUDE)).andReturn(fc).anyTimes();
expect(fc.getSchema()).andReturn(schema).anyTimes();
- replay(fc);
+ replay(fc);*/
}
@Test
public void testHide() throws Exception {
- SecuredFeatureCollection ro = new SecuredFeatureCollection(fc, WrapperPolicy.hide(null));
+ SecuredFeatureStore ro = new SecuredFeatureStore(store, WrapperPolicy.hide(null));
+
+ DefaultFeatureCollection fc = new DefaultFeatureCollection();
+ fc.add(feature);
// check the easy ones, those that are not implemented in a read only
// collection
try {
- ro.add(feature);
- fail("Should have failed with an UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // ok
- }
- try {
- ro.addAll(new ArrayList());
- fail("Should have failed with an UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // ok
- }
- try {
- ro.clear();
- fail("Should have failed with an UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // ok
- }
- try {
- ro.remove(feature);
- fail("Should have failed with an UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // ok
- }
- try {
- ro.removeAll(new ArrayList());
+ ro.addFeatures(fc);
fail("Should have failed with an UnsupportedOperationException");
} catch (UnsupportedOperationException e) {
// ok
}
+
try {
- ro.retainAll(new ArrayList());
+ ro.removeFeatures(Filter.INCLUDE);
fail("Should have failed with an UnsupportedOperationException");
} catch (UnsupportedOperationException e) {
// ok
}
+ }
+ @Test
+ public void testReadOnly() throws Exception {
+ SecuredFeatureStore ro = new SecuredFeatureStore(store, WrapperPolicy.readOnlyHide(null));
+
// let's check the iterator, should allow read but not remove
- Iterator roit = ro.iterator();
+ FeatureCollection rofc = ro.getFeatures();
+ FeatureIterator roit = rofc.features();
roit.hasNext();
roit.next();
- try {
- roit.remove();
- fail("Should have failed with an UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // ok
- }
-
+
// check derived collections are still read only and share the same
// challenge policy
- SecuredFeatureCollection sorted = (SecuredFeatureCollection) ro
- .sort(sort);
+ SecuredFeatureCollection sorted = (SecuredFeatureCollection) rofc
+ .sort(SortBy.NATURAL_ORDER);
assertEquals(ro.policy, sorted.policy);
- SecuredFeatureCollection sub = (SecuredFeatureCollection) ro
+ SecuredFeatureCollection sub = (SecuredFeatureCollection) rofc
.subCollection(Filter.INCLUDE);
assertEquals(ro.policy, sorted.policy);
}
@@ -113,73 +109,55 @@ public void testHide() throws Exception {
@Test
public void testChallenge() throws Exception {
- SecuredFeatureCollection ro = new SecuredFeatureCollection(fc, WrapperPolicy.readOnlyChallenge(null));
+ SecuredFeatureStore ro = new SecuredFeatureStore(store, WrapperPolicy.readOnlyChallenge(null));
+
+ DefaultFeatureCollection fc = new DefaultFeatureCollection();
+ fc.add(feature);
// check the easy ones, those that are not implemented in a read only
// collection
try {
- ro.add(feature);
- fail("Should have failed with a spring security exception");
- } catch (Exception e) {
- if (ReadOnlyDataStoreTest.isSpringSecurityException(e)==false)
- fail("Should have failed with a security exception");
- }
- try {
- ro.addAll(new ArrayList());
+ ro.addFeatures(fc);
fail("Should have failed with a spring security exception");
} catch (Exception e) {
if (ReadOnlyDataStoreTest.isSpringSecurityException(e)==false)
fail("Should have failed with a security exception");
}
+
try {
- ro.clear();
+ ro.removeFeatures(Filter.INCLUDE);
fail("Should have failed with a spring security exception");
} catch (Exception e) {
if (ReadOnlyDataStoreTest.isSpringSecurityException(e)==false)
fail("Should have failed with a security exception");
}
try {
- ro.remove(feature);
+ ro.removeFeatures(ECQL.toFilter("IN ('testSchema.1')"));
fail("Should have failed with a spring security exception");
} catch (Exception e) {
if (ReadOnlyDataStoreTest.isSpringSecurityException(e)==false)
fail("Should have failed with a security exception");
}
try {
- ro.removeAll(new ArrayList());
+ ro.removeFeatures(Filter.EXCLUDE);
fail("Should have failed with a spring security exception");
} catch (Exception e) {
if (ReadOnlyDataStoreTest.isSpringSecurityException(e)==false)
fail("Should have failed with a security exception");
}
- try {
- ro.retainAll(new ArrayList());
- fail("Should have failed with a spring security exception");
- } catch(UnsupportedOperationException e) {
- // ok
- } catch (Exception e) {
- if (ReadOnlyDataStoreTest.isSpringSecurityException(e)==false)
- fail("Should have failed with a security exception");
- }
// let's check the iterator, should allow read but not remove
- Iterator roit = ro.iterator();
+ FeatureCollection rofc = ro.getFeatures();
+ FeatureIterator roit = rofc.features();
roit.hasNext();
roit.next();
- try {
- roit.remove();
- fail("Should have failed with a spring security exception");
- } catch (Exception e) {
- if (ReadOnlyDataStoreTest.isSpringSecurityException(e)==false)
- fail("Should have failed with a security exception");
- }
// check derived collections are still read only and share the same
// challenge policy
- SecuredFeatureCollection sorted = (SecuredFeatureCollection) ro
- .sort(sort);
+ SecuredFeatureCollection sorted = (SecuredFeatureCollection) rofc
+ .sort(SortBy.NATURAL_ORDER);
assertEquals(ro.policy, sorted.policy);
- SecuredFeatureCollection sub = (SecuredFeatureCollection) ro
+ SecuredFeatureCollection sub = (SecuredFeatureCollection) rofc
.subCollection(Filter.INCLUDE);
assertEquals(ro.policy, sorted.policy);
}
View
4 src/main/src/test/java/org/geoserver/template/FeatureWrapperTest.java
@@ -26,7 +26,7 @@
public class FeatureWrapperTest {
- SimpleFeatureCollection features;
+ DefaultFeatureCollection features;
Configuration cfg;
@Before
@@ -37,7 +37,7 @@ public void setUp() throws Exception {
SimpleFeatureType featureType = DataUtilities.createType("testType",
"string:String,int:Integer,double:Double,geom:Point");
- features = new DefaultFeatureCollection(null, null) {};
+ features = new DefaultFeatureCollection() {};
features.add(
SimpleFeatureBuilder.build(featureType, new Object[] {
"one", new Integer(1), new Double(1.1), gf.createPoint(new Coordinate(1, 1))
View
5 src/web/demo/src/main/java/org/geoserver/web/crs/CRSAreaOfValidityMapBuilder.java
@@ -29,6 +29,8 @@
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.GeoTools;
+import org.geotools.feature.DefaultFeatureCollection;
+import org.geotools.feature.DefaultFeatureCollections;
import org.geotools.feature.FeatureCollections;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
@@ -246,8 +248,7 @@ private SimpleFeature createCrsBoundsFeature(Geometry geom, CoordinateReferenceS
}
private Layer createCrsLayer(Geometry geom, CoordinateReferenceSystem crs) {
- SimpleFeatureCollection collection = FeatureCollections
- .newCollection();
+ DefaultFeatureCollection collection = new DefaultFeatureCollection();
collection.add(createCrsBoundsFeature(geom, crs));
Style style = getStyle("crs.sld");
View
4 src/wfs/src/main/java/org/geoserver/wfs/InsertElementHandler.java
@@ -93,8 +93,8 @@ public void execute(TransactionElement element, TransactionRequest request, Map
for (Iterator f = featureList.iterator(); f.hasNext();) {
SimpleFeature feature = (SimpleFeature) f.next();
SimpleFeatureType schema = feature.getFeatureType();
- SimpleFeatureCollection collection;
- collection = (SimpleFeatureCollection) schema2features.get(schema);
+ DefaultFeatureCollection collection =
+ (DefaultFeatureCollection) schema2features.get(schema);
if (collection == null) {
collection = new DefaultFeatureCollection(null, schema);
View
15 src/wfs/src/main/java/org/geoserver/wfs/LockFeature.java
@@ -14,12 +14,6 @@
import javax.xml.namespace.QName;
-import net.opengis.wfs.AllSomeType;
-import net.opengis.wfs.LockFeatureResponseType;
-import net.opengis.wfs.LockFeatureType;
-import net.opengis.wfs.LockType;
-import net.opengis.wfs.WfsFactory;
-
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.FeatureTypeInfo;
@@ -28,7 +22,6 @@
import org.geoserver.wfs.request.LockFeatureResponse;
import org.geotools.data.DataAccess;
import org.geotools.data.DataStore;
-import org.geotools.data.Query;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.FeatureLock;
import org.geotools.data.FeatureLockFactory;
@@ -37,8 +30,8 @@
import org.geotools.data.LockingManager;
import org.geotools.data.Query;
import org.geotools.data.Transaction;
-import org.geotools.data.simple.SimpleFeatureLocking;
import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
import org.opengis.feature.Feature;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.type.FeatureType;
@@ -175,11 +168,11 @@ public LockFeatureResponse lockFeature(LockFeatureRequest request)
throw new WFSException(request, e);
}
- Iterator reader = null;
+ FeatureIterator reader = null;
int numberLocked = -1;
try {
- for (reader = features.iterator(); reader.hasNext();) {
+ for (reader = features.features(); reader.hasNext();) {
SimpleFeature feature = (SimpleFeature) reader.next();
FeatureId fid = fid(feature.getID());
@@ -229,7 +222,7 @@ public LockFeatureResponse lockFeature(LockFeatureRequest request)
throw new WFSException(request, ioe);
} finally {
if (reader != null) {
- features.close(reader);
+ reader.close();
}
}
View
13 src/wfs/src/main/java/org/geoserver/wfs/UpdateElementHandler.java
@@ -6,7 +6,6 @@
import java.io.IOException;
import java.math.BigInteger;
-import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -17,13 +16,6 @@
import javax.xml.namespace.QName;
-import net.opengis.wfs.AllSomeType;
-import net.opengis.wfs.PropertyType;
-import net.opengis.wfs.TransactionResponseType;
-import net.opengis.wfs.TransactionType;
-import net.opengis.wfs.UpdateElementType;
-
-import org.eclipse.emf.ecore.EObject;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.config.GeoServer;
import org.geoserver.wfs.request.Property;
@@ -40,6 +32,7 @@
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.GeoTools;
+import org.geotools.feature.FeatureIterator;
import org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
@@ -237,7 +230,7 @@ public void execute(TransactionElement element, TransactionRequest request,
listener.dataStoreChange( event );
- Iterator preprocess = features.iterator();
+ FeatureIterator preprocess = features.features();
try {
while (preprocess.hasNext()) {
@@ -247,7 +240,7 @@ public void execute(TransactionElement element, TransactionRequest request,
} catch (NoSuchElementException e) {
throw new WFSException(request, "Could not aquire FeatureIDs", e);
} finally {
- features.close(preprocess);
+ preprocess.close();
}
try {
View
6 src/wfs/src/main/java/org/geoserver/wfs/response/CSVOutputFormat.java
@@ -12,14 +12,10 @@
import java.util.Date;
import java.util.Locale;
-import javax.xml.namespace.QName;
-
import org.geoserver.config.GeoServer;
-import org.geoserver.ows.util.OwsUtils;
import org.geoserver.platform.Operation;
import org.geoserver.platform.ServiceException;
import org.geoserver.wfs.WFSGetFeatureOutputFormat;
-import org.geoserver.wfs.WFSInfo;
import org.geoserver.wfs.request.FeatureCollectionResponse;
import org.geoserver.wfs.request.GetFeatureRequest;
import org.geotools.data.simple.SimpleFeatureCollection;
@@ -145,7 +141,7 @@ else if(att instanceof java.sql.Time)
w.write( "\r\n" );
}
} finally {
- fc.close( i );
+ i.close();
}
w.flush();
View
2  src/wfs/src/main/java/org/geoserver/wfs/response/GeoJSONOutputFormat.java
@@ -200,7 +200,7 @@ protected void write(FeatureCollectionResponse featureCollection,
}
} // catch an exception here?
finally {
- collection.close(iterator);
+ iterator.close();
}
}
View
30 src/wfs/src/main/java/org/geoserver/wfs/response/RemappingFeatureCollection.java
@@ -5,13 +5,11 @@
package org.geoserver.wfs.response;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.collection.DecoratingSimpleFeatureCollection;
-import org.geotools.feature.collection.DelegateSimpleFeatureIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.opengis.feature.simple.SimpleFeature;
@@ -69,25 +67,10 @@ private SimpleFeatureType remapSchema(SimpleFeatureType schema) {
return builder.buildFeatureType();
}
- public Iterator<SimpleFeature> iterator() {
- return new RemappingIterator(delegate.iterator(), attributesMapping,getSchema());
- }
-
- public void close(Iterator<SimpleFeature> iterator) {
- RemappingIterator remapping = (RemappingIterator) iterator;
- delegate.close(remapping.delegate);
- }
-
public SimpleFeatureIterator features() {
- return new DelegateSimpleFeatureIterator(this, iterator());
+ return new RemappingIterator(delegate.features(), attributesMapping, getSchema());
}
- public void close(SimpleFeatureIterator iterator) {
- DelegateSimpleFeatureIterator delegate = (DelegateSimpleFeatureIterator) iterator;
- delegate.close();
- }
-
-
/**
* Remaps a SimpleFeature, using the given mappings (oldname -> mappedname).
* The builder uses the mapped schema.
@@ -114,12 +97,12 @@ static SimpleFeature remap(SimpleFeature source, Map<String,String> attributeMap
}
- public static class RemappingIterator implements Iterator<SimpleFeature> {
+ public static class RemappingIterator implements SimpleFeatureIterator {
Map<String,String> attributesMapping;
- Iterator<SimpleFeature> delegate;
+ SimpleFeatureIterator delegate;
SimpleFeatureBuilder builder;
- public RemappingIterator(Iterator<SimpleFeature> delegate, Map attributesMapping,SimpleFeatureType schema) {
+ public RemappingIterator(SimpleFeatureIterator delegate, Map attributesMapping,SimpleFeatureType schema) {
this.delegate = delegate;
this.attributesMapping = RemappingFeatureCollection.invertMappings(attributesMapping);
this.builder = new SimpleFeatureBuilder(schema);
@@ -133,8 +116,9 @@ public SimpleFeature next() {
return RemappingFeatureCollection.remap(delegate.next(), attributesMapping,builder);
}
- public void remove() {
- delegate.remove();
+ @Override
+ public void close() {
+ delegate.close();
}
}
View
5 src/wfs/src/test/java/org/geoserver/wfs/response/ShapeZipTest.java
@@ -41,6 +41,7 @@
import org.geotools.data.FeatureSource;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.FeatureCollection;
import org.junit.Before;
@@ -513,7 +514,7 @@ private SimpleFeatureType checkFieldsAreNotEmpty(InputStream in) throws IOExcept
SimpleFeatureCollection fc = fs.getFeatures();
SimpleFeatureType schema = fc.getSchema();
- Iterator<SimpleFeature> iter = fc.iterator();
+ SimpleFeatureIterator iter = fc.features();
try {
// check that every field has a not null or "empty" value
while (iter.hasNext()) {
@@ -529,7 +530,7 @@ private SimpleFeatureType checkFieldsAreNotEmpty(InputStream in) throws IOExcept
}
} finally {
- fc.close(iter);
+ iter.close();
tempFolder.delete();
}
View
6 src/wfs/src/test/java/org/geoserver/wfs/v1_1/TransactionTest.java
@@ -20,6 +20,7 @@
import org.geotools.data.DataStore;
import org.geotools.data.FeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
+import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.junit.Before;
@@ -710,7 +711,10 @@ public void testInsertUseExistingId() throws Exception {
SimpleFeatureBuilder b = new SimpleFeatureBuilder(fs.getSchema());
b.add("one");
b.add(new WKTReader().read("POINT(1 1)"));
- fs.getFeatures().add(b.buildFeature(null));
+
+ DefaultFeatureCollection fc = new DefaultFeatureCollection();
+ fc.add(b.buildFeature(null));
+ fs.addFeatures(fc);
FeatureTypeInfo ft = cb.buildFeatureType(fs);
cat.add(ft);
View
58 src/wms/src/main/java/org/geoserver/kml/KMLRasterTransformer.java
@@ -13,6 +13,7 @@
import org.geoserver.wms.WMSMapContent;
import org.geoserver.wms.WMSRequests;
import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.Layer;
@@ -185,36 +186,41 @@ public void encode(Object o) throws IllegalArgumentException {
FeatureTypeStyle[] fts = KMLUtils.filterFeatureTypeStyles(layer.getStyle(),
featureType);
- Iterator<SimpleFeature> iter = features.iterator();
- while (iter.hasNext()) {
- SimpleFeature ftr = iter.next();
- geom = (Geometry) ftr.getDefaultGeometry();
-
- List<Symbolizer> symbolizers = filterSymbolizers(ftr, fts);
- if (symbolizers.size() != 0)
- encodeStyle(ftr, symbolizers);
-
- // if this is a multipolygon, get the largest polygon
- // that intersects the AOI
- if (geom instanceof MultiPolygon) {
- double maxSize = -1;
- int numGeoms = geom.getNumGeometries();
- for (int i = 0; i < numGeoms; i++) {
- Polygon poly = (Polygon) geom.getGeometryN(i);
- if (poly.getArea() > maxSize) {
- if (displayGeom.intersects(poly)) {
- geom = poly;
- maxSize = poly.getArea();
+ SimpleFeatureIterator iter = features.features();
+ try {
+ while (iter.hasNext()) {
+ SimpleFeature ftr = iter.next();
+ geom = (Geometry) ftr.getDefaultGeometry();
+
+ List<Symbolizer> symbolizers = filterSymbolizers(ftr, fts);
+ if (symbolizers.size() != 0)
+ encodeStyle(ftr, symbolizers);
+
+ // if this is a multipolygon, get the largest polygon
+ // that intersects the AOI
+ if (geom instanceof MultiPolygon) {
+ double maxSize = -1;
+ int numGeoms = geom.getNumGeometries();
+ for (int i = 0; i < numGeoms; i++) {
+ Polygon poly = (Polygon) geom.getGeometryN(i);
+ if (poly.getArea() > maxSize) {
+ if (displayGeom.intersects(poly)) {
+ geom = poly;
+ maxSize = poly.getArea();
+ }
}
}
}
+ Geometry g1 = displayGeom.intersection(geom);
+ // skip if the geometry is not in the AOI
+ if (g1.isEmpty())
+ continue;
+ centroidGeom = g1.getCentroid();
+ encodePlacemark(ftr, symbolizers, centroidGeom, lookAtOpts);
}
- Geometry g1 = displayGeom.intersection(geom);
- // skip if the geometry is not in the AOI
- if (g1.isEmpty())
- continue;
- centroidGeom = g1.getCentroid();
- encodePlacemark(ftr, symbolizers, centroidGeom, lookAtOpts);
+ }
+ finally {
+ iter.close();
}
}
}
View
2  src/wms/src/main/java/org/geoserver/kml/KMLVectorTransformer.java
@@ -236,7 +236,7 @@ protected void encode(SimpleFeatureCollection features, FeatureTypeStyle[] style
}
} finally {
// make sure we always close
- features.close(reader);
+ reader.close();
}
}
}
View
58 src/wms/src/main/java/org/geoserver/wms/featureinfo/FeatureCollectionDecorator.java
@@ -8,9 +8,7 @@
import java.io.IOException;
import java.util.Collection;
-import java.util.Iterator;
-import org.geotools.feature.CollectionListener;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.geometry.jts.ReferencedEnvelope;
@@ -70,24 +68,6 @@ public Name getName() {
return (FeatureIterator<Feature>) fc.features();
}
- @SuppressWarnings("deprecation")
- public void close(FeatureIterator<Feature> close) {
- fc.close(close);
- }
-
- @SuppressWarnings("deprecation")
- public void close(Iterator<Feature> close) {
- fc.close(close);
- }
-
- public void addListener(CollectionListener listener) throws NullPointerException {
- fc.addListener(listener);
- }
-
- public void removeListener(CollectionListener listener) throws NullPointerException {
- fc.removeListener(listener);
- }
-
public FeatureType getSchema() {
return fc.getSchema();
}
@@ -113,32 +93,6 @@ public ReferencedEnvelope getBounds() {
return fc.getBounds();
}
- @SuppressWarnings("deprecation")
- public Iterator<Feature> iterator() {
- return fc.iterator();
- }
-
- @SuppressWarnings("deprecation")
- public void purge() {
- fc.purge();
- }
-
- public boolean add(Feature obj) {
- return fc.add(obj);
- }
-
- public boolean addAll(Collection<? extends Feature> collection) {
- return fc.addAll(collection);
- }
-
- public boolean addAll(FeatureCollection<? extends FeatureType, ? extends Feature> resource) {
- return fc.addAll(resource);
- }
-
- public void clear() {
- fc.clear();
- }
-
public boolean contains(Object o) {
return fc.contains(o);
}
@@ -151,18 +105,6 @@ public boolean isEmpty() {
return fc.isEmpty();
}
- public boolean remove(Object o) {
- return fc.remove(o);
- }
-
- public boolean removeAll(Collection<?> c) {
- return fc.removeAll(c);
- }
-
- public boolean retainAll(Collection<?> c) {
- return fc.retainAll(c);
- }
-
public int size() {
//overriding size implementation
//simply counting!
View
2  src/wms/src/main/java/org/geoserver/wms/georss/AtomGeoRSSTransformer.java
@@ -96,7 +96,7 @@ void encodeEntries(WMSMapContent map) throws IOException{
}
} finally {
if (iterator != null) {
- features.close(iterator);
+ iterator.close();
}
}
}
View
2  src/wms/src/main/java/org/geoserver/wms/georss/RSSGeoRSSTransformer.java
@@ -103,7 +103,7 @@ void encodeItems(WMSMapContent map) throws IOException {
}
} finally {
if (iterator != null) {
- features.close(iterator);
+ iterator.close();
}
}
View
14 src/wms/src/test/java/org/geoserver/wms/featureinfo/FeatureTemplateTest.java
@@ -7,8 +7,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import java.util.Iterator;
-
import org.geoserver.data.test.MockData;
import org.geoserver.wms.WMSTestSupport;
import org.geoserver.wms.featureinfo.dummy.Dummy;
@@ -26,7 +24,7 @@ public void testWithDateAndBoolean() throws Exception {
SimpleFeatureSource source = getFeatureSource( MockData.PRIMITIVEGEOFEATURE );
SimpleFeatureCollection fc = source.getFeatures();
- Iterator i = fc.iterator();
+ SimpleFeatureIterator i = fc.features();
try {
SimpleFeature f = (SimpleFeature) i.next();
@@ -40,7 +38,7 @@ public void testWithDateAndBoolean() throws Exception {
}
}
finally {
- fc.close( i );
+ i.close();
}
}
@@ -48,7 +46,7 @@ public void testWithDateAndBoolean() throws Exception {
public void testRawValue() throws Exception {
SimpleFeatureSource source = getFeatureSource(MockData.PRIMITIVEGEOFEATURE);
SimpleFeatureCollection fc = source.getFeatures();
- Iterator i = fc.iterator();
+ SimpleFeatureIterator i = fc.features();
try {
SimpleFeature f = (SimpleFeature) i.next();
@@ -60,7 +58,7 @@ public void testRawValue() throws Exception {
throw(e);
}
} finally {
- fc.close(i);
+ i.close();
}
}
@@ -69,7 +67,7 @@ public void testWithNull() throws Exception {
SimpleFeatureSource source = getFeatureSource( MockData.BASIC_POLYGONS );
SimpleFeatureCollection fc = source.getFeatures();
- Iterator i = fc.iterator();
+ SimpleFeatureIterator i = fc.features();
try {
SimpleFeature f = (SimpleFeature) i.next();
@@ -88,7 +86,7 @@ public void testWithNull() throws Exception {
}
finally {
- fc.close( i );
+ i.close();
}
}
View
2  src/wms/src/test/java/org/geoserver/wms/featureinfo/FeatureTimeTemplateTest.java
@@ -35,7 +35,7 @@ public void findFeature() throws Exception {
break;
}
}
- features.close(iterator);
+ iterator.close();
}
@Test
Something went wrong with that request. Please try again.