Author: ang05a Date: 2012-05-03 06:01:36 -0700 (Thu, 03 May 2012) New Revision: 38701 Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AttributeMapping.java trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/ComplexFeatureConstants.java trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/NestedAttributeMapping.java trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AppSchemaDataAccessConfigurator.java trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AttributeMapping.java trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/XMLConfigDigester.java trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/TestData.java trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/AppSchemaDataAccess.xsd Log: GEOT-4126: Enable specifying row number in getting sourceExpression for denormalised rows (for timeseries subsetting). Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AttributeMapping.java =================================================================== --- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AttributeMapping.java 2012-05-02 13:20:19 UTC (rev 38700) +++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/AttributeMapping.java 2012-05-03 13:01:36 UTC (rev 38701) @@ -63,6 +63,8 @@ private String instancePath; + private String sourceIndex; + /** * Creates a new AttributeMapping object. * @@ -73,10 +75,10 @@ */ public AttributeMapping(Expression idExpression, Expression sourceExpression, StepList targetXPath) { - this(idExpression, sourceExpression, targetXPath, null, false, null); + this(idExpression, sourceExpression, null, targetXPath, null, false, null); } - public AttributeMapping(Expression idExpression, Expression sourceExpression, + public AttributeMapping(Expression idExpression, Expression sourceExpression, String sourceIndex, StepList targetXPath, AttributeType targetNodeInstance, boolean isMultiValued, Map<Name, Expression> clientProperties) { @@ -86,6 +88,7 @@ if (this.sourceExpression == null) { this.sourceExpression = Expression.NIL; } + this.sourceIndex = sourceIndex; this.targetXPath = targetXPath; this.targetNodeInstance = targetNodeInstance; this.clientProperties = clientProperties == null ? Collections @@ -103,6 +106,10 @@ public Expression getSourceExpression() { return sourceExpression; } + + public String getSourceIndex() { + return sourceIndex; + } public StepList getTargetXPath() { return targetXPath; Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/ComplexFeatureConstants.java =================================================================== --- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/ComplexFeatureConstants.java 2012-05-02 13:20:19 UTC (rev 38700) +++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/ComplexFeatureConstants.java 2012-05-03 13:01:36 UTC (rev 38701) @@ -85,4 +85,9 @@ * Fake attribute name for simple contents of a complex type, eg. gml:name of gml:CodeType type */ public static final Name SIMPLE_CONTENT = new NameImpl(null, "simpleContent"); + + /** + * Constant to indicate the last row from denormalised rows. + */ + public static final String LAST_INDEX = "LAST"; } Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java =================================================================== --- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java 2012-05-02 13:20:19 UTC (rev 38700) +++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java 2012-05-03 13:01:36 UTC (rev 38701) @@ -902,7 +902,17 @@ setAttributeValue(target, null, source, attMapping, null, null, selectedProperties.get(attMapping)); } } else { - setAttributeValue(target, null, sources.get(0), attMapping, null, null, selectedProperties.get(attMapping)); + String indexString = attMapping.getSourceIndex(); + // if not specified, get the first row by default + int index = 0; + if (indexString != null) { + if (ComplexFeatureConstants.LAST_INDEX.equals(indexString)) { + index = sources.size() - 1; + } else { + index = Integer.parseInt(indexString); + } + } + setAttributeValue(target, null, sources.get(index), attMapping, null, null, selectedProperties.get(attMapping)); // When a feature is not multi-valued but still has multiple rows with the same ID in // a denormalised table, by default app-schema only takes the first row and ignores // the rest (see above). The following line is to make sure that the cursors in the Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/NestedAttributeMapping.java =================================================================== --- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/NestedAttributeMapping.java 2012-05-02 13:20:19 UTC (rev 38700) +++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/NestedAttributeMapping.java 2012-05-03 13:01:36 UTC (rev 38701) @@ -127,7 +127,7 @@ StepList targetXPath, boolean isMultiValued, Map<Name, Expression> clientProperties, Expression sourceElement, StepList sourcePath, NamespaceSupport namespaces) throws IOException { - super(idExpression, parentExpression, targetXPath, null, isMultiValued, clientProperties); + super(idExpression, parentExpression, null, targetXPath, null, isMultiValued, clientProperties); this.nestedTargetXPath = sourcePath; this.nestedFeatureType = sourceElement; this.filterFac = new FilterFactoryImplNamespaceAware(namespaces); Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AppSchemaDataAccessConfigurator.java =================================================================== --- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AppSchemaDataAccessConfigurator.java 2012-05-02 13:20:19 UTC (rev 38700) +++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AppSchemaDataAccessConfigurator.java 2012-05-03 13:01:36 UTC (rev 38701) @@ -346,8 +346,6 @@ final boolean isMultiValued = attDto.isMultiple(); - final boolean isList = attDto.isList(); - final Expression idExpression = (idXpath == null) ? parseOgcCqlExpression(idExpr) : new AttributeExpressionImpl(idXpath, new Hints( FeaturePropertyAccessorFactory.NAMESPACE_CONTEXT, this.namespaces)); @@ -401,7 +399,7 @@ } } else { - attMapping = new AttributeMapping(idExpression, sourceExpression, targetXPathSteps, + attMapping = new AttributeMapping(idExpression, sourceExpression, attDto.getSourceIndex(), targetXPathSteps, expectedInstanceOf, isMultiValued, clientProperties); } Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AttributeMapping.java =================================================================== --- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AttributeMapping.java 2012-05-02 13:20:19 UTC (rev 38700) +++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/AttributeMapping.java 2012-05-03 13:01:36 UTC (rev 38701) @@ -62,6 +62,17 @@ private String sourceExpression; /** + * Expression whose evaluation result in numeric value to indicate row number to extract {@link + * this#sourceExpression} from denormalised database rows. + * + * <p> + * At this stage, the expression must be a valid integer, or LAST would work to + * get the last dynamic result. + * </p> + */ + private String sourceIndex; + + /** * Label used to refer to an attribute. */ private String label; @@ -162,6 +173,31 @@ } /** + * Returns the expression whose evaluation result in numeric value to indicate row number to extract {@link + * this#sourceExpression} from denormalised database rows. + * + * <p> + * At this stage, the expression must be a valid integer, or LAST would work to + * get the last dynamic result. + * </p> + * + * @return OGC CQL expression for the attribute value + */ + public String getSourceIndex() { + return sourceIndex; + } + + /** + * Sets the OGC CQL expression index for the attribute value. + * + * @param sourceIndex + * OGC CQL expression index for the attribute value. + */ + public void setSourceIndex(String sourceIndex) { + this.sourceIndex = sourceIndex; + } + + /** * Return the input XPath expression * @return the input XPath expression */ Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/XMLConfigDigester.java =================================================================== --- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/XMLConfigDigester.java 2012-05-02 13:20:19 UTC (rev 38700) +++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/XMLConfigDigester.java 2012-05-03 13:01:36 UTC (rev 38701) @@ -238,6 +238,9 @@ digester.addCallMethod(attMap + "/sourceExpression/OCQL", "setSourceExpression", 1); digester.addCallParam(attMap + "/sourceExpression/OCQL", 0); + + digester.addCallMethod(attMap + "/sourceExpression/index", "setSourceIndex", 1); + digester.addCallParam(attMap + "/sourceExpression/index", 0); digester.addCallMethod(attMap + "/idExpression/inputAttribute", "setIdentifierPath", 1); digester.addCallParam(attMap + "/idExpression/inputAttribute", 0); Modified: trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/TestData.java =================================================================== --- trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/TestData.java 2012-05-02 13:20:19 UTC (rev 38700) +++ trunk/modules/extension/app-schema/app-schema/src/test/java/org/geotools/data/complex/TestData.java 2012-05-03 13:01:36 UTC (rev 38701) @@ -297,7 +297,7 @@ id = ff.property("id[1]"); source = null; target = "wq_plus/measurement"; - mappings.add(new AttributeMapping(id, source, XPath + mappings.add(new AttributeMapping(id, source, null, XPath .steps(targetFeature, target, namespaces), null, true, null)); source = ff.property("determinand_description"); Modified: trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/AppSchemaDataAccess.xsd =================================================================== --- trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/AppSchemaDataAccess.xsd 2012-05-02 13:20:19 UTC (rev 38700) +++ trunk/modules/extension/app-schema/app-schema/src/test/resources/test-data/AppSchemaDataAccess.xsd 2012-05-03 13:01:36 UTC (rev 38701) @@ -310,7 +310,16 @@ </annotation> <sequence> <choice minOccurs="0"> - <element name="OCQL" type="string" /> + <sequence> + <element name="OCQL" type="string" /> + <element name="index" type="string" minOccurs="0" maxOccurs="1"> + <annotation> + <documentation> + <![CDATA[ The index of database row if denormalised. Example of usage is timeseries endPosition that reflects the last timePosition where the timePosition value is dynamic. ]]> + </documentation> + </annotation> + </element> + </sequence> <element name="Expression"> <complexType> <sequence> |