diff --git a/modules/extension/xsd/xsd-fes/src/main/java/org/geotools/filter/v2_0/FESConfiguration.java b/modules/extension/xsd/xsd-fes/src/main/java/org/geotools/filter/v2_0/FESConfiguration.java index e678087..ae4177c 100644 --- a/modules/extension/xsd/xsd-fes/src/main/java/org/geotools/filter/v2_0/FESConfiguration.java +++ b/modules/extension/xsd/xsd-fes/src/main/java/org/geotools/filter/v2_0/FESConfiguration.java @@ -66,6 +66,7 @@ import org.geotools.filter.v2_0.bindings.TEqualsBinding; import org.geotools.filter.v2_0.bindings.TOverlapsBinding; import org.geotools.filter.v2_0.bindings.TouchesBinding; import org.geotools.filter.v2_0.bindings.ValueReferenceBinding; +import org.geotools.filter.v2_0.bindings.VersionTypeBinding; import org.geotools.filter.v2_0.bindings.WithinBinding; import org.geotools.gml3.v3_2.GMLConfiguration; import org.geotools.ows.v1_1.OWSConfiguration; @@ -157,7 +158,7 @@ public class FESConfiguration extends Configuration { // container.registerComponentImplementation(FES.UnaryLogicOpType,UnaryLogicOpTypeBinding.class); // container.registerComponentImplementation(FES.UpperBoundaryType,UpperBoundaryTypeBinding.class); // container.registerComponentImplementation(FES.VersionActionTokens,VersionActionTokensBinding.class); -// container.registerComponentImplementation(FES.VersionType,VersionTypeBinding.class); + container.registerComponentImplementation(FES.VersionType,VersionTypeBinding.class); // container.registerComponentImplementation(FES._Filter_Capabilities,_Filter_CapabilitiesBinding.class); // container.registerComponentImplementation(FES._LogicalOperators,_LogicalOperatorsBinding.class); // container.registerComponentImplementation(FES.GeometryOperandsType_GeometryOperand,GeometryOperandsType_GeometryOperandBinding.class); diff --git a/modules/extension/xsd/xsd-fes/src/main/java/org/geotools/filter/v2_0/bindings/ResourceIdTypeBinding.java b/modules/extension/xsd/xsd-fes/src/main/java/org/geotools/filter/v2_0/bindings/ResourceIdTypeBinding.java index d342d67..87d508c 100644 --- a/modules/extension/xsd/xsd-fes/src/main/java/org/geotools/filter/v2_0/bindings/ResourceIdTypeBinding.java +++ b/modules/extension/xsd/xsd-fes/src/main/java/org/geotools/filter/v2_0/bindings/ResourceIdTypeBinding.java @@ -1,42 +1,97 @@ package org.geotools.filter.v2_0.bindings; +import java.util.Calendar; +import java.util.Date; + import javax.xml.namespace.QName; +import org.geotools.filter.identity.ResourceIdImpl; import org.geotools.filter.v2_0.FES; import org.geotools.xml.AbstractComplexBinding; -import org.geotools.xml.AbstractComplexEMFBinding; import org.geotools.xml.ElementInstance; import org.geotools.xml.Node; import org.opengis.filter.FilterFactory; import org.opengis.filter.identity.FeatureId; +import org.opengis.filter.identity.ResourceId; +import org.opengis.filter.identity.Version; public class ResourceIdTypeBinding extends AbstractComplexBinding { FilterFactory factory; - + public ResourceIdTypeBinding(FilterFactory factory) { this.factory = factory; } - - public Class getType() { + + /** + * @return {@code FeatureId.class}, meant to catch {@code ResourceId.class} too + */ + public Class getType() { return FeatureId.class; } - + public QName getTarget() { return FES.ResourceIdType; } @Override public Object parse(ElementInstance instance, Node node, Object value) throws Exception { - return factory.featureId((String)node.getAttributeValue("rid")); + final String rid = (String) node.getAttributeValue("rid"); + final String previousRid = (String) node.getAttributeValue("previousRid"); + final Version version = (Version) node.getAttributeValue("version"); + final Calendar startTimeAtt = (Calendar) node.getAttributeValue("startDate"); + final Calendar endTimeAtt = (Calendar) node.getAttributeValue("endDate"); + + Date startTime = startTimeAtt == null ? null : startTimeAtt.getTime(); + Date endTime = endTimeAtt == null ? null : endTimeAtt.getTime(); + + String fid; + String featureVersion = null; + int idx = rid.indexOf(ResourceId.VERSION_SEPARATOR); + if (idx == -1) { + fid = rid; + } else { + fid = rid.substring(0, idx); + featureVersion = rid.substring(idx + 1); + } + ResourceIdImpl resourceId = new ResourceIdImpl(fid, featureVersion, version ); + resourceId.setPreviousRid(previousRid); + resourceId.setStartTime(startTime); + resourceId.setEndTime(endTime); + return resourceId; } - + @Override public Object getProperty(Object object, QName name) throws Exception { - if ("rid".equals(name.getLocalPart())) { - FeatureId fid = (FeatureId) object; + if (object == null) { + return null; + } + + final FeatureId fid = (FeatureId) object; + final String localName = name.getLocalPart(); + if ("id".equals(localName)) { return fid.getID(); } + if ("rid".equals(localName)) { + if (fid instanceof ResourceId) { + return ((ResourceId) fid).getRid(); + } else { + return fid.getID(); + } + } + if ("previousRid".equals(localName) && fid instanceof ResourceId) { + return ((ResourceId) fid).getPreviousRid(); + } + if ("version".equals(localName) && fid instanceof ResourceId) { + return ((ResourceId) fid).getVersion(); + } + if ("startDate".equals(localName) && fid instanceof ResourceId) { + return ((ResourceId) fid).getStartTime(); + } + if ("endDate".equals(localName) && fid instanceof ResourceId) { + return ((ResourceId) fid).getEndTime(); + } + return null; } } diff --git a/modules/extension/xsd/xsd-fes/src/main/java/org/geotools/filter/v2_0/bindings/VersionTypeBinding.java b/modules/extension/xsd/xsd-fes/src/main/java/org/geotools/filter/v2_0/bindings/VersionTypeBinding.java new file mode 100644 index 0000000..8587de0 --- /dev/null +++ b/modules/extension/xsd/xsd-fes/src/main/java/org/geotools/filter/v2_0/bindings/VersionTypeBinding.java @@ -0,0 +1,71 @@ +package org.geotools.filter.v2_0.bindings; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +import javax.xml.namespace.QName; + +import org.geotools.filter.v2_0.FES; +import org.geotools.xml.InstanceComponent; +import org.geotools.xml.SimpleBinding; +import org.geotools.xml.impl.DatatypeConverterImpl; +import org.opengis.filter.identity.Version; + +/** + * Binding for FES 2.0 {@code VersionType} mapping to {@link Version} + * + */ +public class VersionTypeBinding implements SimpleBinding { + + @Override + public QName getTarget() { + return FES.VersionType; + } + + @Override + public Class getType() { + return Version.class; + } + + @Override + public int getExecutionMode() { + return OVERRIDE; + } + + @Override + public Object parse(InstanceComponent instance, Object value) throws Exception { + final String content = (String) value; + + try { + Version.Action versionAction = Version.Action.valueOf(content); + return new Version(versionAction); + } catch (IllegalArgumentException e) { + try { + Integer index = Integer.valueOf(content); + return new Version(index); + } catch (NumberFormatException nfe) { + Calendar dateTime = DatatypeConverterImpl.getInstance().parseDateTime(content); + return new Version(dateTime.getTime()); + } + } + } + + @Override + public String encode(Object object, String value) throws Exception { + Version version = (Version) object; + if (version.getDateTime() != null) { + Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT")); + cal.setTimeInMillis(version.getDateTime().getTime()); + String dateTime = DatatypeConverterImpl.getInstance().printDateTime(cal); + return dateTime; + } + if (version.getIndex() != null) { + return String.valueOf(version.getIndex()); + } + if (version.getVersionAction() != null) { + return String.valueOf(version.getVersionAction()); + } + throw new IllegalArgumentException("Empty version union"); + } +} diff --git a/modules/extension/xsd/xsd-fes/src/test/java/org/geotools/filter/v2_0/bindings/FilterTypeBindingTest.java b/modules/extension/xsd/xsd-fes/src/test/java/org/geotools/filter/v2_0/bindings/FilterTypeBindingTest.java index 486a257..a78acb6 100644 --- a/modules/extension/xsd/xsd-fes/src/test/java/org/geotools/filter/v2_0/bindings/FilterTypeBindingTest.java +++ b/modules/extension/xsd/xsd-fes/src/test/java/org/geotools/filter/v2_0/bindings/FilterTypeBindingTest.java @@ -189,6 +189,15 @@ public class FilterTypeBindingTest extends FESTestSupport { assertEquals(3, getElementsByQName(doc, FES.ResourceId).getLength()); } + public void testEncodeRsourceId() throws Exception { + Document doc = encode(FilterMockData.resourceId(), FES.Filter); + assertEquals("fes:Filter", doc.getDocumentElement().getNodeName()); + //print(doc); + + assertEquals(4, getElementsByQName(doc, FES.ResourceId).getLength()); + + } + public void testEncodeSpatial() throws Exception { Document doc = encode(FilterMockData.intersects(), FES.Filter); assertEquals("fes:Filter", doc.getDocumentElement().getNodeName()); diff --git a/modules/extension/xsd/xsd-fes/src/test/java/org/geotools/filter/v2_0/bindings/ResourceIdTypeBindingTest.java b/modules/extension/xsd/xsd-fes/src/test/java/org/geotools/filter/v2_0/bindings/ResourceIdTypeBindingTest.java new file mode 100644 index 0000000..7212da1 --- /dev/null +++ b/modules/extension/xsd/xsd-fes/src/test/java/org/geotools/filter/v2_0/bindings/ResourceIdTypeBindingTest.java @@ -0,0 +1,89 @@ +package org.geotools.filter.v2_0.bindings; + +import static org.opengis.filter.identity.Version.Action.ALL; +import static org.opengis.filter.identity.Version.Action.FIRST; +import static org.opengis.filter.identity.Version.Action.LAST; +import static org.opengis.filter.identity.Version.Action.NEXT; +import static org.opengis.filter.identity.Version.Action.PREVIOUS; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +import org.geotools.factory.CommonFactoryFinder; +import org.geotools.filter.identity.ResourceIdImpl; +import org.geotools.filter.v2_0.FESTestSupport; +import org.geotools.xml.impl.DatatypeConverterImpl; +import org.opengis.filter.FilterFactory; +import org.opengis.filter.Id; +import org.opengis.filter.identity.Identifier; +import org.opengis.filter.identity.ResourceId; +import org.opengis.filter.identity.Version; + +public class ResourceIdTypeBindingTest extends FESTestSupport { + + public void testParse() throws Exception { + String xml = "" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + ""; + + buildDocument(xml); + + Id filter = (Id) parse(); + assertNotNull(filter); + assertEquals(7, filter.getIdentifiers().size()); + List ids = new ArrayList(7); + for (Identifier id : filter.getIdentifiers()) { + assertTrue(id instanceof ResourceId); + ids.add((ResourceId) id); + } + Collections.sort(ids, new Comparator() { + @Override + public int compare(ResourceId o1, ResourceId o2) { + return o1.getRid().compareTo(o2.getRid()); + } + }); + + final DatatypeConverterImpl dateParser = DatatypeConverterImpl.getInstance(); + final Date date1 = dateParser.parseDateTime("1977-01-17T01:05:40Z").getTime(); + final Date date2 = dateParser.parseDateTime("2011-07-29T23:49:40Z").getTime(); + FilterFactory ff = CommonFactoryFinder.getFilterFactory(null); + + // This is in consistent as the FIRST entry cannot have a previous1 + ResourceIdImpl resourceId = new ResourceIdImpl("rid1", "abc", new Version(FIRST)); + resourceId.setPreviousRid("previous1"); + assertEquals( resourceId, ids.get(0)); + + assertEquals(ff.resourceId("rid2", "", new Version(LAST)), + ids.get(1)); + assertEquals(ff.resourceId("rid3", "", new Version(PREVIOUS)), + ids.get(2)); + assertEquals(ff.resourceId("rid4", "", new Version(NEXT)), + ids.get(3)); + assertEquals(ff.resourceId("rid5", "", new Version(ALL)), + ids.get(4)); + + // This is inconsistent as date and resource based query cannot be used at the same time + ResourceIdImpl resourceId2 = new ResourceIdImpl("rid6", "", new Version(4)); + resourceId2.setPreviousRid("previous2"); + resourceId2.setStartTime(date1); + resourceId2.setEndTime(date2); + assertEquals( resourceId2, + ids.get(5)); + + assertEquals(ff.resourceId("rid7", "123", new Version(date1)), ids.get(6)); + } +} diff --git a/modules/extension/xsd/xsd-filter/src/test/java/org/geotools/filter/v1_1/FilterMockData.java b/modules/extension/xsd/xsd-filter/src/test/java/org/geotools/filter/v1_1/FilterMockData.java index edf2929..0a48a03 100644 --- a/modules/extension/xsd/xsd-filter/src/test/java/org/geotools/filter/v1_1/FilterMockData.java +++ b/modules/extension/xsd/xsd-filter/src/test/java/org/geotools/filter/v1_1/FilterMockData.java @@ -17,15 +17,14 @@ package org.geotools.filter.v1_1; import java.util.Arrays; +import java.util.Date; import java.util.LinkedHashSet; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; import javax.xml.namespace.QName; -import com.vividsolutions.jts.geom.Coordinate; -import com.vividsolutions.jts.geom.Geometry; -import com.vividsolutions.jts.geom.GeometryFactory; + +import org.geotools.factory.CommonFactoryFinder; +import org.geotools.filter.identity.ResourceIdImpl; +import org.geotools.gml3.GML; import org.opengis.filter.And; import org.opengis.filter.FilterFactory2; import org.opengis.filter.Id; @@ -46,6 +45,7 @@ import org.opengis.filter.expression.PropertyName; import org.opengis.filter.expression.Subtract; import org.opengis.filter.identity.GmlObjectId; import org.opengis.filter.identity.Identifier; +import org.opengis.filter.identity.Version; import org.opengis.filter.sort.SortBy; import org.opengis.filter.sort.SortOrder; import org.opengis.filter.spatial.Beyond; @@ -58,8 +58,13 @@ import org.opengis.filter.spatial.Intersects; import org.opengis.filter.spatial.Overlaps; import org.opengis.filter.spatial.Touches; import org.opengis.filter.spatial.Within; -import org.geotools.factory.CommonFactoryFinder; -import org.geotools.gml3.GML; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; /** @@ -80,6 +85,20 @@ public class FilterMockData { f.featureId("foo.1"), f.featureId("foo.2"), f.featureId("foo.3")))); } + public static Id resourceId() { + ResourceIdImpl resourceId = new ResourceIdImpl("foo.4","", new Version(Version.Action.NEXT)); + + resourceId.setPreviousRid("previousRid"); + resourceId.setStartTime( new Date(1000) ); + resourceId.setEndTime(new Date(2000)); + + return f.id(new LinkedHashSet(Arrays.asList( + f.featureId("foo.1", "v1"), + f.resourceId("foo.2", "", new Version(new Date(1000))),// + f.resourceId("foo.3", "", new Version(5)),// + resourceId))); + } + public static Element propertyName(Document document, Node parent) { return propertyName("foo", document, parent); } diff --git a/modules/extension/xsd/xsd-gml2/src/main/java/org/geotools/gml2/bindings/GMLEncodingUtils.java b/modules/extension/xsd/xsd-gml2/src/main/java/org/geotools/gml2/bindings/GMLEncodingUtils.java index 4f977b2..b3cde83 100644 --- a/modules/extension/xsd/xsd-gml2/src/main/java/org/geotools/gml2/bindings/GMLEncodingUtils.java +++ b/modules/extension/xsd/xsd-gml2/src/main/java/org/geotools/gml2/bindings/GMLEncodingUtils.java @@ -113,7 +113,7 @@ public class GMLEncodingUtils { if (type == null) { if (featureType instanceof SimpleFeatureType) { // could not find the feature type in the schema, create a mock one - LOGGER.fine("Could find type for " + typeName + LOGGER.warning("Could find type for " + typeName + " in the schema, generating type from feature."); type = createXmlTypeFromFeatureType((SimpleFeatureType) featureType, schemaIndex, toFilter); diff --git a/modules/extension/xsd/xsd-gml3/src/main/java/org/geotools/gml3/bindings/FeaturePropertyTypeBinding.java b/modules/extension/xsd/xsd-gml3/src/main/java/org/geotools/gml3/bindings/FeaturePropertyTypeBinding.java index 440dc71..17a7e97 100644 --- a/modules/extension/xsd/xsd-gml3/src/main/java/org/geotools/gml3/bindings/FeaturePropertyTypeBinding.java +++ b/modules/extension/xsd/xsd-gml3/src/main/java/org/geotools/gml3/bindings/FeaturePropertyTypeBinding.java @@ -25,7 +25,6 @@ import javax.xml.namespace.QName; import org.geotools.feature.FeatureImpl; import org.geotools.feature.NameImpl; -import org.geotools.feature.type.FeatureTypeImpl; import org.geotools.gml3.GML; import org.geotools.gml3.XSDIdRegistry; import org.geotools.util.Converters; @@ -35,10 +34,10 @@ import org.geotools.xml.ElementInstance; import org.geotools.xml.Node; import org.opengis.feature.ComplexAttribute; import org.opengis.feature.Feature; -import org.opengis.feature.Property; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.type.Name; import org.opengis.filter.identity.Identifier; +import org.opengis.filter.identity.ResourceId; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.Attributes; @@ -120,7 +119,12 @@ public class FeaturePropertyTypeBinding extends AbstractComplexBinding { if (ident == null) { return object; } - String id = Converters.convert(ident.getID(), String.class); + String id; + if (ident instanceof ResourceId) { + id = ((ResourceId) ident).getRid(); + } else { + id = Converters.convert(ident.getID(), String.class); + } if (idSet.idExists(id)) { return null; } @@ -162,7 +166,12 @@ public class FeaturePropertyTypeBinding extends AbstractComplexBinding { if (ident == null) { return; } - String id = Converters.convert(ident.getID(), String.class); + String id; + if (ident instanceof ResourceId) { + id = ((ResourceId) ident).getRid(); + } else { + id = Converters.convert(ident.getID(), String.class); + } if (idSet.idExists(id)) { // XSD type ids can only appear once in the same document, otherwise the document is // not schema valid. Attributes of the same ids should be encoded as xlink:href to diff --git a/modules/extension/xsd/xsd-gml3/src/main/java/org/geotools/gml3/bindings/GML3EncodingUtils.java b/modules/extension/xsd/xsd-gml3/src/main/java/org/geotools/gml3/bindings/GML3EncodingUtils.java index d91aa99..36602a6 100644 --- a/modules/extension/xsd/xsd-gml3/src/main/java/org/geotools/gml3/bindings/GML3EncodingUtils.java +++ b/modules/extension/xsd/xsd-gml3/src/main/java/org/geotools/gml3/bindings/GML3EncodingUtils.java @@ -46,6 +46,8 @@ import org.opengis.feature.Feature; import org.opengis.feature.Property; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.type.Name; +import org.opengis.filter.identity.FeatureId; +import org.opengis.filter.identity.ResourceId; import org.opengis.geometry.DirectPosition; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.w3c.dom.Document; @@ -203,7 +205,16 @@ public class GML3EncodingUtils { public Element AbstractFeatureTypeEncode(Object object, Document document, Element value, XSDIdRegistry idSet) { Feature feature = (Feature) object; - String id = (feature.getIdentifier() != null ? feature.getIdentifier().getID() : null); + String id = null; + FeatureId identifier = feature.getIdentifier(); + if (identifier != null) { + if (identifier instanceof ResourceId) { + id = ((ResourceId) identifier).getRid(); + } else { + id = identifier.getID(); + } + } + Name typeName; if (feature.getDescriptor() == null) { // no descriptor, assume WFS feature type name is the same as the name of the content diff --git a/modules/library/api/src/main/java/org/geotools/data/Query.java b/modules/library/api/src/main/java/org/geotools/data/Query.java index 9a33cee..086b1d0 100644 --- a/modules/library/api/src/main/java/org/geotools/data/Query.java +++ b/modules/library/api/src/main/java/org/geotools/data/Query.java @@ -20,11 +20,14 @@ import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Date; import java.util.List; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory; import org.opengis.filter.expression.PropertyName; +import org.opengis.filter.identity.ResourceId; +import org.opengis.filter.identity.Version; import org.opengis.filter.sort.SortBy; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.geotools.factory.CommonFactoryFinder; @@ -690,7 +693,40 @@ public class Query { public String getVersion() { return version; } - + public void setVersion( int index ){ + this.version = String.valueOf( index ); + } + public void setVersion( Date date ){ + this.version = date == null ? null : "date:"+date; + } + public void setVersion( Version.Action action ){ + this.version = action == null ? null : action.name(); + } + public void setVersion( Date startTime, Date endTime ){ + if( startTime == null || endTime == null ){ + this.version = null; + } + else { + this.version = "start:"+startTime+" end:"+endTime; + } + } + public void setVersion( ResourceId history ){ + if( history.getStartTime() != null && history.getEndTime() != null ){ + setVersion( history.getStartTime(),history.getEndTime() ); + } + else if( history.getVersion() != null ){ + Version ver = history.getVersion(); + if( ver.isVersionAction()){ + setVersion( ver.getVersionAction() ); + } + else if( ver.isDateTime() ){ + setVersion( ver.getDateTime() ); + } + else if( ver.isIndex() ){ + setVersion( ver.getIndex() ); + } + } + } /** * Set the version of features to retrieve where this is supported by the * data source being queried. diff --git a/modules/library/api/src/main/java/org/geotools/data/QueryCapabilities.java b/modules/library/api/src/main/java/org/geotools/data/QueryCapabilities.java index 8ccba9b..c70e1a2 100644 --- a/modules/library/api/src/main/java/org/geotools/data/QueryCapabilities.java +++ b/modules/library/api/src/main/java/org/geotools/data/QueryCapabilities.java @@ -115,4 +115,11 @@ public class QueryCapabilities { public boolean isJoiningSupported() { return false; } + + /** + * If true the datastore supports version information and allows version based queries. + */ + public boolean isVersionSupported() { + return false; + } } diff --git a/modules/library/main/src/main/java/org/geotools/filter/FidFilterImpl.java b/modules/library/main/src/main/java/org/geotools/filter/FidFilterImpl.java index bf88cfd..1097d55 100644 --- a/modules/library/main/src/main/java/org/geotools/filter/FidFilterImpl.java +++ b/modules/library/main/src/main/java/org/geotools/filter/FidFilterImpl.java @@ -150,7 +150,7 @@ public class FidFilterImpl extends AbstractFilterImpl implements FidFilter { Set set = new TreeSet(); for (Iterator i = fids.iterator(); i.hasNext();) { Identifier id = (Identifier) i.next(); - set.add(id.toString()); + set.add(id.getID().toString()); } return set; @@ -197,7 +197,7 @@ public class FidFilterImpl extends AbstractFilterImpl implements FidFilter { for (Iterator f = fids.iterator(); f.hasNext();) { Identifier featureId = (Identifier) f.next(); - if (fid.equals(featureId.toString())) { + if (fid.equals(featureId.getID().toString())) { f.remove(); } } diff --git a/modules/library/main/src/main/java/org/geotools/filter/FilterFactoryImpl.java b/modules/library/main/src/main/java/org/geotools/filter/FilterFactoryImpl.java index 5c4b38c..2c1f8b0 100644 --- a/modules/library/main/src/main/java/org/geotools/filter/FilterFactoryImpl.java +++ b/modules/library/main/src/main/java/org/geotools/filter/FilterFactoryImpl.java @@ -22,6 +22,8 @@ package org.geotools.filter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -46,7 +48,9 @@ import org.geotools.filter.expression.MultiplyImpl; import org.geotools.filter.expression.PropertyAccessorFactory; import org.geotools.filter.expression.SubtractImpl; import org.geotools.filter.identity.FeatureIdImpl; +import org.geotools.filter.identity.FeatureIdVersionedImpl; import org.geotools.filter.identity.GmlObjectIdImpl; +import org.geotools.filter.identity.ResourceIdImpl; import org.geotools.filter.spatial.BBOXImpl; import org.geotools.filter.spatial.BeyondImpl; import org.geotools.filter.spatial.ContainsImpl; @@ -117,6 +121,8 @@ import org.opengis.filter.expression.Subtract; import org.opengis.filter.identity.FeatureId; import org.opengis.filter.identity.GmlObjectId; import org.opengis.filter.identity.Identifier; +import org.opengis.filter.identity.ResourceId; +import org.opengis.filter.identity.Version; import org.opengis.filter.sort.SortBy; import org.opengis.filter.sort.SortOrder; import org.opengis.filter.spatial.BBOX; @@ -185,6 +191,21 @@ public class FilterFactoryImpl implements FilterFactory { return new GmlObjectIdImpl( id ); } + /** Creates a new feature id with version information */ + public FeatureId featureId(String fid, String featureVersion){ + return new FeatureIdVersionedImpl(fid, featureVersion); + } + + /** ResouceId for identifier based query */ + public ResourceId resourceId(String fid, String featureVersion, Version version ){ + return new ResourceIdImpl(fid, featureVersion, version); + } + + /** ResourceId for time based query */ + public ResourceId resourceId(String fid, Date startTime, Date endTime){ + return new ResourceIdImpl(fid, startTime, endTime ); + } + public And and(Filter f, Filter g ) { List/**/ list = new ArrayList/**/( 2 ); list.add( f ); @@ -216,6 +237,15 @@ public class FilterFactoryImpl implements FilterFactory { return new FidFilterImpl( id ); } + public Id id(FeatureId... fids) { + Set selection = new HashSet(); + for( FeatureId featureId : fids ){ + if( featureId == null ) continue; + selection.add( featureId ); + } + return id( selection ); + } + public PropertyName property(String name) { return new AttributeExpressionImpl(name); } diff --git a/modules/library/main/src/main/java/org/geotools/filter/identity/FeatureIdImpl.java b/modules/library/main/src/main/java/org/geotools/filter/identity/FeatureIdImpl.java index ee7984b..aec73fa 100644 --- a/modules/library/main/src/main/java/org/geotools/filter/identity/FeatureIdImpl.java +++ b/modules/library/main/src/main/java/org/geotools/filter/identity/FeatureIdImpl.java @@ -28,62 +28,98 @@ import org.opengis.filter.identity.FeatureId; *

* @author Justin Deoliveira, The Open Planning Project * - * - * - * * @source $URL$ + * @since 2.5 + * @version 8.0 */ public class FeatureIdImpl implements FeatureId { - /** underlying fid */ - protected String fid; - protected String origionalFid; - public FeatureIdImpl( String fid ) { - this.fid = fid; - if ( fid == null ) { - throw new NullPointerException( "fid must not be null" ); - } - } - - public String getID() { - return fid; - } - - public void setID( String id ){ - if ( id == null ) { - throw new NullPointerException( "fid must not be null" ); - } - if( origionalFid == null ){ - origionalFid = fid; - } - fid = id; - } - - public boolean matches(Feature feature) { - return feature != null && fid.equals( feature.getIdentifier().getID() ); - } - - public boolean matches(Object object) { - if ( object instanceof Feature ) { - return matches( (Feature) object ); - } - return false; - } - - public String toString() { - return fid; - } - - public boolean equals(Object obj) { - if ( obj instanceof FeatureId) { - return fid.equals( ((FeatureId)obj).getID() ); - } - - return false; - } - - public int hashCode() { - return fid.hashCode(); - } - -} + /** underlying fid */ + protected String fid; + protected String origionalFid; + + public FeatureIdImpl(String fid) { + this.fid = fid; + if (fid == null) { + throw new NullPointerException("fid must not be null"); + } + } + + public String getID() { + return fid; + } + + public void setID(String id) { + if (id == null) { + throw new NullPointerException("fid must not be null"); + } + if (origionalFid == null) { + origionalFid = fid; + } + fid = id; + } + + public boolean matches(Feature feature) { + if( feature == null ){ + return false; + } + return equalsExact( feature.getIdentifier() ); + } + + + public boolean matches(Object object) { + if (object instanceof Feature) { + return matches((Feature) object); + } + return false; + } + + public String toString() { + return fid; + } + + public boolean equals(Object obj) { + if (obj instanceof FeatureId) { + return fid.equals(((FeatureId) obj).getID()); + } + return false; + } + + public int hashCode() { + return fid.hashCode(); + } + + @Override + public boolean equalsExact(FeatureId id) { + if (id instanceof FeatureId) { + return fid.equals( id.getID() ) && + fid.equals( id.getRid() ) && + id.getPreviousRid() == null && + id.getFeatureVersion() == null; + } + return false; + } + + @Override + public boolean equalsFID(FeatureId id) { + if( id == null ) return false; + + return getID().equals(id.getID()); + } + + @Override + public String getRid() { + return getID(); + } + + @Override + public String getPreviousRid() { + return null; + } + + @Override + public String getFeatureVersion() { + return null; + } + +} \ No newline at end of file diff --git a/modules/library/main/src/main/java/org/geotools/filter/identity/FeatureIdVersionedImpl.java b/modules/library/main/src/main/java/org/geotools/filter/identity/FeatureIdVersionedImpl.java new file mode 100644 index 0000000..38337fd --- /dev/null +++ b/modules/library/main/src/main/java/org/geotools/filter/identity/FeatureIdVersionedImpl.java @@ -0,0 +1,102 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package org.geotools.filter.identity; + +import org.opengis.feature.Feature; +import org.opengis.filter.identity.FeatureId; +import org.opengis.filter.identity.Version; + +/** + * Implementation of {@link org.opengis.filter.identity.FeatureId} + *

+ * This class is mutable under one condition only; during a commit + * a datastore can update the internal fid to reflect the real identify + * assigned by the database or wfs. + *

+ * @author Justin Deoliveira, The Open Planning Project + * + * @source $URL$ + * @since 2.5 + * @version 8.0 + */ +public class FeatureIdVersionedImpl extends FeatureIdImpl { + protected static String VERSION_SEPARATOR = "@"; + + protected String featureVersion; + protected String previousRid; + + public FeatureIdVersionedImpl(String fid, String version ) { + this( fid, version, null); + } + public FeatureIdVersionedImpl(String fid, String version, String previousRid) { + super( fid ); + this.featureVersion = version; + this.previousRid = previousRid; + } + + + public String toString() { + return fid; + } + + public boolean equals(Object obj) { + if (obj instanceof FeatureId) { + return fid.equals(((FeatureId) obj).getID()); + } + return false; + } + + public int hashCode() { + return fid.hashCode(); + } + + @Override + public boolean equalsExact(FeatureId id) { + if (id instanceof FeatureId) { + return fid.equals( id.getID() ) && + fid.equals( id.getRid() ) && + id.getPreviousRid() == null && + id.getFeatureVersion() == null; + } + return false; + } + + @Override + public boolean equalsFID(FeatureId id) { + if( id == null ) return false; + + return getID().equals(id.getID()); + } + + @Override + public String getRid() { + return featureVersion == null ? getID() : new StringBuilder(getID()) + .append(VERSION_SEPARATOR).append(featureVersion).toString(); + } + + @Override + public String getPreviousRid() { + return previousRid; + } + + @Override + public String getFeatureVersion() { + return featureVersion; + } + + +} \ No newline at end of file diff --git a/modules/library/main/src/main/java/org/geotools/filter/identity/ResourceIdImpl.java b/modules/library/main/src/main/java/org/geotools/filter/identity/ResourceIdImpl.java new file mode 100644 index 0000000..bd09050 --- /dev/null +++ b/modules/library/main/src/main/java/org/geotools/filter/identity/ResourceIdImpl.java @@ -0,0 +1,130 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package org.geotools.filter.identity; + +import java.util.Date; + +import org.geotools.util.Utilities; +import org.opengis.filter.identity.ResourceId; +import org.opengis.filter.identity.Version; + +/** + * Implementation of {@link ResourceId} used for Query. + *

+ * This class is mutable under one condition only; during a commit a datastore can update the + * internal fid to reflect the real identify assigned by the database or wfs. + *

+ * + * @author Justin Deoliveira, The Open Planning Project + * @since 8.0 + * @source $URL$ + */ +public class ResourceIdImpl extends FeatureIdVersionedImpl implements ResourceId { + + private Date startTime; + private Date endTime; + + private long version; + + /** + * Obtain a ResourceId based on version lookup. + * + * @param fid feature being queried + * @param featureVersion version used as a reference point + * @param version scope of version based query (first, last, index, all, date, etc...) + */ + public ResourceIdImpl(String fid, String featureVersion, Version version) { + super(fid, featureVersion, null ); + if( version == null ){ + throw new NullPointerException("Version is required for rid lookup"); + } + this.version = version.union(); + } + /** + * + * @param rid + */ + public ResourceIdImpl(String fid, Date start, Date end ) { + super(fid, null, null ); + if( start == null || end == null ){ + throw new NullPointerException("Start and end time are required for a lookup based on a date range"); + } + this.startTime = start; + this.endTime = end; + } + + public void setRid(String rid) { + setID(rid); + } + + public void setPreviousRid(final String previousRid) { + this.previousRid = previousRid; + } + + public void setVersion(final Version version) { + this.version = version.union(); + } + + @Override + public Date getStartTime() { + return startTime; + } + + public void setStartTime(final Date startTime) { + this.startTime = startTime; + } + + @Override + public Date getEndTime() { + return endTime; + } + + public void setEndTime(final Date endTime) { + this.endTime = endTime; + } + + @Override + public Version getVersion() { + return new Version( version ); + } + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ResourceId)) { + return false; + } + if (!super.equals(obj)) { + return false; + } + final ResourceId o = (ResourceId) obj; + return Utilities.equals(featureVersion, o.getFeatureVersion()) + && Utilities.equals(previousRid, o.getPreviousRid()) + && Utilities.equals(version, o.getVersion()) + && Utilities.equals(startTime, o.getStartTime()) + && Utilities.equals(endTime, o.getEndTime()); + } + + @Override + public int hashCode() { + int hash = super.hashCode(); + hash = Utilities.hash(previousRid, hash); + hash = Utilities.hash(version, hash); + hash = Utilities.hash(startTime, hash); + hash = Utilities.hash(endTime, hash); + return hash; + } + +} diff --git a/modules/library/opengis/src/main/java/org/opengis/filter/FilterFactory.java b/modules/library/opengis/src/main/java/org/opengis/filter/FilterFactory.java index b26117f..8f2d7fc 100644 --- a/modules/library/opengis/src/main/java/org/opengis/filter/FilterFactory.java +++ b/modules/library/opengis/src/main/java/org/opengis/filter/FilterFactory.java @@ -9,6 +9,7 @@ */ package org.opengis.filter; +import java.util.Date; import java.util.List; import java.util.Set; @@ -39,6 +40,8 @@ import org.opengis.filter.expression.Subtract; import org.opengis.filter.identity.FeatureId; import org.opengis.filter.identity.GmlObjectId; import org.opengis.filter.identity.Identifier; +import org.opengis.filter.identity.ResourceId; +import org.opengis.filter.identity.Version; import org.opengis.filter.sort.SortBy; import org.opengis.filter.sort.SortOrder; import org.opengis.filter.spatial.BBOX; @@ -97,10 +100,19 @@ public interface FilterFactory { //////////////////////////////////////////////////////////////////////////////// /** Creates a new feautre id from a string */ FeatureId featureId(String id); + + /** Creates a new feature id with version information */ + FeatureId featureId(String fid, String featureVersion); /** Creates a new gml object id from a string */ GmlObjectId gmlObjectId(String id); + /** ResouceId for identifier based query */ + ResourceId resourceId(String fid, String featureVersion, Version version ); + + /** ResourceId for time based query */ + ResourceId resourceId(String fid, Date startTime, Date endTime); + //////////////////////////////////////////////////////////////////////////////// // // FILTERS diff --git a/modules/library/opengis/src/main/java/org/opengis/filter/FilterFactory2.java b/modules/library/opengis/src/main/java/org/opengis/filter/FilterFactory2.java index 4f23aa6..5d32ac0 100644 --- a/modules/library/opengis/src/main/java/org/opengis/filter/FilterFactory2.java +++ b/modules/library/opengis/src/main/java/org/opengis/filter/FilterFactory2.java @@ -16,6 +16,7 @@ import org.opengis.filter.MultiValuedFilter.MatchAction; import org.opengis.filter.capability.FunctionName; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.PropertyName; +import org.opengis.filter.identity.FeatureId; import org.opengis.filter.spatial.BBOX; import org.opengis.filter.spatial.Beyond; import org.opengis.filter.spatial.Contains; @@ -121,6 +122,8 @@ public interface FilterFactory2 extends FilterFactory { // //////////////////////////////////////////////////////////////////////////////// + Id id( FeatureId ...fids); + /** * Retrieves the value of a {@linkplain org.opengis.feature.Feature feature}'s property. * @param name Name of attribute referenced diff --git a/modules/library/opengis/src/main/java/org/opengis/filter/identity/FeatureId.java b/modules/library/opengis/src/main/java/org/opengis/filter/identity/FeatureId.java index 741c9cb..77b2e55 100644 --- a/modules/library/opengis/src/main/java/org/opengis/filter/identity/FeatureId.java +++ b/modules/library/opengis/src/main/java/org/opengis/filter/identity/FeatureId.java @@ -14,10 +14,9 @@ import org.opengis.annotation.XmlElement; /** * Feature identifier. + *

* Features are identified as strings. * - * - * * @source $URL$ * @version Implementation specification 1.0 * @author Chris Dillard (SYS Technologies) @@ -26,12 +25,18 @@ import org.opengis.annotation.XmlElement; */ @XmlElement("FeatureId") public interface FeatureId extends Identifier { + + public static final char VERSION_SEPARATOR = '@'; + /** * The identifier value, which is a string. */ @XmlElement("fid") String getID(); + // + // Query and Test methods used to test a feature or record + // /** * Evaluates the identifer value against the given feature. * @@ -39,4 +44,68 @@ public interface FeatureId extends Identifier { * @return {@code true} if a match, otherwise {@code false}. */ boolean matches(Object feature); + + /** Check if the provided FeatureId is an exact match (including any optional version + * information). + * + * @param id + * @return true if this is an exact match (including any optional version information) + */ + boolean equalsExact(FeatureId id); + + /** + * Checks if the provided FeatureId reflects the same feature. + *

+ * This comparison does not compare any optional version information. + * + * @param id + * @return true if both identifiers describe the same feature (does not compare version information). + */ + boolean equalsFID(FeatureId id); + + // + // Filter 2.0 Versioning Support + // + // The following methods are optional and are used as part of the FeatureId data + // structure to report any available version information associated with a resoruce. + // + /** + * id of the resource that shall be selected by the predicate. + *

+ * Equals to {@link #getID()} if no feature version is provided, or + * {@code getID() + "@" + getFeatureVersion()} if {@code getFeatureVersion() != null} + * + *

+ * If an implementation that references this International Standard supports versioning, the rid + * shall be a system generated hash containing a logical resource identifier and a version + * number. The specific details of the hash are implementation dependant and shall be opaque to + * a client + *

+ *

+ * If versioning is not supported, the same value than {@link FeatureId#getID()} shall be + * returned. + *

+ * @return Resource identifier made up of FID (combined with FeatureVersion if available) + */ + @XmlElement("rid") + String getRid(); + + /** + * previousRid attribute may be used, in implementations that support versioning, to report the + * previous identifier of a resource. + * + * @return Previous rid if available; or {@code null} + */ + @XmlElement("previousRid") + String getPreviousRid(); + + /** + * Version identifier for the feature instance, may be {@code null} + * + * @see #getID() + * @see #getRid() + * @return Optional version information; {@code null} if not available + */ + String getFeatureVersion(); + } diff --git a/modules/library/opengis/src/main/java/org/opengis/filter/identity/ResourceId.java b/modules/library/opengis/src/main/java/org/opengis/filter/identity/ResourceId.java new file mode 100644 index 0000000..ba26f91 --- /dev/null +++ b/modules/library/opengis/src/main/java/org/opengis/filter/identity/ResourceId.java @@ -0,0 +1,59 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2011, Open Source Geospatial Foundation (OSGeo) + * (C) 2005, Open Geospatial Consortium Inc. + * + * All Rights Reserved. http://www.opengis.org/legal/ + */ +package org.opengis.filter.identity; + +import java.util.Date; + +import org.opengis.annotation.XmlElement; + +/** + * Resource identifier as per FES 2.0. + *

+ * Please note this is a query object for use with the Filter Id filter as shown: + *

Filter filter = filterFactory.id(
+ *    ff.featureId("CITY.123"),
+ *    ff.resourceId("CITY.123",Version.Action.PREVIOUS) );
+ * In cases where a plain FetureId is used for lookup it is understood to refer to + * Version.Action.LAST. + *

+ * If an implementation that references this International Standard does not support versioning, any + * value specified for the attributes {@link #getPreviousRid() previousRid}, {@link #getVersion() + * version}, {@link #getStartTime() startTime}, and {@link #getEndTime() endTime} shall be ignored + * and the predicate shall always select the single version that is available. + *

+ */ +@XmlElement("ResourceId") +public interface ResourceId extends FeatureId { + + /** + * Used to navigate versions of a resource. + *

+ * @return Version based resource query; or {@code null} if using a start and end time + */ + @XmlElement("version") + Version getVersion(); + + /** + * Used to select versions of a resource between start and end time. + *

+ * @return start time for a time based query; or {@code null} if using version + */ + @XmlElement("startTime") + Date getStartTime(); + + /** + * Used to select versions of a resource between start and end time. + * + * @return end time for a time based query; or {@code null} if using version + */ + @XmlElement("endTime") + Date getEndTime(); + +} \ No newline at end of file diff --git a/modules/library/opengis/src/main/java/org/opengis/filter/identity/Version.java b/modules/library/opengis/src/main/java/org/opengis/filter/identity/Version.java new file mode 100644 index 0000000..f388575 --- /dev/null +++ b/modules/library/opengis/src/main/java/org/opengis/filter/identity/Version.java @@ -0,0 +1,175 @@ +package org.opengis.filter.identity; + +import java.util.Date; + +/** + * Union type class for the {@code Version} Union type in FES 2.0. + *

+ * The union is actually captured as a union inside a single long field. + * + * @invariant {@code #getVersionAction() != null || #getIndex() != null || #getDateTime() != null} + */ +public final class Version { + + /** + * The VersionAction attribute may also be the strings FIRST, LATEST, PREVIOUS, NEXT and ALL. + */ + public enum Action { + /** Select the first version of a resource. */ + FIRST, + /** Select the most recent version of a resource. */ + LAST, + /** Select the previous version of a resource relative to the version specified using the rid attribute. */ + NEXT, + /** Select the next version of a resource relative to the version specified using the rid attribute. */ + PREVIOUS, + /** Select all available version of a resource. */ + ALL; + + public static Action lookup(int ordinal) { + for (Action action : Action.values()) { + if (action.ordinal() == ordinal) { + return action; + } + } + return null; // not found + } + } + + static final long UNION_MASK = 0x0FFFFFFFFFFFFFFFl; + + static final long UNION_INTEGER = 0x1000000000000000l; + + static final long UNION_DATE = 0x2000000000000000l; + + static final long UNION_ACTION = 0x4000000000000000l; + + /** + * The union is represented as + *

    + *
  • UNION_INTEGER | int
  • + *
  • UNION_DATE | date.getTime()
  • + *
  • UNION_ACTION | action.ordinal()
  • + *
+ */ + final long union; + + public Version(long union){ + this.union = union; + } + + public Version(final Action action) { + if (action == null) { + throw new IllegalArgumentException("action can't be null"); + } + this.union = UNION_ACTION | action.ordinal(); + } + + public Version(final Integer index) { + if (index == null) { + throw new IllegalArgumentException("index can't be null"); + } + this.union = UNION_INTEGER | (long) index; + } + + public Version(final Date dateTime) { + if (dateTime == null) { + throw new IllegalArgumentException("dateTime can't be null"); + } + this.union = UNION_DATE | (dateTime.getTime()); + } + + public boolean isVersionAction() { + return (UNION_ACTION & union) > 0; + } + + /** + * Access to the union memento; this may be stored as an encoding of the + * Version in memory sensitive settings where the over head of an object + * is not desired. + *

+ * To restore please use new Version( union ) + * + * @return memento holding the contents of a Version object + */ + public long union(){ + return union; + } + + /** + * Version requested using a predefined constant. + *

+ * The versionAction attribute may also be the strings FIRST, LATEST, PREVIOUS, NEXT and ALL. The token FIRST shall select the first version of a + * resource. The token LATEST shall select the most recent version of a resource. The PREVIOUS and NEXT tokens shall select the previous or next + * version of a resource relative to the version specified using the rid attribute. The token ALL shall select all available version of a + * resource. + * + * @return Version requested using a predefined constant. + */ + public Action getVersionAction() { + if ((UNION_ACTION & union) > 0) { + int ordinal = (int) (union & UNION_MASK); + Action action = Action.lookup(ordinal); + return action; + } + return null; + } + + /** + * Version index requested. + * + * @return true if the Version is supplied by an index + */ + public boolean isIndex() { + return (UNION_INTEGER & union) > 0; + } + + /** + * Version requested as defined by an index (from 1 throught to the latest). + *

+ * The version attribute may be an integer N indicating that the Nth version of the resource shall be selected. The first version of a resource + * shall be numbered 1. If N exceeds the number of versions available, the latest version of the resource shall be selected. + * + * @return index of version requested (from 1 through to the latest) + */ + public Integer getIndex() { + if ((UNION_INTEGER & union) > 0) { + int index = (int) (union & UNION_MASK); + return index; + } + return null; + } + + public boolean isDateTime() { + return (UNION_DATE & union) > 0; + } + + /** + * Version requested as the closest to the provided date. + *

+ * The version attribute may also be date indicating that the version of the resource closest to the specified date shall be selected. + * + * @return date of version requested + */ + public Date getDateTime() { + if ((UNION_DATE & union) > 0) { + long time = (union & UNION_MASK); + return new Date(time); + } + return null; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Version)) { + return false; + } + Version v = (Version) o; + return union == v.union; + } + + @Override + public int hashCode() { + return 17 * (int) union; + } +} \ No newline at end of file diff --git a/modules/library/opengis/src/test/java/org/opengis/filter/identity/VersionTest.java b/modules/library/opengis/src/test/java/org/opengis/filter/identity/VersionTest.java new file mode 100644 index 0000000..eb3b9f5 --- /dev/null +++ b/modules/library/opengis/src/test/java/org/opengis/filter/identity/VersionTest.java @@ -0,0 +1,59 @@ +package org.opengis.filter.identity; + +import static org.junit.Assert.*; + +import java.util.Date; + +import org.junit.Test; +import org.opengis.filter.identity.Version.Action; + +public class VersionTest { + + @Test + public void bitwise() { + for (Action action : Action.values()) { + long encoded = Version.UNION_ACTION | ((long) action.ordinal()); + + assertTrue( (encoded & Version.UNION_ACTION) > 0 ); + long decoded = Version.UNION_MASK & ((long)encoded); + + Action found = Action.lookup((int)decoded); + assertEquals( action, found ); + } + + } + + @Test + public void versionInteger() { + Version version = new Version(1234567890); + + assertNotNull(version.getIndex()); + assertTrue( version.isIndex() ); + assertEquals(1234567890, (int) version.getIndex()); + + assertFalse( version.isVersionAction() ); + assertNull(version.getVersionAction()); + + assertNull(version.getDateTime()); + } + + @Test + public void versionDate() { + Date now = new Date(); + + Version version = new Version(now); + + assertEquals(now, version.getDateTime()); + assertNull(version.getIndex()); + assertNull(version.getVersionAction()); + } + + @Test + public void versionAction() { + Version version = new Version(Version.Action.ALL); + + assertEquals(Version.Action.ALL, version.getVersionAction()); + assertNull(version.getIndex()); + assertNull(version.getDateTime()); + } +} diff --git a/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureWriter.java b/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureWriter.java index ac08923..a5ba0ce 100644 --- a/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureWriter.java +++ b/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureWriter.java @@ -883,17 +883,7 @@ abstract class ArcSdeFeatureWriter implements FeatureWriter