package org.eclipse.core.internal.expressions;
import java.util.Collection;
import org.w3c.dom.Element;
import org.eclipse.core.expressions.EvaluationResult;
import org.eclipse.core.expressions.Expression;
import org.eclipse.core.expressions.ExpressionInfo;
import org.eclipse.core.expressions.ICountable;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
public class CountExpression extends Expression {
private static final int GREATER_THAN = 7;
private static final int LESS_THAN = 6;
private static final int ANY_NUMBER = 5;
private static final int EXACT = 4;
private static final int ONE_OR_MORE = 3;
private static final int NONE_OR_ONE = 2;
private static final int NONE = 1;
private static final int UNKNOWN = 0;
private static final int HASH_INITIAL= CountExpression.class.getName().hashCode();
private int fMode;
private int fSize;
public CountExpression(IConfigurationElement configElement) {
String size = configElement.getAttribute(ATT_VALUE);
initializeSize(size);
}
public CountExpression(Element element) {
String size = element.getAttribute(ATT_VALUE);
initializeSize(size.isEmpty() ? null : size);
}
public CountExpression(String size) {
initializeSize(size);
}
private void initializeSize(String size) {
if (size == null)
size= "*";
if (size.equals("*"))
fMode= ANY_NUMBER;
else if (size.equals("?"))
fMode= NONE_OR_ONE;
else if (size.equals("!"))
fMode= NONE;
else if (size.equals("+"))
fMode= ONE_OR_MORE;
else if (size.charAt(0) == '-' && size.charAt(size.length() - 1) == ')') {
try {
fMode = LESS_THAN;
fSize = Integer.parseInt(size.substring(1, size.length() - 1));
} catch (NumberFormatException e) {
fMode= UNKNOWN;
}
} else if (size.charAt(0) == '(' && size.charAt(size.length() - 1) == '-') {
try {
fMode = GREATER_THAN;
fSize = Integer.parseInt(size.substring(1, size.length() - 1));
} catch (NumberFormatException e) {
fMode= UNKNOWN;
}
} else {
try {
fSize= Integer.parseInt(size);
fMode= EXACT;
} catch (NumberFormatException e) {
fMode= UNKNOWN;
}
}
}
@Override
public EvaluationResult evaluate(IEvaluationContext context) throws CoreException {
Object var= context.getDefaultVariable();
int size;
if (var instanceof Collection) {
size= ((Collection<?>)var).size();
} else {
ICountable countable= Expressions.getAsICountable(var, this);
if (countable == null)
return EvaluationResult.NOT_LOADED;
size= countable.count();
}
switch (fMode) {
case UNKNOWN:
return EvaluationResult.FALSE;
case NONE:
return EvaluationResult.valueOf(size == 0);
case NONE_OR_ONE:
return EvaluationResult.valueOf(size == 0 || size == 1);
case ONE_OR_MORE:
return EvaluationResult.valueOf(size >= 1);
case EXACT:
return EvaluationResult.valueOf(fSize == size);
case ANY_NUMBER:
return EvaluationResult.TRUE;
case LESS_THAN:
return EvaluationResult.valueOf(size < fSize);
case GREATER_THAN:
return EvaluationResult.valueOf(size > fSize);
}
return EvaluationResult.FALSE;
}
@Override
public void collectExpressionInfo(ExpressionInfo info) {
info.markDefaultVariableAccessed();
}
@Override
public boolean equals(final Object object) {
if (!(object instanceof CountExpression))
return false;
final CountExpression that= (CountExpression)object;
return (this.fMode == that.fMode) && (this.fSize == that.fSize);
}
@Override
protected int computeHashCode() {
return HASH_INITIAL * HASH_FACTOR + fMode
* HASH_FACTOR + fSize;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder(getClass().getSimpleName());
builder.append(" [ size=");
builder.append(fSize);
builder.append(", mode: ");
builder.append(fMode);
switch (fMode) {
case GREATER_THAN:
builder.append(" GREATER_THAN");
break;
case LESS_THAN:
builder.append(" LESS_THAN");
break;
case ANY_NUMBER:
builder.append(" ANY_NUMBER");
break;
case EXACT:
builder.append(" EXACT");
break;
case ONE_OR_MORE:
builder.append(" ONE_OR_MORE");
break;
case NONE_OR_ONE:
builder.append(" NONE_OR_ONE");
break;
case NONE:
builder.append(" NONE");
break;
case UNKNOWN:
builder.append(" UNKNOWN");
break;
default:
break;
}
builder.append("]");
return builder.toString();
}
}