blob: 746a680db80a7985b06210f607929f28cdf84681 [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;
import java.util.*;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.Collector;
/**
* The base class of the expression tree.
*/
public abstract class Expression {
public interface Visitor {
/**
* The method that will be called for each expression that is
* visited.
* @param expression The expression that the visitor visits.
* @return <code>true</code> to continue visiting other expressions or
* <code>false</code> to break out.
*/
boolean accept(Expression expression);
}
public 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(Visitor visitor) {
return visitor.accept(this);
}
/**
* Evaluate this expression in the given context.
* @param scope TODO
* @return The result of the evaluation.
*/
public abstract Object evaluate(ExpressionContext context, VariableScope scope);
public Iterator evaluateAsIterator(ExpressionContext context, VariableScope scope) {
Object value = evaluate(context, scope);
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 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);
}
int countReferenceToEverything() {
return 0;
}
abstract int getPriority();
}