blob: 381d1e027ee9ac36efa6e24b650b434b446b2b87 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2008, 2009 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation.
* Ian Phillips - additional expressions support ( "-N)", "(N-" ).
*******************************************************************************/
package org.eclipse.core.expressions;
import java.util.Collection;
import org.w3c.dom.Element;
import org.eclipse.core.internal.expressions.Expressions;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
/**
* @since 3.7
*/
public class CountExpression extends Expression {
private static final int GREATER_THAN = 7; // (N-
private static final int LESS_THAN = 6; // -N)
private static final int ANY_NUMBER = 5; // *
private static final int EXACT = 4; // N
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;
/**
* The seed for the hash code for all count expressions.
*/
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= "*"; //$NON-NLS-1$
if ("*".equals(size)) //$NON-NLS-1$
fMode= ANY_NUMBER;
else if ("?".equals(size)) //$NON-NLS-1$
fMode= NONE_OR_ONE;
else if ("!".equals(size)) //$NON-NLS-1$
fMode= NONE;
else if ("+".equals(size)) //$NON-NLS-1$
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="); //$NON-NLS-1$
builder.append(fSize);
builder.append(", mode: "); //$NON-NLS-1$
builder.append(fMode);
switch (fMode) {
case GREATER_THAN:
builder.append(" GREATER_THAN"); //$NON-NLS-1$
break;
case LESS_THAN:
builder.append(" LESS_THAN"); //$NON-NLS-1$ // -N)
break;
case ANY_NUMBER:
builder.append(" ANY_NUMBER"); //$NON-NLS-1$ // *
break;
case EXACT:
builder.append(" EXACT"); //$NON-NLS-1$ // N
break;
case ONE_OR_MORE:
builder.append(" ONE_OR_MORE"); //$NON-NLS-1$ // +
break;
case NONE_OR_ONE:
builder.append(" NONE_OR_ONE"); //$NON-NLS-1$ // ?
break;
case NONE:
builder.append(" NONE"); //$NON-NLS-1$ // !
break;
case UNKNOWN:
builder.append(" UNKNOWN"); //$NON-NLS-1$ ;
break;
default:
break;
}
builder.append("]"); //$NON-NLS-1$
return builder.toString();
}
}