/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2011, 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.data.efeature.tests.unit.conditions;
import java.util.Date;
import java.util.Set;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.query.conditions.Condition;
import org.geotools.data.efeature.EFeatureUtils;
import org.geotools.data.efeature.query.EFeatureEncoderException;
import org.geotools.data.efeature.tests.EFeatureData;
import org.geotools.data.efeature.tests.EFeatureTestsFactory;
import org.geotools.data.efeature.tests.EFeatureTestsPackage;
import com.vividsolutions.jts.geom.Geometry;
/**
* @author kengu - 14. juni 2011
*
*/
public abstract class AbstractEAttributeValueTest extends AbstractEAttributeFilterTest<EFeatureData<Object, Geometry>> {
// ---------------------------------------------
// Unary operators
// ---------------------------------------------
/** The {@literal IS NULL} operator. */
public static final int IS_NULL = 1;
// ---------------------------------------------
// Binary operators
// ---------------------------------------------
/** The {@literal =} operator. */
public static final int EQUAL_TO = 2;
/** The {@literal !=} operator. */
public static final int NOT_EQUAL_TO = 4;
/** The {@literal <} operator. */
public static final int LESS_THAN = 8;
/** The {@literal <=} operator. */
public static final int LESS_THAN_OR_EQUAL_TO = 16;
/** The {@literal >} operator. */
public static final int GREATER_THAN = 32;
/** The {@literal >=} operator. */
public static final int GREATER_THAN_OR_EQUAL_TO = 64;
/** The {@literal = IS LIKE} operator. */
public static final int IS_LIKE = 128;
// ---------------------------------------------
// Ternary operators
// ---------------------------------------------
/** The {@literal BETWEEN} operator. */
public static final int BETWEEN = 256;
/** The {@literal OUTSIDE} operator. */
public static final int OUTSIDE = 512;
// ---------------------------------------------
// N-ary operators
// ---------------------------------------------
/** The {@literal = IS ID} operator. */
public static final int IS_ID = 1024;
// -----------------------------------------------------
// Operation sets group on value type
// -----------------------------------------------------
/** Booleans: {@link #EQUAL_TO} and {@link #NOT_EQUAL_TO} only */
public static final int BOOLEAN_OPS = EQUAL_TO | NOT_EQUAL_TO;
/** Numbers: All except {@link #IS_LIKE} and {@link #UNARY_OPS}*/
public static final int NUMBER_OPS = EQUAL_TO | NOT_EQUAL_TO | LESS_THAN | LESS_THAN_OR_EQUAL_TO
| GREATER_THAN | GREATER_THAN_OR_EQUAL_TO | BETWEEN | OUTSIDE;
/** Characters: All except {@link #IS_LIKE} and {@link #UNARY_OPS} */
public static final int CHARACTER_OPS = NUMBER_OPS;
/** Dates: All except {@link #IS_LIKE} and {@link #UNARY_OPS} */
public static final int DATE_OPS = NUMBER_OPS;
/** Strings: All operations */
public static final int STRING_OPS = NUMBER_OPS | IS_LIKE;
// -----------------------------------------------------
// Cached tests specifications
// -----------------------------------------------------
/**
* {@link #IS_NULL} operation test specification.
* <p>
* This is a unary operation, only requiring a single test value (no filter value).
*/
public static final Tests IS_NULL_TESTS = new Tests(nameOf(IS_NULL),
new Pass(true, 0));
/**
* {@link #EQUAL_TO} operation test specification.
* <p>
* This is a binary operation requiring two equal values
*/
public static final Tests EQUAL_TO_TESTS = new Tests(nameOf(EQUAL_TO),
new Pass(true,0,0));
/**
* {@link #NOT_EQUAL_TO} operation test specification.
* <p>
* This is a binary operation, requiring two unequal values
*/
public static final Tests NOT_EQUAL_TO_TESTS = new Tests(nameOf(NOT_EQUAL_TO),
new Pass(true,0,1));
/**
* {@link #LESS_THAN} operation test specification.
* <p>
* This is a binary operation requiring two values, one less than the other
*/
public static final Tests LESS_THAN_TESTS = new Tests(nameOf(LESS_THAN),
new Pass(true,0,1));
/**
* {@link #LESS_THAN_OR_EQUAL_TO} operation test specification.
* <p>
* This is binary operation requiring two passes. First pass verifies
* {@link #EQUAL_TO}, requiring one unique value. The second pass verifies
* {@link #LESS_THAN}, requiring two values, one less than the other.
*/
public static final Tests LESS_THAN_OR_EQUAL_TO_TESTS = new Tests(
nameOf(LESS_THAN_OR_EQUAL_TO), EQUAL_TO_TESTS, LESS_THAN_TESTS);
/**
* {@link #GREATER_THAN} operation test specification.
* <p>
* This is a binary operation requiring two values, one greater than the other
*/
public static final Tests GREATER_THAN_TESTS = new Tests(nameOf(GREATER_THAN),
new Pass(true,1,0));
/**
* {@link #GREATER_THAN_OR_EQUAL_TO} operation test specification.
* <p>
* This is binary operation requiring two passes. First pass verifies
* {@link #EQUAL_TO}, requiring one unique value. The second pass verifies
* {@link #GREATER_THAN}, requiring two values, one greater than the other.
*/
public static final Tests GREATER_THAN_OR_EQUAL_TO_TESTS = new Tests(
nameOf(GREATER_THAN_OR_EQUAL_TO), EQUAL_TO_TESTS, GREATER_THAN_TESTS);
/**
* {@link #IS_LIKE} operation test specification.
* <p>
* This is a binary operation requiring two values, where one match the other.
*/
public static final Tests IS_LIKE_TESTS = new Tests(nameOf(IS_LIKE),
new Pass(true,0,3));
/**
* {@link #BETWEEN} operation test specification.
* <p>
* This is a ternary operation requiring three values: two defining a range,
* and the last inside this range.
*/
public static final Tests BETWEEN_TESTS = new Tests(nameOf(BETWEEN),
new Pass(true,2,0,1));
/**
* {@link #OUTSIDE} operation test specification.
* <p>
* This is a ternary operation requiring three values: two defining a range,
* and the last outside this range.
*/
public static final Tests OUTSIDE_TESTS = new Tests(nameOf(OUTSIDE),
new Pass(true,0,2,1));
/**
* {@link #IS_ID} operation test specification.
* <p>
* This is a n-ary operation requiring N values, N>0.
*/
public static final Tests IS_ID_TESTS = new Tests(nameOf(IS_ID),
new Pass(true,2,ALL));
// -----------------------------------------------------
// Cached tests
// -----------------------------------------------------
public static final Tests[] TESTS = new Tests[]{
//
// Unary operation tests
//
IS_NULL_TESTS,
//
// Binary operation tests
//
EQUAL_TO_TESTS,NOT_EQUAL_TO_TESTS,
LESS_THAN_TESTS,LESS_THAN_OR_EQUAL_TO_TESTS,
GREATER_THAN_TESTS, GREATER_THAN_OR_EQUAL_TO_TESTS,
IS_LIKE_TESTS,
//
// Ternary operation tests
//
BETWEEN_TESTS,OUTSIDE_TESTS,
//
// N-ary operation tests
//
IS_ID_TESTS
};
// -----------------------------------------------------
// Cached test values
// -----------------------------------------------------
/**
* Cached <code>null</code> values
*/
protected static final Values NULLS[] = new Values[]{
new Values(IS_NULL,Object.class,null,null,null) };
/**
* Cached boolean values
*/
protected static final Values BOOLEANS[] = new Values[]{
new Values(BOOLEAN_OPS,Boolean.class,Boolean.TRUE,Boolean.FALSE,Boolean.FALSE) };
/**
* Cached primitive values
*/
protected static final Values NUMBERS[] = new Values[]{
new Values(NUMBER_OPS,Integer.class,Integer.MIN_VALUE,Integer.MAX_VALUE,new Integer(1)),
new Values(NUMBER_OPS,Double.class,Double.MIN_VALUE, Double.MAX_VALUE, new Double(1.0)),
new Values(NUMBER_OPS,Float.class,Float.MIN_VALUE, Float.MAX_VALUE, new Float(1.0F)),
new Values(NUMBER_OPS,Byte.class,Byte.MIN_VALUE, Byte.MAX_VALUE, new Byte((byte)1)),
new Values(NUMBER_OPS,Short.class,Short.MIN_VALUE, Short.MAX_VALUE, new Short((short)1)),
new Values(NUMBER_OPS,Long.class,Long.MIN_VALUE, Long.MAX_VALUE, new Long(1L)) };
/**
* Cached date values
*/
protected static final Values DATES[] = new Values[]{
new Values(DATE_OPS,Integer.class, new Date(Long.MIN_VALUE), new Date(Long.MAX_VALUE), new Date(0)) };
/**
* Cached character values
*/
protected static final Values CHARACTERS[] = new Values[]{
new Values(CHARACTER_OPS,Character.class,Character.MIN_VALUE,Character.MAX_VALUE,new Character((char)0)) };
/**
* Cached string values
*/
protected static final Values STRINGS[] = new Values[]{
new Values(STRING_OPS,String.class,"ax","az","ay","a*") };
/**
* Cached ID values
*/
public static final Values IDS[] = new Values[]{
new Values(IS_ID,Set.class,"F1","F100","F50") };
/**
* Concatenation of all cached values
*/
protected static final Values VALUES[] =
EFeatureUtils.concat(Values.class,
NULLS, BOOLEANS, NUMBERS, DATES, CHARACTERS, STRINGS, IDS);
/**
* Cached {@link EAttribute} reference
*/
protected static final EAttribute eAttribute = EFeatureTestsPackage.eINSTANCE.getEFeatureData_Attribute();
// -----------------------------------------------------
// AbstractEAttributeValueTest instance members
// -----------------------------------------------------
/**
* Operation ID
*/
protected final int operationID;
/**
* Operation index
*/
protected final int operationIndex;
// -----------------------------------------------------
// Constructors
// -----------------------------------------------------
/**
* @param name
*/
public AbstractEAttributeValueTest(String name, int operationID) {
//
// Forward to AbstractEAttributeFilterTest
//
super(name);
//
// Save operation ID
//
this.operationID = operationID;
//
// Map operation ID to field index
//
this.operationIndex = indexOf(operationID);
}
// -----------------------------------------------------
// AbstractEAttributeFilterTest implementation
// -----------------------------------------------------
@Override
protected final EFeatureData<Object, Geometry> createFixture() {
//
// Create instance using the factory
//
return EFeatureTestsFactory.eINSTANCE.<Object, Geometry>createEFeatureData();
}
@Override
protected String getType(int value) {
return VALUES[value].getType().getSimpleName();
}
@Override
protected String getOperationName() {
return TESTS[operationIndex].name;
}
@Override
protected boolean isOperand(int value) {
return VALUES[value].isOperand(operationID);
}
@Override
protected int getPassCount() {
return TESTS[operationIndex].passes.length;
}
@Override
protected int getValueCount() {
return VALUES.length;
}
@Override
protected boolean expect(int pass) {
return TESTS[operationIndex].passes[pass].success;
}
@Override
protected final Object getFilter(int value, int pass) {
return VALUES[value].getFilter(TESTS[operationIndex].passes[pass]);
}
@Override
protected final Object getTest(int value, int pass) {
return VALUES[value].getTest(TESTS[operationIndex].passes[pass]);
}
@Override
protected final void updateFixture(EFeatureData<Object, Geometry> eFixture, int value, int pass) {
//
// Update values
//
eFixture.setAttribute(getTest(value, pass));
}
@Override
protected final Condition createCondition(int value, int pass) throws EFeatureEncoderException {
return createCondition(value, getFilter(value, pass));
}
// -----------------------------------------------------
// AbstractEAttributeValueTest implementation methods
// -----------------------------------------------------
protected abstract Condition createCondition(int value, Object filter) throws EFeatureEncoderException;
// -----------------------------------------------------
// Helper methods
// -----------------------------------------------------
protected static final String nameOf(int operation) throws IllegalArgumentException {
return nameOf(operation,AbstractEAttributeValueTest.class.getFields());
}
}