blob: 7992dda5b0fb65a66dd261e19342fe7e658b4178 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 Cloudsmith Inc. and others.
* 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:
* Cloudsmith Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.*;
import org.eclipse.equinox.internal.p2.ql.IRepeatableIterator;
import org.eclipse.equinox.internal.p2.ql.RepeatableIterator;
import org.eclipse.equinox.internal.p2.ql.parser.IParserConstants;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.Collector;
import org.eclipse.equinox.p2.ql.*;
/**
* The base class of the expression tree.
*/
abstract class Expression implements IExpression, IParserConstants {
static final Expression[] emptyArray = new Expression[0];
static Set asSet(Object val, boolean forcePrivateCopy) {
if (val == null)
throw new IllegalArgumentException("Cannot convert null into an set"); //$NON-NLS-1$
if (val instanceof IRepeatableIterator) {
Object provider = ((IRepeatableIterator) val).getIteratorProvider();
if (!forcePrivateCopy) {
if (provider instanceof Set)
return (Set) provider;
if (provider instanceof Collector)
return (Set) ((Collector) provider).toCollection();
}
if (provider instanceof Collection)
val = provider;
} else {
if (!forcePrivateCopy) {
if (val instanceof Set)
return (Set) val;
if (val instanceof Collector)
return (Set) ((Collector) val).toCollection();
}
}
HashSet result;
if (val instanceof Collection)
result = new HashSet((Collection) val);
else {
result = new HashSet();
Iterator iterator = RepeatableIterator.create(val);
while (iterator.hasNext())
result.add(iterator.next());
}
return result;
}
/**
* Let the visitor visit this instance and all expressions that this
* instance contains.
* @param visitor The visiting visitor.
* @return <code>true</code> if the visitor should continue visiting, <code>false</code> otherwise.
*/
public boolean accept(IExpressionVisitor visitor) {
return visitor.accept(this);
}
/**
* Evaluate this expression with given context and variables.
* @param context The evaluation context
* @return The result of the evaluation.
*/
public abstract Object evaluate(IEvaluationContext context);
public Iterator evaluateAsIterator(IEvaluationContext context) {
Object value = evaluate(context);
if (!(value instanceof Iterator))
value = RepeatableIterator.create(value);
return (Iterator) value;
}
/**
* Checks if the expression will make repeated requests for the 'everything' iterator.
* @return <code>true</code> if repeated requests will be made, <code>false</code> if not.
*/
public boolean needsRepeatedIterations() {
return countReferenceToEverything() > 1;
}
public final boolean needsTranslations() {
final boolean[] translationSupportNeeded = new boolean[] {false};
accept(new IExpressionVisitor() {
public boolean accept(IExpression expr) {
if (((Expression) expr).isReferencingTranslations()) {
translationSupportNeeded[0] = true;
return false;
}
return true;
}
});
return translationSupportNeeded[0];
}
public String toString() {
StringBuffer bld = new StringBuffer();
toString(bld);
return bld.toString();
}
public abstract void toString(StringBuffer bld);
static void appendOperand(StringBuffer bld, Expression operand, int priority) {
if (priority < operand.getPriority()) {
bld.append('(');
operand.toString(bld);
bld.append(')');
} else
operand.toString(bld);
}
void assertNotCollection(Expression expr, String usage) {
if (expr.isCollection())
throw new IllegalArgumentException("A collection cannot be used as " + usage + " in a " + getOperator()); //$NON-NLS-1$//$NON-NLS-2$
}
void assertNotBoolean(Expression expr, String usage) {
if (expr.isBoolean())
throw new IllegalArgumentException("A boolean cannot be used as " + usage + " in a " + getOperator()); //$NON-NLS-1$//$NON-NLS-2$
}
int countReferenceToEverything() {
return 0;
}
abstract String getOperator();
abstract int getPriority();
boolean isBoolean() {
return false;
}
boolean isCollection() {
return false;
}
boolean isElementBoolean() {
return false;
}
boolean isReferencingTranslations() {
return false;
}
boolean isPipeable() {
// TODO Auto-generated method stub
return false;
}
Expression pipeFrom(Expression nxt) {
// TODO Auto-generated method stub
return null;
}
boolean isElementCollection() {
// TODO Auto-generated method stub
return false;
}
}