Author: jsorel
Date: Thu Apr 26 10:34:34 2018
New Revision: 1830184
URL: http://svn.apache.org/viewvc?rev=1830184&view=rev
Log:
Query : support simple query columns
Added:
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/AbstractBinaryComparisonOperator.java
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultPropertyIsEqualTo.java
Modified:
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/AbstractExpression.java
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultLiteral.java
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultPropertyName.java
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultSortBy.java
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQueryFeatureSet.java
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/query/SimpleQueryTest.java
Added:
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/AbstractBinaryComparisonOperator.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/AbstractBinaryComparisonOperator.java?rev=1830184&view=auto
==============================================================================
---
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/AbstractBinaryComparisonOperator.java
(added)
+++
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/AbstractBinaryComparisonOperator.java
Thu Apr 26 10:34:34 2018
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.filter;
+
+import org.opengis.filter.BinaryComparisonOperator;
+import org.opengis.filter.MatchAction;
+import org.opengis.filter.expression.Expression;
+
+/**
+ *
+ * @author Johann Sorel (Geomatys)
+ * @version 1.0
+ * @since 1.0
+ * @module
+ */
+abstract class AbstractBinaryComparisonOperator implements
BinaryComparisonOperator {
+
+ protected final Expression exp1;
+ protected final Expression exp2;
+ protected final boolean matchCase;
+ protected final MatchAction matchAction;
+
+ public AbstractBinaryComparisonOperator(Expression exp1, Expression exp2,
boolean matchCase, MatchAction matchAction) {
+ this.exp1 = exp1;
+ this.exp2 = exp2;
+ this.matchCase = matchCase;
+ this.matchAction = matchAction;
+ }
+
+ @Override
+ public Expression getExpression1() {
+ return exp1;
+ }
+
+ @Override
+ public Expression getExpression2() {
+ return exp2;
+ }
+
+ @Override
+ public boolean isMatchingCase() {
+ return matchCase;
+ }
+
+ @Override
+ public MatchAction getMatchAction() {
+ return matchAction;
+ }
+
+
+}
Modified:
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/AbstractExpression.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/AbstractExpression.java?rev=1830184&r1=1830183&r2=1830184&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/AbstractExpression.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/AbstractExpression.java
[UTF-8] Thu Apr 26 10:34:34 2018
@@ -21,6 +21,9 @@ import org.opengis.filter.expression.Exp
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ObjectConverters;
import org.apache.sis.util.UnconvertibleObjectException;
+import org.opengis.feature.FeatureType;
+import org.opengis.feature.IdentifiedType;
+import org.opengis.feature.PropertyType;
/**
@@ -49,4 +52,18 @@ public abstract class AbstractExpression
return null;
}
}
+
+ /**
+ * Estimate the produced type of this expression when a feature will
+ * be evaluated.
+ * <p>
+ * The resulting type must be static, an AttributeType or
FeatureAssociationRole
+ * but not an Operation.
+ * </p>
+ *
+ * @param type expected evaluated feature type
+ * @return expected expression result type
+ */
+ public abstract PropertyType expectedType(FeatureType type);
+
}
Modified:
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java?rev=1830184&r1=1830183&r2=1830184&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
[UTF-8] Thu Apr 26 10:34:34 2018
@@ -426,7 +426,7 @@ public class DefaultFilterFactory implem
@Override
public PropertyIsEqualTo equal(final Expression expr1,
final Expression expr2, final boolean matchCase, MatchAction
matchAction) {
- throw new UnsupportedOperationException("Not supported yet.");
+ return new DefaultPropertyIsEqualTo(expr1, expr2, matchCase,
matchAction);
}
/**
@@ -795,7 +795,7 @@ public class DefaultFilterFactory implem
*/
@Override
public SortBy sort(final String propertyName, final SortOrder order) {
- throw new UnsupportedOperationException("Not supported yet.");
+ return new DefaultSortBy(property(propertyName), order);
}
// CAPABILITIES
////////////////////////////////////////////////////////////
Modified:
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultLiteral.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultLiteral.java?rev=1830184&r1=1830183&r2=1830184&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultLiteral.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultLiteral.java
[UTF-8] Thu Apr 26 10:34:34 2018
@@ -17,6 +17,9 @@
package org.apache.sis.filter;
import java.util.Objects;
+import org.apache.sis.feature.builder.FeatureTypeBuilder;
+import org.opengis.feature.AttributeType;
+import org.opengis.feature.FeatureType;
import org.opengis.filter.expression.ExpressionVisitor;
import org.opengis.filter.expression.Literal;
@@ -37,6 +40,7 @@ public class DefaultLiteral<T> extends A
private static final long serialVersionUID = 3240145927452086297L;
private final T value;
+ private final AttributeType<T> resultType;
/**
*
@@ -44,6 +48,7 @@ public class DefaultLiteral<T> extends A
*/
public DefaultLiteral(final T value) {
this.value = value;
+ resultType = (AttributeType<T>) new
FeatureTypeBuilder().addAttribute(value.getClass()).setName("Literal").build();
}
/**
@@ -55,6 +60,14 @@ public class DefaultLiteral<T> extends A
}
/**
+ * {@inheritDoc }
+ */
+ @Override
+ public AttributeType<T> expectedType(FeatureType type) {
+ return resultType;
+ }
+
+ /**
* {@inheritDoc }
*/
@Override
Added:
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultPropertyIsEqualTo.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultPropertyIsEqualTo.java?rev=1830184&view=auto
==============================================================================
---
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultPropertyIsEqualTo.java
(added)
+++
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultPropertyIsEqualTo.java
Thu Apr 26 10:34:34 2018
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.filter;
+
+import java.util.Objects;
+import org.opengis.filter.FilterVisitor;
+import org.opengis.filter.MatchAction;
+import org.opengis.filter.PropertyIsEqualTo;
+import org.opengis.filter.expression.Expression;
+
+/**
+ * Immutable PropertyIsEqualTo filter.
+ *
+ * @author Johann Sorel (Geomatys)
+ * @version 1.0
+ * @since 1.0
+ * @module
+ */
+public class DefaultPropertyIsEqualTo extends AbstractBinaryComparisonOperator
implements PropertyIsEqualTo {
+
+ public DefaultPropertyIsEqualTo(Expression exp1, Expression exp2, boolean
matchCase, MatchAction matchAction) {
+ super(exp1, exp2, matchCase, matchAction);
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ public boolean evaluate(Object object) {
+ final Object r1 = exp1.evaluate(object);
+ final Object r2 = exp2.evaluate(object);
+ //TODO be more relax on equality testing, for example
Date,TimeStamp,Instant or numerics
+ return Objects.equals(r1, r2);
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ public Object accept(FilterVisitor visitor, Object extraData) {
+ return visitor.visit(this, extraData);
+ }
+
+}
Modified:
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultPropertyName.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultPropertyName.java?rev=1830184&r1=1830183&r2=1830184&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultPropertyName.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultPropertyName.java
[UTF-8] Thu Apr 26 10:34:34 2018
@@ -18,11 +18,17 @@ package org.apache.sis.filter;
import java.util.Map;
import java.util.Objects;
+import org.apache.sis.feature.builder.FeatureTypeBuilder;
import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.collection.BackingStoreException;
// Branch-dependent imports
import org.opengis.feature.Feature;
+import org.opengis.feature.FeatureType;
+import org.opengis.feature.IdentifiedType;
+import org.opengis.feature.Operation;
import org.opengis.feature.PropertyNotFoundException;
+import org.opengis.feature.PropertyType;
import org.opengis.filter.expression.ExpressionVisitor;
import org.opengis.filter.expression.PropertyName;
@@ -78,6 +84,25 @@ public class DefaultPropertyName extends
}
/**
+ * {@inheritDoc }
+ */
+ @Override
+ public PropertyType expectedType(FeatureType type) {
+ PropertyType propertyType = type.getProperty(property);
+ while (propertyType instanceof Operation) {
+ IdentifiedType it = ((Operation) propertyType).getResult();
+ if (it instanceof FeatureType) {
+ propertyType = new
FeatureTypeBuilder().addAssociation(type).setName(property).build();
+ } else if (it instanceof PropertyType) {
+ propertyType = (PropertyType) it;
+ } else {
+ throw new BackingStoreException("Unexpected operation result
type "+it);
+ }
+ }
+ return propertyType;
+ }
+
+ /**
* {@inheritDoc }
*/
@Override
Modified:
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultSortBy.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultSortBy.java?rev=1830184&r1=1830183&r2=1830184&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultSortBy.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultSortBy.java
[UTF-8] Thu Apr 26 10:34:34 2018
@@ -16,6 +16,7 @@
*/
package org.apache.sis.filter;
+import java.util.Objects;
import org.opengis.filter.expression.PropertyName;
import org.opengis.filter.sort.SortBy;
import org.opengis.filter.sort.SortOrder;
@@ -59,4 +60,30 @@ public class DefaultSortBy implements So
return order;
}
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 41 * hash + Objects.hashCode(this.property);
+ hash = 41 * hash + Objects.hashCode(this.order);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final DefaultSortBy other = (DefaultSortBy) obj;
+ if (!Objects.equals(this.property, other.property)) {
+ return false;
+ }
+ return Objects.equals(this.order, other.order);
+ }
+
}
Modified:
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java?rev=1830184&r1=1830183&r2=1830184&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
[UTF-8] Thu Apr 26 10:34:34 2018
@@ -22,11 +22,17 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.sis.feature.builder.FeatureTypeBuilder;
+import org.apache.sis.filter.AbstractExpression;
import org.apache.sis.storage.FeatureSet;
import org.apache.sis.storage.Query;
import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.collection.BackingStoreException;
import org.apache.sis.util.iso.Names;
+import org.opengis.feature.AttributeType;
+import org.opengis.feature.FeatureAssociationRole;
import org.opengis.feature.FeatureType;
+import org.opengis.feature.IdentifiedType;
+import org.opengis.feature.PropertyType;
import org.opengis.filter.Filter;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.sort.SortBy;
@@ -234,10 +240,37 @@ public class SimpleQuery implements Quer
public Column(Expression expression, String alias) {
ArgumentChecks.ensureNonNull("expression", expression);
- this.alias = Names.createLocalName(null, null, alias);
+ this.alias = alias == null ? null : Names.createLocalName(null,
null, alias);
this.expression = expression;
}
+ /**
+ * Returns the column expected property type.
+ * @param type
+ * @return
+ */
+ public PropertyType expectedType(FeatureType type) {
+ PropertyType resultType;
+ if (expression instanceof AbstractExpression) {
+ resultType = ((AbstractExpression)
expression).expectedType(type);
+ } else {
+ resultType = expression.evaluate(type, PropertyType.class);
+ }
+
+ if (alias != null) {
+ //rename result type
+ if (resultType instanceof AttributeType) {
+ resultType = new
FeatureTypeBuilder().addAttribute((AttributeType<?>)
resultType).setName(alias).build();
+ } else if (resultType instanceof FeatureAssociationRole) {
+ resultType = new
FeatureTypeBuilder().addAssociation((FeatureAssociationRole)
resultType).setName(alias).build();
+ } else {
+ throw new BackingStoreException("Expression "+expression+"
returned an unexpected property type result "+resultType);
+ }
+ }
+
+ return resultType;
+ }
+
@Override
public int hashCode() {
int hash = 3;
@@ -302,7 +335,10 @@ public class SimpleQuery implements Quer
if (columns == null) return source;
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
-
+ ftb.setName(source.getName());
+ for (Column col : columns) {
+ ftb.addProperty(col.expectedType(source));
+ }
return ftb.build();
}
Modified:
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQueryFeatureSet.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQueryFeatureSet.java?rev=1830184&r1=1830183&r2=1830184&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQueryFeatureSet.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQueryFeatureSet.java
[UTF-8] Thu Apr 26 10:34:34 2018
@@ -108,7 +108,7 @@ final class SimpleQueryFeatureSet implem
//apply filter
final Filter filter = query.getFilter();
if (!Filter.INCLUDE.equals(filter)) {
- stream.filter(filter::evaluate);
+ stream = stream.filter(filter::evaluate);
}
//apply sort by
@@ -141,7 +141,7 @@ final class SimpleQueryFeatureSet implem
.collect(Collectors.toList())
.toArray(new String[0]);
- stream.map(new Function<Feature, Feature>() {
+ stream = stream.map(new Function<Feature, Feature>() {
@Override
public Feature apply(Feature t) {
final Feature f = type.newInstance();
Modified:
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/query/SimpleQueryTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/query/SimpleQueryTest.java?rev=1830184&r1=1830183&r2=1830184&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/query/SimpleQueryTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/query/SimpleQueryTest.java
[UTF-8] Thu Apr 26 10:34:34 2018
@@ -19,6 +19,8 @@ package org.apache.sis.internal.storage.
import java.util.Arrays;
import java.util.stream.Collectors;
import org.apache.sis.feature.builder.FeatureTypeBuilder;
+import org.apache.sis.filter.DefaultLiteral;
+import org.apache.sis.filter.DefaultPropertyIsEqualTo;
import org.apache.sis.filter.DefaultPropertyName;
import org.apache.sis.filter.DefaultSortBy;
import org.apache.sis.internal.storage.ArrayFeatureSet;
@@ -27,8 +29,11 @@ import org.apache.sis.storage.FeatureSet
import org.apache.sis.test.TestCase;
import static org.junit.Assert.*;
import org.junit.Test;
+import org.opengis.feature.AttributeType;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureType;
+import org.opengis.feature.PropertyType;
+import org.opengis.filter.MatchAction;
import org.opengis.filter.sort.SortOrder;
/**
@@ -132,4 +137,65 @@ public class SimpleQueryTest extends Tes
assertEquals(FEATURES[4], result[4]);
}
+ /**
+ * Verify query filter.
+ *
+ * @throws DataStoreException
+ */
+ @Test
+ public void testFilter() throws DataStoreException {
+
+ final SimpleQuery query = new SimpleQuery();
+ query.setFilter(new DefaultPropertyIsEqualTo(new
DefaultPropertyName("value1"), new DefaultLiteral(2), true, MatchAction.ALL));
+
+ final FeatureSet fs = SimpleQuery.executeOnCPU(FEATURESET, query);
+ final Feature[] result =
fs.features(false).collect(Collectors.toList()).toArray(new Feature[0]);
+
+ assertEquals(FEATURES[1], result[0]);
+ assertEquals(FEATURES[2], result[1]);
+ }
+
+ /**
+ * Verify query columns.
+ *
+ * @throws DataStoreException
+ */
+ @Test
+ public void testColumns() throws DataStoreException {
+
+ final SimpleQuery query = new SimpleQuery();
+ query.setColumns(Arrays.asList(
+ new SimpleQuery.Column(new DefaultPropertyName("value1"),
(String)null),
+ new SimpleQuery.Column(new DefaultPropertyName("value1"),
"renamed1"),
+ new SimpleQuery.Column(new DefaultLiteral<>("a literal"),
"computed")
+ ));
+ query.setLimit(1);
+
+ final FeatureSet fs = SimpleQuery.executeOnCPU(FEATURESET, query);
+ final Feature[] results =
fs.features(false).collect(Collectors.toList()).toArray(new Feature[0]);
+ assertEquals(1, results.length);
+
+ final Feature result = results[0];
+
+ //check result type
+ final FeatureType resultType = result.getType();
+ assertEquals("Test", resultType.getName().toString());
+ assertEquals(3, resultType.getProperties(true).size());
+ final PropertyType pt1 = resultType.getProperty("value1");
+ final PropertyType pt2 = resultType.getProperty("renamed1");
+ final PropertyType pt3 = resultType.getProperty("computed");
+ assertTrue(pt1 instanceof AttributeType);
+ assertTrue(pt2 instanceof AttributeType);
+ assertTrue(pt3 instanceof AttributeType);
+ assertEquals(Integer.class, ((AttributeType) pt1).getValueClass());
+ assertEquals(Integer.class, ((AttributeType) pt2).getValueClass());
+ assertEquals(String.class, ((AttributeType) pt3).getValueClass());
+
+ //check feature
+ assertEquals(3, result.getPropertyValue("value1"));
+ assertEquals(3, result.getPropertyValue("renamed1"));
+ assertEquals("a literal", result.getPropertyValue("computed"));
+
+
+ }
}