blob: b1dc7e465a7824905324da0adb4fd378577792a9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014 Formal Mind GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ingo Weigelt - initial API and implementation
* Michael Jastram - adding SUPPORTED_OPERATIONS
******************************************************************************/
package org.eclipse.rmf.reqif10.search.filter;
import java.util.GregorianCalendar;
import org.eclipse.rmf.reqif10.AttributeDefinitionDate;
import org.eclipse.rmf.reqif10.AttributeValue;
import org.eclipse.rmf.reqif10.AttributeValueDate;
import org.eclipse.rmf.reqif10.SpecElementWithAttributes;
import org.eclipse.rmf.reqif10.common.util.ReqIF10Util;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
/**
* Filter for String-based values.
*/
public class DateFilter extends AbstractAttributeFilter {
public static enum InternalAttribute {
LAST_CHANGE
}
// TODO cross-check this with supported operators.
public static final ImmutableSet<Operator> SUPPORTED_OPERATORS = Sets
.immutableEnumSet(Operator.IS, Operator.IS_NOT,
Operator.BETWEEN, Operator.BEFORE, Operator.AFTER, Operator.IS_SET, Operator.IS_NOT_SET);
private Operator operator;
private GregorianCalendar filterValue1;
private GregorianCalendar filterValue2;
private AttributeDefinitionDate attributeDefinition;
private InternalAttribute internalAttribute;
private boolean isInternal;
/**
* Constructor used to create a filter for an {@link AttributeDefinitionDate}
*
* @param operator the filter operator to use
* @param value the value to match
* @param attributeDefinition the attributeDefinition that defines the value of a SpecObject that should be matched
* @param caseSensitive
*/
public DateFilter(Operator operator, GregorianCalendar value1, GregorianCalendar value2,
AttributeDefinitionDate attributeDefinition) {
this(operator, value1, value2, null, attributeDefinition);
this.isInternal = false;
if (null == attributeDefinition){
throw new IllegalArgumentException("AttributeDefinition can not be null");
}
}
/**
* Constructor used to create a filter for an {@link InternalAttribute}
*
* @param operator the filter operator to use
* @param value the value to match
* @param attributeDefinition the attributeDefinition that defines the value of a SpecObject that should be matched
* @param caseSensitive
*/
public DateFilter(Operator operator, GregorianCalendar value1, GregorianCalendar value2,
InternalAttribute internalFeature) {
this(operator, value1, value2, internalFeature, null);
this.isInternal = true;
if (null == internalFeature){
throw new IllegalArgumentException("AttributeDefinition can not be null");
}
}
private DateFilter(Operator operator, GregorianCalendar value1, GregorianCalendar value2,
InternalAttribute internalFeature, AttributeDefinitionDate attributeDefinition){
if (!SUPPORTED_OPERATORS.contains(operator)){
throw new IllegalArgumentException(
"This filter does not support the " + operator.toString()
+ " operation");
}
if (null == value1 && operator != Operator.IS_SET && operator != Operator.IS_NOT_SET ){
throw new IllegalArgumentException(
"Value can not be null");
}
if (operator.equals(Operator.BETWEEN) ){
if (value2 == null){
throw new IllegalArgumentException("Value2 can not be null when using the operator " + operator.toString());
}
}
this.operator = operator;
if (operator.equals(Operator.BETWEEN) && value1.after(value2)){
this.filterValue1 = value2;
this.filterValue2 = value1;
}else{
this.filterValue1 = value1;
this.filterValue2 = value2;
}
this.internalAttribute = internalFeature;
this.attributeDefinition = attributeDefinition;
}
@Override
public boolean match(SpecElementWithAttributes element) {
GregorianCalendar theValue;
// retrieve the value to check depending on this is a filter on an
// internal Attribute or a value
if (isInternal) {
theValue = getInternalAttributeValue(element);
} else {
AttributeValue attributeValue = ReqIF10Util.getAttributeValue(
element, attributeDefinition);
if (attributeValue == null || !((AttributeValueDate) attributeValue).isSetTheValue()){
theValue = null;
}else{
theValue = ((AttributeValueDate) attributeValue).getTheValue();
}
}
if (theValue == null){
theValue = getDefaultValue(element);
}
if (theValue == null){
switch (operator) {
case IS_NOT:
return true;
case IS:
case BEFORE:
case AFTER:
case BETWEEN:
return false;
default:
return super.match(element);
}
}
switch (operator) {
case IS:
return theValue.equals(filterValue1);
case IS_NOT:
return !theValue.equals(filterValue1);
case BEFORE:
return theValue.compareTo(filterValue1) < 0;
case AFTER:
return theValue.compareTo(filterValue1) > 0;
case BETWEEN:
return theValue.compareTo(filterValue1) >= 0 && theValue.compareTo(filterValue2) <= 0;
default:
return super.match(element);
}
}
private GregorianCalendar getDefaultValue(SpecElementWithAttributes element) {
if (!AbstractAttributeFilter.isSetAttribute(element, attributeDefinition)){
return null;
}
if (!isInternal && attributeDefinition instanceof AttributeDefinitionDate) {
AttributeDefinitionDate ad = (AttributeDefinitionDate) attributeDefinition;
return ad.isSetDefaultValue() ? ad.getDefaultValue().getTheValue() : null;
}
if (isInternal){
// What is the default Value for LAST_CHANGE
// I am not even sure if a non set LAST_CHANGE is valid
return null;
}
throw new IllegalStateException("Expected an AttributeDefinitionString as attribute but found " + attributeDefinition.getClass());
}
@Override
public Object getAttribute() {
return isInternal ? internalAttribute : attributeDefinition;
}
public Operator getOperator() {
return operator;
}
public GregorianCalendar getFilterValue1() {
return filterValue1;
}
public GregorianCalendar getFilterValue2() {
return filterValue2;
}
@Override
public ImmutableSet<Operator> getSupportedOperators() {
return SUPPORTED_OPERATORS;
}
@Override
protected GregorianCalendar getInternalAttributeValue(SpecElementWithAttributes element) {
if (internalAttribute.equals(InternalAttribute.LAST_CHANGE)){
if (!element.isSetLastChange()){
return null;
}
return element.getLastChange();
}else{
throw new IllegalArgumentException(internalAttribute + " is not supported by this feature");
}
}
}