Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hallgren2010-01-13 12:59:44 +0000
committerThomas Hallgren2010-01-13 12:59:44 +0000
commit62eb06de9e9564748a3048f99f307c32a984b214 (patch)
tree28d62c65462ccffbb66b32f133eba01430d51da4 /bundles/org.eclipse.equinox.p2.ql
parent81026456fefe243425035fa2f1091d6810eff8e3 (diff)
downloadrt.equinox.p2-62eb06de9e9564748a3048f99f307c32a984b214.tar.gz
rt.equinox.p2-62eb06de9e9564748a3048f99f307c32a984b214.tar.xz
rt.equinox.p2-62eb06de9e9564748a3048f99f307c32a984b214.zip
298604 : Split the p2QL into one core simple Expression part and one Query part
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.ql')
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/.settings/.api_filters28
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/META-INF/MANIFEST.MF3
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/CapabilityIndex.java70
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/Everything.java4
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/FlattenIterator.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/IRepeatableIterator.java25
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/MultiVariableContext.java51
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/ParameterContext.java44
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/QueryContext.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/RepeatableIterator.java237
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/SingleVariableContext.java46
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/All.java46
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/And.java73
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Array.java44
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Assignment.java23
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/At.java70
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Binary.java47
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/BooleanFunction.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/CapabilityIndexFunction.java57
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ClassFunction.java10
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Collect.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/CollectionFilter.java73
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Compare.java71
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Condition.java42
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Constant.java94
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ContextExpression.java63
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/CurryedLambdaExpression.java (renamed from bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/LambdaExpression.java)84
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Equals.java60
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Exists.java46
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Expression.java174
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/FilterFunction.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/First.java24
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Flatten.java5
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Function.java58
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/IQLConstants.java30
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Intersect.java53
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Latest.java5
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Limit.java32
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/MatchExpression.java64
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Matches.java108
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Member.java197
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/NAry.java87
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Not.java42
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Or.java71
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Parameter.java64
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/QLFactory.java (renamed from bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ExpressionFactory.java)152
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/QLUtil.java96
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/RangeFunction.java7
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Select.java22
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/SetFunction.java7
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Traverse.java30
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Unary.java48
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/UnaryCollectionFilter.java28
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Union.java50
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Unique.java35
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Variable.java87
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/VersionFunction.java7
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/WrappedIQuery.java14
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/ExpressionParser.java847
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/IParserConstants.java75
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/QLParser.java384
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IContextExpression.java33
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IEvaluationContext.java47
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpression.java95
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpressionVisitor.java25
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IMatchExpression.java43
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLExpression.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLFactory.java (renamed from bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpressionFactory.java)162
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLParser.java (renamed from bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpressionParser.java)18
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QL.java12
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLContextQuery.java24
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLMatchQuery.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLQuery.java8
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QueryResult.java4
74 files changed, 1205 insertions, 3673 deletions
diff --git a/bundles/org.eclipse.equinox.p2.ql/.settings/.api_filters b/bundles/org.eclipse.equinox.p2.ql/.settings/.api_filters
new file mode 100644
index 000000000..dfbf53e91
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ql/.settings/.api_filters
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.equinox.p2.ql" version="2">
+ <resource path="src/org/eclipse/equinox/internal/p2/ql/expression/WrappedIQuery.java" type="org.eclipse.equinox.internal.p2.ql.expression.WrappedIQuery">
+ <filter id="640712815">
+ <message_arguments>
+ <message_argument value="IMatchQuery&lt;T&gt;"/>
+ <message_argument value="WrappedIQuery"/>
+ <message_argument value="isMatch(T)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/equinox/p2/ql/QLMatchQuery.java" type="org.eclipse.equinox.p2.ql.QLMatchQuery">
+ <filter id="574619656">
+ <message_arguments>
+ <message_argument value="IMatchQuery&lt;T&gt;"/>
+ <message_argument value="QLMatchQuery&lt;T&gt;"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/equinox/p2/ql/QLQuery.java" type="org.eclipse.equinox.p2.ql.QLQuery">
+ <filter id="574619656">
+ <message_arguments>
+ <message_argument value="IQuery&lt;T&gt;"/>
+ <message_argument value="QLQuery&lt;T&gt;"/>
+ </message_arguments>
+ </filter>
+ </resource>
+</component>
diff --git a/bundles/org.eclipse.equinox.p2.ql/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.ql/META-INF/MANIFEST.MF
index da22b4c74..8eb989b7d 100644
--- a/bundles/org.eclipse.equinox.p2.ql/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.ql/META-INF/MANIFEST.MF
@@ -12,9 +12,12 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5,
Bundle-ActivationPolicy: lazy
Import-Package: org.eclipse.equinox.internal.p2.core.helpers,
org.eclipse.equinox.internal.p2.metadata,
+ org.eclipse.equinox.internal.p2.metadata.expression,
+ org.eclipse.equinox.internal.p2.metadata.expression.parser,
org.eclipse.equinox.internal.p2.query,
org.eclipse.equinox.internal.provisional.p2.metadata,
org.eclipse.equinox.p2.metadata,
+ org.eclipse.equinox.p2.metadata.expression,
org.eclipse.equinox.p2.metadata.query,
org.eclipse.equinox.p2.query,
org.eclipse.equinox.p2.repository.artifact,
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/CapabilityIndex.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/CapabilityIndex.java
index e6b3f74bf..ccb132be1 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/CapabilityIndex.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/CapabilityIndex.java
@@ -23,34 +23,24 @@ public class CapabilityIndex implements ICapabilityIndex {
private final Map<String, Object> capabilityMap;
- private static class IUCapability {
- final IInstallableUnit iu;
- final IProvidedCapability capability;
-
- IUCapability(IInstallableUnit iu, IProvidedCapability capability) {
- this.iu = iu;
- this.capability = capability;
- }
- }
-
+ @SuppressWarnings("unchecked")
public CapabilityIndex(Iterator<IInstallableUnit> itor) {
HashMap<String, Object> index = new HashMap<String, Object>();
while (itor.hasNext()) {
IInstallableUnit iu = itor.next();
Collection<IProvidedCapability> pcs = iu.getProvidedCapabilities();
for (IProvidedCapability pc : pcs) {
- IUCapability iuCap = new IUCapability(iu, pc);
String name = pc.getName();
- Object prev = index.put(name, iuCap);
+ Object prev = index.put(name, iu);
if (prev != null) {
- ArrayList<IUCapability> lst;
+ ArrayList<IInstallableUnit> lst;
if (prev instanceof ArrayList<?>)
- lst = (ArrayList<IUCapability>) prev;
+ lst = (ArrayList<IInstallableUnit>) prev;
else {
- lst = new ArrayList<IUCapability>(4);
- lst.add((IUCapability) prev);
+ lst = new ArrayList<IInstallableUnit>(4);
+ lst.add((IInstallableUnit) prev);
}
- lst.add(iuCap);
+ lst.add(iu);
index.put(name, lst);
}
}
@@ -65,7 +55,7 @@ public class CapabilityIndex implements ICapabilityIndex {
List<IInstallableUnit> collector = new ArrayList<IInstallableUnit>();
do {
IRequirement nxt = requirements.next();
- collectMatchingIUs((IRequiredCapability) nxt, collector);
+ collectMatchingIUs(nxt, collector);
} while (requirements.hasNext());
return collector.iterator();
}
@@ -85,22 +75,22 @@ public class CapabilityIndex implements ICapabilityIndex {
private void collectMatchingIUs(IRequirement requirement, Collection<IInstallableUnit> collector) {
if (!(requirement instanceof IRequiredCapability))
return;
- IRequiredCapability rc = (IRequiredCapability) requirement;
- Object v = capabilityMap.get(rc.getName());
+ Object v = capabilityMap.get(((IRequiredCapability) requirement).getName());
if (v == null)
return;
- if (v instanceof IUCapability) {
- IUCapability iuc = (IUCapability) v;
- if (iuc.capability.satisfies(requirement))
- collector.add(iuc.iu);
+ if (v instanceof IInstallableUnit) {
+ IInstallableUnit iu = (IInstallableUnit) v;
+ if (iu.satisfies(requirement))
+ collector.add(iu);
} else {
- List<IUCapability> iucs = (List<IUCapability>) v;
- int idx = iucs.size();
+ @SuppressWarnings("unchecked")
+ List<IInstallableUnit> ius = (List<IInstallableUnit>) v;
+ int idx = ius.size();
while (--idx >= 0) {
- IUCapability iuc = iucs.get(idx);
- if (iuc.capability.satisfies(requirement))
- collector.add(iuc.iu);
+ IInstallableUnit iu = ius.get(idx);
+ if (iu.satisfies(requirement))
+ collector.add(iu);
}
}
}
@@ -109,28 +99,28 @@ public class CapabilityIndex implements ICapabilityIndex {
if (!(requirement instanceof IRequiredCapability))
return CollectionUtils.emptySet();
- IRequiredCapability rc = (IRequiredCapability) requirement;
- Object v = capabilityMap.get(rc.getName());
+ Object v = capabilityMap.get(((IRequiredCapability) requirement).getName());
if (v == null)
return CollectionUtils.emptySet();
Set<IInstallableUnit> retained = null;
- if (v instanceof IUCapability) {
- IUCapability iuc = (IUCapability) v;
- if (iuc.capability.satisfies(requirement) && collector.contains(iuc.iu)) {
+ if (v instanceof IInstallableUnit) {
+ IInstallableUnit iu = (IInstallableUnit) v;
+ if (iu.satisfies(requirement) && collector.contains(iu)) {
if (retained == null)
retained = new HashSet<IInstallableUnit>();
- retained.add(iuc.iu);
+ retained.add(iu);
}
} else {
- List<IUCapability> iucs = (List<IUCapability>) v;
- int idx = iucs.size();
+ @SuppressWarnings("unchecked")
+ List<IInstallableUnit> ius = (List<IInstallableUnit>) v;
+ int idx = ius.size();
while (--idx >= 0) {
- IUCapability iuc = iucs.get(idx);
- if (iuc.capability.satisfies(requirement) && collector.contains(iuc.iu)) {
+ IInstallableUnit iu = ius.get(idx);
+ if (iu.satisfies(requirement) && collector.contains(iu)) {
if (retained == null)
retained = new HashSet<IInstallableUnit>();
- retained.add(iuc.iu);
+ retained.add(iu);
}
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/Everything.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/Everything.java
index 4f3fc819b..d127bf72a 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/Everything.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/Everything.java
@@ -10,6 +10,10 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql;
+import org.eclipse.equinox.internal.p2.metadata.expression.IRepeatableIterator;
+
+import org.eclipse.equinox.internal.p2.metadata.expression.RepeatableIterator;
+
import java.util.Collection;
import java.util.Iterator;
import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/FlattenIterator.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/FlattenIterator.java
index f41e20c1b..179a36613 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/FlattenIterator.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/FlattenIterator.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql;
+import org.eclipse.equinox.internal.p2.metadata.expression.RepeatableIterator;
+
import java.util.Iterator;
import java.util.NoSuchElementException;
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/IRepeatableIterator.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/IRepeatableIterator.java
deleted file mode 100644
index 1f8fa8655..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/IRepeatableIterator.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*******************************************************************************
- * 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.Iterator;
-
-public interface IRepeatableIterator<T> extends Iterator<T> {
- /**
- * Returns a copy that will iterate over the same elements
- * as this iterator. The contents or position of this iterator
- * is left unchanged.
- * @return A re-initialized copy of this iterator.
- */
- IRepeatableIterator<T> getCopy();
-
- Object getIteratorProvider();
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/MultiVariableContext.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/MultiVariableContext.java
deleted file mode 100644
index 8218e76d6..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/MultiVariableContext.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*******************************************************************************
- * 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 org.eclipse.equinox.p2.ql.IEvaluationContext;
-import org.eclipse.equinox.p2.ql.IExpression;
-
-public final class MultiVariableContext implements IEvaluationContext {
- private final IEvaluationContext parentContext;
-
- private final Object[] values;
-
- public MultiVariableContext(IEvaluationContext parentContext, IExpression[] variables) {
- this.parentContext = parentContext;
- values = new Object[variables.length * 2];
- for (int idx = 0, ndx = 0; ndx < variables.length; ++ndx, idx += 2)
- values[idx] = variables[ndx];
- }
-
- public Object getParameter(int position) {
- return parentContext.getParameter(position);
- }
-
- public Object getParameter(String key) {
- return parentContext.getParameter(key);
- }
-
- public Object getValue(IExpression variable) {
- for (int idx = 0; idx < values.length; ++idx)
- if (values[idx++] == variable)
- return values[idx];
- return parentContext.getValue(variable);
- }
-
- public void setValue(IExpression variable, Object value) {
- for (int idx = 0; idx < values.length; ++idx)
- if (values[idx++] == variable) {
- values[idx] = value;
- return;
- }
- parentContext.setValue(variable, value);
- }
-} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/ParameterContext.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/ParameterContext.java
deleted file mode 100644
index 653c103ad..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/ParameterContext.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*******************************************************************************
- * 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.Map;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
-import org.eclipse.equinox.p2.ql.IExpression;
-
-/**
- * The immutable top level context used when evaluating an expression.
- */
-public final class ParameterContext implements IEvaluationContext {
- private static final Object[] noParameters = new Object[0];
-
- private final Object[] parameters;
-
- public ParameterContext(Object[] parameters) {
- this.parameters = parameters == null ? noParameters : parameters;
- }
-
- public Object getParameter(int position) {
- return parameters[position];
- }
-
- public Object getParameter(String key) {
- return parameters.length == 1 && parameters[0] instanceof Map<?, ?> ? ((Map<?, ?>) parameters[0]).get(key) : null;
- }
-
- public Object getValue(IExpression variable) {
- throw new IllegalArgumentException("No such variable: " + variable); //$NON-NLS-1$
- }
-
- public void setValue(IExpression variable, Object value) {
- throw new IllegalArgumentException("No such variable: " + variable); //$NON-NLS-1$
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/QueryContext.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/QueryContext.java
index 2f82b3f25..0f8f63cf2 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/QueryContext.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/QueryContext.java
@@ -3,6 +3,8 @@ package org.eclipse.equinox.internal.p2.ql;
import java.util.*;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.p2.metadata.expression.IRepeatableIterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.RepeatableIterator;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.ql.IQueryContext;
import org.eclipse.equinox.p2.ql.ITranslationSupport;
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/RepeatableIterator.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/RepeatableIterator.java
deleted file mode 100644
index 7c1a83500..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/RepeatableIterator.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*******************************************************************************
- * 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.p2.query.IQueryResult;
-
-public class RepeatableIterator<T> implements IRepeatableIterator<T> {
- private final List<T> values;
- private int position = -1;
-
- @SuppressWarnings("unchecked")
- public static <T> IRepeatableIterator<T> create(Object unknown) {
- if (unknown.getClass().isArray())
- return create((T[]) unknown);
- if (unknown instanceof Iterator<?>)
- return create((Iterator<T>) unknown);
- if (unknown instanceof List<?>)
- return create((List<T>) unknown);
- if (unknown instanceof Collection<?>)
- return create((Collection<T>) unknown);
- if (unknown instanceof Map<?, ?>)
- return create((Set<T>) ((Map<?, ?>) unknown).entrySet());
- if (unknown instanceof IQueryResult<?>)
- return create((IQueryResult<T>) unknown);
- throw new IllegalArgumentException("Cannot convert a " + unknown.getClass().getName() + " into an iterator"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- public static <T> IRepeatableIterator<T> create(Iterator<T> iterator) {
- return iterator instanceof IRepeatableIterator<?> ? ((IRepeatableIterator<T>) iterator).getCopy() : new ElementRetainingIterator<T>(iterator);
- }
-
- public static <T> IRepeatableIterator<T> create(List<T> values) {
- return new RepeatableIterator<T>(values);
- }
-
- public static <T> IRepeatableIterator<T> create(Collection<T> values) {
- return new CollectionIterator<T>(values);
- }
-
- public static <T> IRepeatableIterator<T> create(IQueryResult<T> values) {
- return new QueryResultIterator<T>(values);
- }
-
- public static <T> IRepeatableIterator<T> create(T[] values) {
- return new ArrayIterator<T>(values);
- }
-
- RepeatableIterator(List<T> values) {
- this.values = values;
- }
-
- public IRepeatableIterator<T> getCopy() {
- return new RepeatableIterator<T>(values);
- }
-
- public boolean hasNext() {
- return position + 1 < values.size();
- }
-
- public T next() {
- if (++position == values.size()) {
- --position;
- throw new NoSuchElementException();
- }
- return values.get(position);
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- public Object getIteratorProvider() {
- return values;
- }
-
- void setPosition(int position) {
- this.position = position;
- }
-
- List<T> getValues() {
- return values;
- }
-
- static class ArrayIterator<T> implements IRepeatableIterator<T> {
- private final T[] array;
- private int position = -1;
-
- public ArrayIterator(T[] array) {
- this.array = array;
- }
-
- public Object getIteratorProvider() {
- return array;
- }
-
- public boolean hasNext() {
- return position + 1 < array.length;
- }
-
- public T next() {
- if (++position >= array.length)
- throw new NoSuchElementException();
- return array[position];
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- public IRepeatableIterator<T> getCopy() {
- return new ArrayIterator<T>(array);
- }
- }
-
- static class CollectionIterator<T> implements IRepeatableIterator<T> {
- private final Collection<T> collection;
-
- private final Iterator<T> iterator;
-
- CollectionIterator(Collection<T> collection) {
- this.collection = collection;
- this.iterator = collection.iterator();
- }
-
- public IRepeatableIterator<T> getCopy() {
- return new CollectionIterator<T>(collection);
- }
-
- public Object getIteratorProvider() {
- return collection;
- }
-
- public boolean hasNext() {
- return iterator.hasNext();
- }
-
- public T next() {
- return iterator.next();
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- static class QueryResultIterator<T> implements IRepeatableIterator<T> {
- private final IQueryResult<T> queryResult;
-
- private final Iterator<T> iterator;
-
- QueryResultIterator(IQueryResult<T> queryResult) {
- this.queryResult = queryResult;
- this.iterator = queryResult.iterator();
- }
-
- public IRepeatableIterator<T> getCopy() {
- return new QueryResultIterator<T>(queryResult);
- }
-
- public Object getIteratorProvider() {
- return queryResult;
- }
-
- public boolean hasNext() {
- return iterator.hasNext();
- }
-
- public T next() {
- return iterator.next();
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- static class ElementRetainingIterator<T> extends RepeatableIterator<T> {
-
- private Iterator<T> innerIterator;
-
- ElementRetainingIterator(Iterator<T> iterator) {
- super(new ArrayList<T>());
- innerIterator = iterator;
- }
-
- public synchronized boolean hasNext() {
- if (innerIterator != null) {
- if (innerIterator.hasNext())
- return true;
- innerIterator = null;
- setPosition(getValues().size());
- }
- return super.hasNext();
- }
-
- public synchronized T next() {
- if (innerIterator != null) {
- T val = innerIterator.next();
- getValues().add(val);
- return val;
- }
- return super.next();
- }
-
- public synchronized IRepeatableIterator<T> getCopy() {
- // If the current iterator still exists, we must exhaust it first
- //
- exhaustInnerIterator();
- return super.getCopy();
- }
-
- public synchronized Object getIteratorProvider() {
- exhaustInnerIterator();
- return super.getIteratorProvider();
- }
-
- private void exhaustInnerIterator() {
- if (innerIterator != null) {
- List<T> values = getValues();
- int savePos = values.size() - 1;
- while (innerIterator.hasNext())
- values.add(innerIterator.next());
- innerIterator = null;
- setPosition(savePos);
- }
- }
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/SingleVariableContext.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/SingleVariableContext.java
deleted file mode 100644
index 5d57b69c3..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/SingleVariableContext.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*******************************************************************************
- * 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 org.eclipse.equinox.p2.ql.IEvaluationContext;
-import org.eclipse.equinox.p2.ql.IExpression;
-
-public final class SingleVariableContext implements IEvaluationContext {
- private final IEvaluationContext parentContext;
-
- private Object value;
-
- private final IExpression variable;
-
- public SingleVariableContext(IEvaluationContext parentContext, IExpression variable) {
- this.parentContext = parentContext;
- this.variable = variable;
- }
-
- public Object getParameter(int position) {
- return parentContext.getParameter(position);
- }
-
- public Object getParameter(String key) {
- return parentContext.getParameter(key);
- }
-
- public Object getValue(IExpression var) {
- return variable == var ? value : parentContext.getValue(var);
- }
-
- public void setValue(IExpression var, Object val) {
- if (variable == var)
- value = val;
- else
- parentContext.setValue(var, val);
- }
-} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/All.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/All.java
deleted file mode 100644
index a8181dc2c..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/All.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*******************************************************************************
- * 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.Iterator;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
-
-/**
- * A collection filter that yields true if the <code>filter</code> yields true for
- * all of the elements of the <code>collection</code>
- */
-final class All extends CollectionFilter {
- All(Expression collection, LambdaExpression lambda) {
- super(collection, lambda);
- }
-
- public int getExpressionType() {
- return TYPE_ALL;
- }
-
- Object evaluate(IEvaluationContext context, Iterator<?> itor) {
- Variable variable = lambda.getItemVariable();
- while (itor.hasNext()) {
- variable.setValue(context, itor.next());
- if (lambda.evaluate(context) != Boolean.TRUE)
- return Boolean.FALSE;
- }
- return Boolean.TRUE;
- }
-
- String getOperator() {
- return KEYWORD_ALL;
- }
-
- boolean isBoolean() {
- return true;
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/And.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/And.java
deleted file mode 100644
index 992ad9be5..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/And.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
- * 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.p2.ql.IEvaluationContext;
-
-/**
- * n-ary AND operator. This operator evaluates its first operand and then checks
- * the class of the result. If the class is {@link Boolean} then it is assumed
- * that all other operands also evaluates to a boolean and the full evaluation is
- * <code>true</code> if all its operands evaluate to <code>true</code>. If the first
- * result was not of class {@link Boolean}, then it is assumed that it can be accessed
- * as an {@link Iterator} and that all other operands also evaluates to something that
- * can be accessed as an {@link Iterator}. The AND operator will then function as a
- * INTERSECT operator and the result is the set of elements that were found in all operands.
- */
-final class And extends NAry {
- And(Expression[] operands) {
- super(assertLength(operands, 2, OPERATOR_AND));
- }
-
- public Object evaluate(IEvaluationContext context) {
- Object firstValue = operands[0].evaluate(context);
-
- // Determine operation mode
- if (firstValue instanceof Boolean) {
- // The first value was boolean. Assume that the rest are too
- if (!((Boolean) firstValue).booleanValue())
- return Boolean.FALSE;
-
- for (int idx = 1; idx < operands.length; ++idx) {
- if (operands[idx].evaluate(context) != Boolean.TRUE)
- return Boolean.FALSE;
- }
- return Boolean.TRUE;
- }
-
- // Not a boolean. Assume that we can use an iterator on all values
- Set<?> resultSet = asSet(firstValue, false); // Safe since it will not be modified
- for (int idx = 1; idx < operands.length && !resultSet.isEmpty(); ++idx) {
- Iterator<?> itor = operands[idx].evaluateAsIterator(context);
- Set<Object> retained = new HashSet<Object>();
- while (itor.hasNext()) {
- Object value = itor.next();
- if (resultSet.contains(value))
- retained.add(value);
- }
- resultSet = retained;
- }
- return resultSet;
- }
-
- public int getExpressionType() {
- return TYPE_AND;
- }
-
- String getOperator() {
- return OPERATOR_AND;
- }
-
- int getPriority() {
- return PRIORITY_AND;
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Array.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Array.java
index ebba0e5ca..62dfb329c 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Array.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Array.java
@@ -12,13 +12,14 @@ package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.Iterator;
import java.util.NoSuchElementException;
-import org.eclipse.equinox.internal.p2.ql.parser.IParserConstants;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
/**
* An array of expressions
*/
-final class Array extends NAry {
+final class Array extends NAry implements IQLConstants, IQLExpression {
final class ArrayIterator implements Iterator<Object> {
private final IEvaluationContext context;
@@ -45,19 +46,8 @@ final class Array extends NAry {
}
}
- static void elementsToString(StringBuffer bld, Expression[] elements) {
- int top = elements.length;
- if (top > 0) {
- elements[0].toString(bld);
- for (int idx = 1; idx < top; ++idx) {
- bld.append(", "); //$NON-NLS-1$
- appendOperand(bld, elements[idx], PRIORITY_COMMA);
- }
- }
- }
-
Array(Expression[] operands) {
- super(assertLength(operands, 0, IParserConstants.OPERATOR_ARRAY));
+ super(assertLength(operands, 0, OPERATOR_ARRAY));
}
public Object evaluate(IEvaluationContext context) {
@@ -72,29 +62,17 @@ final class Array extends NAry {
return TYPE_ARRAY;
}
- public void toString(StringBuffer bld) {
+ public void toString(StringBuffer bld, Variable rootVariable) {
bld.append('[');
- elementsToString(bld, operands);
+ elementsToString(bld, rootVariable, operands);
bld.append(']');
}
- String getOperator() {
- return IParserConstants.OPERATOR_ARRAY;
- }
-
- int getPriority() {
- return PRIORITY_CONSTRUCTOR;
- }
-
- boolean isBoolean() {
- return false;
- }
-
- boolean isCollection() {
- return true;
+ public String getOperator() {
+ return OPERATOR_ARRAY;
}
- boolean isElementBoolean() {
- return super.isBoolean();
+ public int getPriority() {
+ return PRIORITY_FUNCTION;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Assignment.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Assignment.java
index 23b69e8a7..22b747b7e 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Assignment.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Assignment.java
@@ -10,12 +10,15 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import java.util.Iterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
/**
* An expression representing a variable stack in the current thread.
*/
-class Assignment extends Binary {
+class Assignment extends Binary implements IQLConstants, IQLExpression {
Assignment(Variable variable, Expression expression) {
super(variable, expression);
}
@@ -30,19 +33,17 @@ class Assignment extends Binary {
return TYPE_ASSIGNMENT;
}
- int getPriority() {
- return PRIORITY_ASSIGNMENT;
+ public int getPriority() {
+ return IExpressionConstants.PRIORITY_ASSIGNMENT;
}
- String getOperator() {
+ public String getOperator() {
return OPERATOR_ASSIGN;
}
- boolean isBoolean() {
- return rhs.isBoolean();
- }
-
- boolean isCollection() {
- return rhs.isCollection();
+ public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
+ Iterator<?> value = rhs.evaluateAsIterator(context);
+ context.setValue(lhs, value);
+ return value;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/At.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/At.java
index 70b97119f..70d1639f9 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/At.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/At.java
@@ -10,76 +10,30 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
-import java.util.*;
-import org.eclipse.equinox.internal.p2.ql.expression.Member.DynamicMember;
+import org.eclipse.equinox.internal.p2.metadata.expression.Expression;
+import org.eclipse.equinox.internal.p2.metadata.expression.Member;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
import org.eclipse.equinox.p2.ql.ITranslationSupport;
/**
* This class represents indexed or keyed access to an indexed collection
* or a map.
*/
-final class At extends Binary {
+final class At extends org.eclipse.equinox.internal.p2.metadata.expression.At implements IQLExpression {
At(Expression lhs, Expression rhs) {
super(lhs, rhs);
}
- public Object evaluate(IEvaluationContext context) {
- Object lval;
- if (lhs instanceof DynamicMember) {
- DynamicMember lm = (DynamicMember) lhs;
- Object instance = lm.operand.evaluate(context);
- if (instance instanceof IInstallableUnit) {
- if ("properties".equals(lm.name)) //$NON-NLS-1$
- // Avoid full copy of the properties map just to get one member
- return ((IInstallableUnit) instance).getProperty((String) rhs.evaluate(context));
-
- if (VARIABLE_TRANSLATIONS.equals(lm.name)) {
- ITranslationSupport ts = (ITranslationSupport) Variable.TRANSLATIONS.evaluate(context);
- return ts.getIUProperty((IInstallableUnit) instance, (String) rhs.evaluate(context));
- }
+ protected Object handleMember(IEvaluationContext context, Member member, Object instance, boolean[] handled) {
+ if (instance instanceof IInstallableUnit) {
+ if (IQLConstants.VARIABLE_TRANSLATIONS.equals(member.getName())) {
+ ITranslationSupport ts = (ITranslationSupport) QLFactory.TRANSLATIONS.evaluate(context);
+ handled[0] = true;
+ return ts.getIUProperty((IInstallableUnit) instance, (String) rhs.evaluate(context));
}
- lval = lm.invoke(instance);
- } else
- lval = lhs.evaluate(context);
-
- Object rval = rhs.evaluate(context);
- if (lval == null)
- throw new IllegalArgumentException("Unable to use [] on null"); //$NON-NLS-1$
-
- if (lval instanceof Map<?, ?>)
- return ((Map<?, ?>) lval).get(rval);
-
- if (rval instanceof Number) {
- if (lval instanceof List<?>)
- return ((List<?>) lval).get(((Number) rval).intValue());
- if (lval != null && lval.getClass().isArray())
- return ((Object[]) lval)[((Number) rval).intValue()];
}
-
- if (lval instanceof Dictionary<?, ?>)
- return ((Dictionary<?, ?>) lval).get(rval);
-
- throw new IllegalArgumentException("Unable to use [] on a " + lval.getClass().getName()); //$NON-NLS-1$
- }
-
- public int getExpressionType() {
- return TYPE_AT;
- }
-
- public void toString(StringBuffer bld) {
- appendOperand(bld, lhs, getPriority());
- bld.append('[');
- appendOperand(bld, rhs, PRIORITY_COMMA);
- bld.append(']');
- }
-
- String getOperator() {
- return OPERATOR_AT;
- }
-
- int getPriority() {
- return PRIORITY_MEMBER;
+ return super.handleMember(context, member, instance, handled);
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Binary.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Binary.java
deleted file mode 100644
index ac17e0d49..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Binary.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * 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 org.eclipse.equinox.p2.ql.IExpressionVisitor;
-
-/**
- * The abstract base class for all binary operations
- */
-abstract class Binary extends Expression {
- final Expression lhs;
-
- final Expression rhs;
-
- Binary(Expression lhs, Expression rhs) {
- this.lhs = lhs;
- this.rhs = rhs;
- }
-
- public boolean accept(IExpressionVisitor visitor) {
- return super.accept(visitor) && lhs.accept(visitor) && rhs.accept(visitor);
- }
-
- public void toString(StringBuffer bld) {
- appendOperand(bld, lhs, getPriority());
- bld.append(' ');
- bld.append(getOperator());
- bld.append(' ');
- appendOperand(bld, rhs, getPriority());
- }
-
- int countReferenceToEverything() {
- return lhs.countReferenceToEverything() + rhs.countReferenceToEverything();
- }
-
- int getPriority() {
- return PRIORITY_BINARY; // Default priority
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/BooleanFunction.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/BooleanFunction.java
index 10268eb36..860fe6e12 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/BooleanFunction.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/BooleanFunction.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 Cloudsmith Inc. and others.
+ * Copyright (c) 2010 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
@@ -10,14 +10,15 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
+import org.eclipse.equinox.internal.p2.metadata.expression.Expression;
+
/**
* A function that obtains a class based on a String
*/
-final class BooleanFunction extends Function {
+public final class BooleanFunction extends Function {
public BooleanFunction(Expression[] operands) {
super(assertLength(operands, 1, 1, KEYWORD_BOOLEAN));
- assertNotCollection(operands[0], "parameter"); //$NON-NLS-1$
}
boolean assertSingleArgumentClass(Object v) {
@@ -32,7 +33,7 @@ final class BooleanFunction extends Function {
return Boolean.FALSE;
}
- String getOperator() {
+ public String getOperator() {
return KEYWORD_BOOLEAN;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/CapabilityIndexFunction.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/CapabilityIndexFunction.java
index 99e37e985..56297974e 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/CapabilityIndexFunction.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/CapabilityIndexFunction.java
@@ -11,26 +11,75 @@
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.Iterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.Expression;
+import org.eclipse.equinox.internal.p2.metadata.expression.Member;
import org.eclipse.equinox.internal.p2.ql.CapabilityIndex;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.IRequirement;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.ICapabilityIndex;
+import org.eclipse.equinox.p2.ql.IQLExpression;
/**
* A function that creates a {@link CapabilityIndex} based on a collection of
* {@link IInstallableUnit} instances.
*/
-final class CapabilityIndexFunction extends Function {
+public final class CapabilityIndexFunction extends Function implements IQLConstants {
+ static abstract class CapabilityIndexMethod extends Member implements IQLExpression {
+ public CapabilityIndexMethod(Expression operand, String name, Expression[] args) {
+ super(operand, name, args);
+ }
+
+ final ICapabilityIndex getSelf(IEvaluationContext context) {
+ Object self = operand.evaluate(context);
+ if (self instanceof ICapabilityIndex)
+ return (ICapabilityIndex) self;
+ throw new IllegalArgumentException("lhs of member expected to be an ICapabilityIndex implementation"); //$NON-NLS-1$
+ }
+
+ public final Object evaluate(IEvaluationContext context) {
+ return evaluateAsIterator(context);
+ }
+
+ boolean isCollection() {
+ return true;
+ }
+ }
+
+ static final class SatisfiesAny extends CapabilityIndexMethod {
+
+ public SatisfiesAny(Expression operand, Expression[] argExpressions) {
+ super(operand, KEYWORD_SATISFIES_ANY, assertLength(argExpressions, 1, 1, KEYWORD_SATISFIES_ANY));
+ }
+
+ @SuppressWarnings("unchecked")
+ public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
+ return getSelf(context).satisfiesAny((Iterator<IRequirement>) argExpressions[0].evaluateAsIterator(context));
+ }
+ }
+
+ static final class SatisfiesAll extends CapabilityIndexMethod {
+
+ public SatisfiesAll(Expression operand, Expression[] argExpressions) {
+ super(operand, KEYWORD_SATISFIES_ALL, assertLength(argExpressions, 1, 1, KEYWORD_SATISFIES_ALL));
+ }
+
+ @SuppressWarnings("unchecked")
+ public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
+ return getSelf(context).satisfiesAll((Iterator<IRequirement>) argExpressions[0].evaluateAsIterator(context));
+ }
+ }
public CapabilityIndexFunction(Expression[] operands) {
super(assertLength(operands, 1, 1, KEYWORD_CAPABILITY_INDEX));
- assertNotBoolean(operands[0], "parameter"); //$NON-NLS-1$
}
+ @SuppressWarnings("unchecked")
public Object evaluate(IEvaluationContext context) {
return new CapabilityIndex((Iterator<IInstallableUnit>) operands[0].evaluateAsIterator(context));
}
- String getOperator() {
+ public String getOperator() {
return KEYWORD_CAPABILITY_INDEX;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ClassFunction.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ClassFunction.java
index 5fe40c0ac..53d0b3044 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ClassFunction.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ClassFunction.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 Cloudsmith Inc. and others.
+ * Copyright (c) 2010 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
@@ -10,15 +10,15 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
+import org.eclipse.equinox.internal.p2.metadata.expression.Expression;
+
/**
* A function that obtains a class based on a String
*/
-final class ClassFunction extends Function {
+public final class ClassFunction extends Function {
public ClassFunction(Expression[] operands) {
super(assertLength(operands, 1, 1, KEYWORD_CLASS));
- assertNotBoolean(operands[0], "parameter"); //$NON-NLS-1$
- assertNotCollection(operands[0], "parameter"); //$NON-NLS-1$
}
boolean assertSingleArgumentClass(Object v) {
@@ -33,7 +33,7 @@ final class ClassFunction extends Function {
}
}
- String getOperator() {
+ public String getOperator() {
return KEYWORD_CLASS;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Collect.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Collect.java
index fddda5dd5..5f3a67ebc 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Collect.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Collect.java
@@ -11,12 +11,14 @@
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.Iterator;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
-import org.eclipse.equinox.p2.ql.IExpression;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.expression.IExpression;
+import org.eclipse.equinox.p2.ql.IQLExpression;
/**
*/
-final class Collect extends CollectionFilter {
+final class Collect extends CollectionFilter implements IQLExpression {
final class CollectIterator implements Iterator<Object> {
private final IEvaluationContext context;
@@ -48,11 +50,11 @@ final class Collect extends CollectionFilter {
super(collection, lambda);
}
- Object evaluate(IEvaluationContext context, Iterator<?> itor) {
+ public Object evaluate(IEvaluationContext context, Iterator<?> itor) {
return evaluateAsIterator(context, itor);
}
- Iterator<?> evaluateAsIterator(IEvaluationContext context, Iterator<?> itor) {
+ public Iterator<?> evaluateAsIterator(IEvaluationContext context, Iterator<?> itor) {
return new CollectIterator(context, itor);
}
@@ -60,11 +62,7 @@ final class Collect extends CollectionFilter {
return TYPE_COLLECT;
}
- String getOperator() {
- return KEYWORD_COLLECT;
- }
-
- boolean isCollection() {
- return true;
+ public String getOperator() {
+ return IQLConstants.KEYWORD_COLLECT;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/CollectionFilter.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/CollectionFilter.java
deleted file mode 100644
index b33b28aee..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/CollectionFilter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
- * 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.Iterator;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
-import org.eclipse.equinox.p2.ql.IExpressionVisitor;
-
-/**
- * Some kind of operation that is performed for each element of a collection. I.e.
- * <code>x.&lt;operation&gt;(y | &lt;expression&rt;)</code>
- */
-abstract class CollectionFilter extends Unary {
- static void appendProlog(StringBuffer bld, Expression lhs, String operator) {
- if (lhs != Variable.EVERYTHING && lhs != Variable.ITEM) {
- appendOperand(bld, lhs, PRIORITY_COLLECTION);
- bld.append('.');
- }
- bld.append(operator);
- bld.append('(');
- }
-
- final LambdaExpression lambda;
-
- CollectionFilter(Expression collection, LambdaExpression lambda) {
- super(collection);
- this.lambda = lambda;
- }
-
- public boolean accept(IExpressionVisitor visitor) {
- return super.accept(visitor) && lambda.accept(visitor);
- }
-
- public final Object evaluate(IEvaluationContext context) {
- Iterator<?> lval = operand.evaluateAsIterator(context);
- context = lambda.prolog(context);
- return evaluate(context, lval);
- }
-
- public final Iterator<?> evaluateAsIterator(IEvaluationContext context) {
- Iterator<?> lval = operand.evaluateAsIterator(context);
- context = lambda.prolog(context);
- return evaluateAsIterator(context, lval);
- }
-
- public void toString(StringBuffer bld) {
- appendProlog(bld, operand, getOperator());
- appendOperand(bld, lambda, PRIORITY_LAMBDA);
- bld.append(')');
- }
-
- int countReferenceToEverything() {
- return super.countReferenceToEverything() + lambda.countReferenceToEverything();
- }
-
- abstract Object evaluate(final IEvaluationContext context, Iterator<?> iterator);
-
- Iterator<?> evaluateAsIterator(IEvaluationContext context, Iterator<?> iterator) {
- throw new UnsupportedOperationException();
- }
-
- int getPriority() {
- return PRIORITY_COLLECTION;
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Compare.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Compare.java
deleted file mode 100644
index 89d21d02e..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Compare.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * 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 org.eclipse.equinox.p2.metadata.Version;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
-
-/**
- * Comparisons for magnitude.
- */
-final class Compare extends Binary {
- final boolean compareLess;
- final boolean equalOK;
-
- Compare(Expression lhs, Expression rhs, boolean compareLess, boolean equalOK) {
- super(lhs, rhs);
- this.compareLess = compareLess;
- this.equalOK = equalOK;
- assertNotCollection(lhs, "lhs"); //$NON-NLS-1$
- assertNotCollection(rhs, "rhs"); //$NON-NLS-1$
- }
-
- public Object evaluate(IEvaluationContext context) {
- Object lval = lhs.evaluate(context);
- Object rval = rhs.evaluate(context);
- if (lval == null || rval == null)
- throw new IllegalArgumentException("Cannot compare null to anything"); //$NON-NLS-1$
-
- try {
-
- if (lval.getClass() != rval.getClass()) {
- if (lval instanceof Version && rval instanceof String)
- rval = Version.create((String) rval);
- else if (rval instanceof Version && lval instanceof String)
- lval = Version.create((String) lval);
- else if (lval instanceof String)
- rval = rval.toString();
- else if (rval instanceof String)
- lval = lval.toString();
- }
-
- if (lval instanceof Comparable) {
- int cmpResult = ((Comparable) lval).compareTo(rval);
- return Boolean.valueOf(cmpResult == 0 ? equalOK : (cmpResult < 0 ? compareLess : !compareLess));
- }
- } catch (Exception e) {
- //
- }
- throw new IllegalArgumentException("Cannot compare a " + lval.getClass().getName() + " to a " + rval.getClass().getName()); //$NON-NLS-1$//$NON-NLS-2$
- }
-
- public int getExpressionType() {
- return compareLess ? (equalOK ? TYPE_LESS_EQUAL : TYPE_LESS) : (equalOK ? TYPE_GREATER_EQUAL : TYPE_GREATER);
- }
-
- String getOperator() {
- return compareLess ? (equalOK ? OPERATOR_LT_EQUAL : OPERATOR_LT) : (equalOK ? OPERATOR_GT_EQUAL : OPERATOR_GT);
- }
-
- boolean isBoolean() {
- return true;
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Condition.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Condition.java
index 543294be4..9de25672c 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Condition.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Condition.java
@@ -10,49 +10,55 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import java.util.Iterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
/**
* Comparisons for magnitude.
*/
-final class Condition extends Binary {
+final class Condition extends Binary implements IQLConstants, IQLExpression {
final Expression ifFalse;
Condition(Expression test, Expression ifTrue, Expression ifFalse) {
super(test, ifTrue);
this.ifFalse = ifFalse;
- assertNotCollection(test, "test"); //$NON-NLS-1$
+ }
+
+ public boolean equals(Object o) {
+ return super.equals(o) && ifFalse.equals(((Condition) o).ifFalse);
}
public Object evaluate(IEvaluationContext context) {
return lhs.evaluate(context) == Boolean.TRUE ? rhs.evaluate(context) : ifFalse.evaluate(context);
}
- public int getExpressionType() {
- return TYPE_CONDITION;
+ public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
+ return lhs.evaluate(context) == Boolean.TRUE ? rhs.evaluateAsIterator(context) : ifFalse.evaluateAsIterator(context);
+ }
+
+ public int hashCode() {
+ return super.hashCode() * 31 + ifFalse.hashCode();
}
- public void toString(StringBuffer bld) {
- super.toString(bld);
+ public void toString(StringBuffer bld, Variable rootVariable) {
+ super.toString(bld, rootVariable);
bld.append(' ');
bld.append(OPERATOR_ELSE);
bld.append(' ');
- appendOperand(bld, ifFalse, getPriority());
+ appendOperand(bld, rootVariable, ifFalse, getPriority());
}
- String getOperator() {
- return OPERATOR_IF;
- }
-
- int getPriority() {
- return PRIORITY_CONDITION;
+ public int getExpressionType() {
+ return TYPE_CONDITION;
}
- boolean isBoolean() {
- return rhs.isBoolean() && ifFalse.isBoolean();
+ public String getOperator() {
+ return OPERATOR_IF;
}
- boolean isCollection() {
- return rhs.isCollection() && ifFalse.isCollection();
+ public int getPriority() {
+ return IExpressionConstants.PRIORITY_CONDITION;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Constant.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Constant.java
deleted file mode 100644
index 797f04535..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Constant.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*******************************************************************************
- * 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.p2.ql.IEvaluationContext;
-import org.eclipse.equinox.p2.ql.SimplePattern;
-import org.eclipse.equinox.p2.query.IQueryResult;
-
-/**
- * An expression that represents a constant value.
- */
-final class Constant extends Expression {
- private final Object value;
-
- static final Constant NULL_CONSTANT = new Constant(null);
-
- static final Constant TRUE_CONSTANT = new Constant(Boolean.TRUE);
-
- static final Constant FALSE_CONSTANT = new Constant(Boolean.FALSE);
-
- static Constant create(Object value) {
- if (value == null)
- return NULL_CONSTANT;
- if (value == Boolean.TRUE)
- return TRUE_CONSTANT;
- if (value == Boolean.FALSE)
- return FALSE_CONSTANT;
- return new Constant(value);
- }
-
- private Constant(Object value) {
- this.value = value;
- }
-
- public Object evaluate(IEvaluationContext context) {
- return value;
- }
-
- public int getExpressionType() {
- return TYPE_LITERAL;
- }
-
- public void toString(StringBuffer bld) {
- if (value == null)
- bld.append("null"); //$NON-NLS-1$
- else if (value instanceof String) {
- String str = (String) value;
- char sep = str.indexOf('\'') >= 0 ? '"' : '\'';
- bld.append(sep);
- bld.append(str);
- bld.append(sep);
- } else if (value instanceof SimplePattern) {
- appendEscaped(bld, '/', value.toString());
- } else
- bld.append(value);
- }
-
- int getPriority() {
- return PRIORITY_LITERAL;
- }
-
- private void appendEscaped(StringBuffer bld, char delimiter, String str) {
- bld.append(delimiter);
- int top = str.length();
- for (int idx = 0; idx < top; ++idx) {
- char c = str.charAt(idx);
- if (c == delimiter)
- bld.append('\\');
- bld.append(c);
- }
- bld.append(delimiter);
- }
-
- boolean isBoolean() {
- return value instanceof Boolean;
- }
-
- boolean isCollection() {
- return value instanceof Collection<?> || value instanceof Map<?, ?> || value instanceof Iterator<?> || value instanceof IQueryResult<?> || value != null && value.getClass().isArray();
- }
-
- String getOperator() {
- return "<literal>"; //$NON-NLS-1$
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ContextExpression.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ContextExpression.java
index 031eb5017..26cbce481 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ContextExpression.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ContextExpression.java
@@ -11,37 +11,49 @@
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.Iterator;
-import org.eclipse.equinox.internal.p2.ql.*;
-import org.eclipse.equinox.p2.ql.*;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.internal.p2.ql.Everything;
+import org.eclipse.equinox.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.ql.IContextExpression;
+import org.eclipse.equinox.p2.ql.ITranslationSupport;
/**
* The context expression is the top expression in context queries. It introduces the
* variable 'everything' and initialized it with the iterator that represents all
* available items.
*/
-final class ContextExpression<T> extends Unary implements IContextExpression<T> {
-
+public final class ContextExpression<T> extends Unary implements IContextExpression<T>, IQLConstants {
+ private static final Object[] noParams = new Object[0];
private final Class<T> elementClass;
+ private final Object[] parameters;
- ContextExpression(Class<T> elementClass, Expression expression) {
+ public ContextExpression(Class<T> elementClass, Expression expression, Object[] parameters) {
super(expression);
this.elementClass = elementClass;
+ this.parameters = parameters == null ? noParams : parameters;
}
- public void toString(StringBuffer bld) {
- operand.toString(bld);
+ public boolean accept(IExpressionVisitor visitor) {
+ return visitor.visit(operand);
+ }
+
+ public void toString(StringBuffer bld, Variable rootVariable) {
+ operand.toString(bld, rootVariable);
}
- public IEvaluationContext createContext(Iterator<T> iterator, Object[] params) {
- IEvaluationContext context = new SingleVariableContext(new ParameterContext(params), Variable.EVERYTHING);
- context.setValue(Variable.EVERYTHING, new Everything<T>(elementClass, iterator, operand.needsRepeatedIterations()));
+ public IEvaluationContext createContext(Iterator<T> iterator) {
+ Variable everything = QLFactory.EVERYTHING;
+ IEvaluationContext context = EvaluationContext.create(parameters, everything);
+ context.setValue(everything, new Everything<T>(elementClass, iterator, QLUtil.needsRepeadedAccessToEverything(operand)));
return context;
}
- public IEvaluationContext createContext(Iterator<T> iterator, Object[] params, ITranslationSupport ts) {
- IEvaluationContext context = new MultiVariableContext(new ParameterContext(params), new IExpression[] {Variable.EVERYTHING, Variable.TRANSLATIONS});
- context.setValue(Variable.EVERYTHING, new Everything<T>(elementClass, iterator, operand.needsRepeatedIterations()));
- context.setValue(Variable.TRANSLATIONS, ts);
+ public IEvaluationContext createContext(Iterator<T> iterator, ITranslationSupport ts) {
+ Variable everything = QLFactory.EVERYTHING;
+ IExpression translations = QLFactory.TRANSLATIONS;
+ IEvaluationContext context = EvaluationContext.create(parameters, new IExpression[] {everything, translations});
+ context.setValue(everything, new Everything<T>(elementClass, iterator, QLUtil.needsRepeadedAccessToEverything(operand)));
+ context.setValue(translations, ts);
return context;
}
@@ -50,26 +62,31 @@ final class ContextExpression<T> extends Unary implements IContextExpression<T>
}
public int getExpressionType() {
- return operand.getExpressionType();
+ return 0;
}
- String getOperator() {
+ public String getOperator() {
throw new UnsupportedOperationException();
}
- int getPriority() {
+ public int getPriority() {
return operand.getPriority();
}
- Expression pipeFrom(Expression expr) {
- return new ContextExpression<T>(elementClass, operand.pipeFrom(expr));
+ public Object[] getParameters() {
+ return parameters;
}
- boolean isBoolean() {
- return operand.isBoolean();
+ public int hashCode() {
+ return operand.hashCode();
}
- boolean isCollection() {
- return operand.isCollection();
+ @SuppressWarnings("unchecked")
+ public Iterator<T> iterator(IEvaluationContext context) {
+ return (Iterator<T>) evaluateAsIterator(context);
+ }
+
+ public void toString(StringBuffer bld) {
+ toString(bld, QLFactory.EVERYTHING);
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/LambdaExpression.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/CurryedLambdaExpression.java
index cdc1d7216..dfdeb7b76 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/LambdaExpression.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/CurryedLambdaExpression.java
@@ -10,31 +10,25 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
-import org.eclipse.equinox.internal.p2.ql.MultiVariableContext;
-import org.eclipse.equinox.internal.p2.ql.SingleVariableContext;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
-import org.eclipse.equinox.p2.ql.IExpressionVisitor;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.expression.IExpressionVisitor;
+import org.eclipse.equinox.p2.ql.IQLExpression;
/**
* A function that executes some code
*/
-final class LambdaExpression extends Unary {
+final class CurryedLambdaExpression extends LambdaExpression implements IQLConstants, IQLExpression {
private static final Assignment[] emptyAssignmentArray = new Assignment[0];
private final Assignment[] assignments;
- private final Variable each;
- LambdaExpression(Variable each, Expression body, Assignment[] assignments) {
- super(body);
- this.each = each;
+ CurryedLambdaExpression(Variable each, Assignment[] assignments, Expression body) {
+ super(each, body);
if (assignments == null)
assignments = emptyAssignmentArray;
this.assignments = assignments;
}
- LambdaExpression(Variable variable, Expression body) {
- this(variable, body, null);
- }
-
public boolean accept(IExpressionVisitor visitor) {
if (super.accept(visitor) && each.accept(visitor)) {
for (int idx = 0; idx < assignments.length; ++idx)
@@ -45,73 +39,53 @@ final class LambdaExpression extends Unary {
return false;
}
- public int getExpressionType() {
- return TYPE_LAMBDA;
+ public int compareTo(Expression e) {
+ int cmp = super.compareTo(e);
+ if (cmp == 0)
+ cmp = compare(assignments, ((CurryedLambdaExpression) e).assignments);
+ return cmp;
}
- public void toString(StringBuffer bld) {
+ public boolean equals(Object o) {
+ return super.equals(o) && equals(assignments, ((CurryedLambdaExpression) o).assignments);
+ }
+
+ public int hashCode() {
+ return 31 * super.hashCode() + hashCode(assignments);
+ }
+
+ public void toString(StringBuffer bld, Variable rootVariable) {
int top = assignments.length;
if (top > 0) {
for (int idx = 0; idx < top; ++idx) {
- appendOperand(bld, assignments[idx].rhs, PRIORITY_COMMA);
+ appendOperand(bld, rootVariable, assignments[idx].rhs, IExpressionConstants.PRIORITY_COMMA);
bld.append(", "); //$NON-NLS-1$
}
- bld.append(OPERATOR_EACH);
+ bld.append(IQLConstants.OPERATOR_EACH);
bld.append(", {"); //$NON-NLS-1$
for (int idx = 0; idx < top; ++idx) {
- appendOperand(bld, assignments[idx].lhs, PRIORITY_COMMA);
+ appendOperand(bld, rootVariable, assignments[idx].lhs, IExpressionConstants.PRIORITY_COMMA);
bld.append(", "); //$NON-NLS-1$
}
}
- each.toString(bld);
- bld.append(" | "); //$NON-NLS-1$
- appendOperand(bld, operand, PRIORITY_COMMA);
+ super.toString(bld, rootVariable);
if (top > 0)
bld.append('}');
}
- int countReferenceToEverything() {
- if (super.countReferenceToEverything() > 0)
- return 2;
- for (int idx = 0; idx < assignments.length; ++idx)
- if (assignments[idx].countReferenceToEverything() > 0)
- return 2;
- return 0;
- }
-
- Variable getItemVariable() {
- return each;
- }
-
- String getOperator() {
- return "|"; //$NON-NLS-1$
- }
-
- int getPriority() {
- return PRIORITY_LAMBDA;
- }
-
- boolean isBoolean() {
- return operand.isBoolean();
- }
-
- boolean isCollection() {
- return operand.isCollection();
- }
-
- IEvaluationContext prolog(IEvaluationContext context) {
- IEvaluationContext lambdaContext = new SingleVariableContext(context, each);
+ public IEvaluationContext prolog(IEvaluationContext context) {
+ IEvaluationContext lambdaContext = super.prolog(context);
int top = assignments.length;
if (top > 0) {
if (top == 1) {
Assignment v = assignments[0];
- lambdaContext = new SingleVariableContext(lambdaContext, v.lhs);
+ lambdaContext = EvaluationContext.create(lambdaContext, v.lhs);
lambdaContext.setValue(v.lhs, v.rhs.evaluate(context));
} else {
Variable[] vars = new Variable[top];
for (int idx = 0; idx < top; ++idx)
vars[idx] = (Variable) assignments[idx].lhs;
- lambdaContext = new MultiVariableContext(lambdaContext, vars);
+ lambdaContext = EvaluationContext.create(lambdaContext, vars);
for (int idx = 0; idx < top; ++idx)
lambdaContext.setValue(vars[idx], assignments[idx].rhs.evaluate(context));
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Equals.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Equals.java
deleted file mode 100644
index 773fb75b4..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Equals.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
- * 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 org.eclipse.equinox.p2.ql.IEvaluationContext;
-
-/**
- * An expression that performs the == and != comparisons
- */
-final class Equals extends Binary {
- final boolean negate;
-
- Equals(Expression lhs, Expression rhs, boolean negate) {
- super(lhs, rhs);
- this.negate = negate;
- assertNotCollection(lhs, "lhs"); //$NON-NLS-1$
- assertNotCollection(rhs, "rhs"); //$NON-NLS-1$
- }
-
- public Object evaluate(IEvaluationContext context) {
- Object lval = lhs.evaluate(context);
- Object rval = rhs.evaluate(context);
- boolean result;
- if (lval == null || rval == null)
- result = lval == rval;
- else {
- if (lval.getClass() != rval.getClass()) {
- if (lval instanceof String)
- rval = rval.toString();
- else if (rval instanceof String)
- lval = lval.toString();
- }
- result = lval.equals(rval);
- }
- if (negate)
- result = !result;
- return Boolean.valueOf(result);
- }
-
- public int getExpressionType() {
- return negate ? TYPE_NOT_EQUALS : TYPE_EQUALS;
- }
-
- String getOperator() {
- return negate ? OPERATOR_NOT_EQUALS : OPERATOR_EQUALS;
- }
-
- boolean isBoolean() {
- return true;
- }
-
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Exists.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Exists.java
deleted file mode 100644
index 71e967aec..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Exists.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*******************************************************************************
- * 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.Iterator;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
-
-/**
- * A collection filter that yields true if the <code>filter</code> yields true for
- * any of the elements of the <code>collection</code>
- */
-final class Exists extends CollectionFilter {
- Exists(Expression collection, LambdaExpression lambda) {
- super(collection, lambda);
- }
-
- public int getExpressionType() {
- return TYPE_EXISTS;
- }
-
- Object evaluate(IEvaluationContext context, Iterator<?> itor) {
- Variable variable = lambda.getItemVariable();
- while (itor.hasNext()) {
- variable.setValue(context, itor.next());
- if (lambda.evaluate(context) == Boolean.TRUE)
- return Boolean.TRUE;
- }
- return Boolean.FALSE;
- }
-
- String getOperator() {
- return KEYWORD_EXISTS;
- }
-
- boolean isBoolean() {
- return true;
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Expression.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Expression.java
deleted file mode 100644
index fcace814a..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Expression.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*******************************************************************************
- * 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.p2.ql.*;
-import org.eclipse.equinox.p2.query.IQueryResult;
-
-/**
- * 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 IQueryResult<?>)
- return ((IQueryResult<?>) provider).unmodifiableSet();
- }
-
- if (provider instanceof Collection<?>)
- val = provider;
- } else {
- if (!forcePrivateCopy) {
- if (val instanceof Set<?>)
- return (Set<?>) val;
- if (val instanceof IQueryResult<?>)
- return ((IQueryResult<?>) val).unmodifiableSet();
- }
- }
-
- HashSet<Object> result;
- if (val instanceof Collection<?>)
- result = new HashSet<Object>((Collection<?>) val);
- else {
- result = new HashSet<Object>();
- 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;
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/FilterFunction.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/FilterFunction.java
index 5f0130c36..0a4f96995 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/FilterFunction.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/FilterFunction.java
@@ -10,34 +10,26 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
-import org.eclipse.equinox.internal.p2.metadata.LDAPQuery;
-import org.eclipse.equinox.internal.p2.ql.QLActivator;
-import org.osgi.framework.InvalidSyntaxException;
+import org.eclipse.equinox.internal.p2.metadata.expression.Expression;
+import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil;
/**
* A function that creates an OSGi filter based on a String
*/
-final class FilterFunction extends Function {
+public final class FilterFunction extends Function {
public FilterFunction(Expression[] operands) {
super(assertLength(operands, 1, 1, KEYWORD_FILTER));
- assertNotBoolean(operands[0], "parameter"); //$NON-NLS-1$
- assertNotCollection(operands[0], "parameter"); //$NON-NLS-1$
}
boolean assertSingleArgumentClass(Object v) {
- return v instanceof LDAPQuery || v instanceof String;
+ return v instanceof String;
}
Object createInstance(Object arg) {
- String str = (arg instanceof LDAPQuery) ? ((LDAPQuery) arg).getFilter() : (String) arg;
- try {
- return QLActivator.context.createFilter(str);
- } catch (InvalidSyntaxException e) {
- throw new IllegalArgumentException(e.getMessage());
- }
+ return ExpressionUtil.parseLDAP((String) arg);
}
- String getOperator() {
+ public String getOperator() {
return KEYWORD_FILTER;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/First.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/First.java
index d587ab0bb..decd15906 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/First.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/First.java
@@ -11,22 +11,20 @@
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.Iterator;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
/**
* A collection filter that yields the first element of the <code>collection</code> for which
* the <code>filter</code> yields <code>true</code>
*/
-final class First extends CollectionFilter {
+final class First extends CollectionFilter implements IQLExpression {
First(Expression collection, LambdaExpression lambda) {
super(collection, lambda);
}
- public int getExpressionType() {
- return TYPE_FIRST;
- }
-
- Object evaluate(IEvaluationContext context, Iterator<?> itor) {
+ protected Object evaluate(IEvaluationContext context, Iterator<?> itor) {
Variable variable = lambda.getItemVariable();
while (itor.hasNext()) {
Object each = itor.next();
@@ -37,15 +35,11 @@ final class First extends CollectionFilter {
return null;
}
- String getOperator() {
- return KEYWORD_FIRST;
- }
-
- boolean isBoolean() {
- return operand.isElementBoolean();
+ public int getExpressionType() {
+ return TYPE_FIRST;
}
- boolean isCollection() {
- return operand.isElementCollection();
+ public String getOperator() {
+ return IQLConstants.KEYWORD_FIRST;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Flatten.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Flatten.java
index bb94afcb7..b0ff4122c 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Flatten.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Flatten.java
@@ -11,8 +11,9 @@
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.Iterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.Expression;
import org.eclipse.equinox.internal.p2.ql.FlattenIterator;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
/**
* An expression that yields a new collection consisting of all elements of the
@@ -31,7 +32,7 @@ final class Flatten extends UnaryCollectionFilter {
return TYPE_FLATTEN;
}
- String getOperator() {
+ public String getOperator() {
return KEYWORD_FLATTEN;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Function.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Function.java
index 5497dca2b..d704681f2 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Function.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Function.java
@@ -10,19 +10,34 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import java.util.Iterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
/**
* An expression that represents a function such as filter(&lt;expr&gt;) or version(&lt;expr&gt;)
*/
-abstract class Function extends NAry {
+public abstract class Function extends NAry implements IQLExpression {
private Object instance;
- Function(Expression[] operands) {
+ protected Function(Expression[] operands) {
super(operands);
}
+ boolean assertSingleArgumentClass(Object v) {
+ return true;
+ }
+
+ Object createInstance(Object arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ final Object createInstance(String arg) {
+ throw new UnsupportedOperationException();
+ }
+
public Object evaluate(IEvaluationContext context) {
if (instance != null)
return instance;
@@ -31,7 +46,7 @@ abstract class Function extends NAry {
Object arg = operand.evaluate(context);
if (assertSingleArgumentClass(arg)) {
Object result = createInstance(arg);
- if (operand instanceof Constant || operand instanceof Parameter)
+ if (operand instanceof Literal || operand instanceof Parameter)
// operand won't change over time so we can cache this instance.
instance = result;
return result;
@@ -40,38 +55,25 @@ abstract class Function extends NAry {
throw new IllegalArgumentException("Cannot create a " + getOperator() + " from " + what); //$NON-NLS-1$ //$NON-NLS-2$
}
- boolean assertSingleArgumentClass(Object v) {
- return true;
+ public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
+ Object value = evaluate(context);
+ if (!(value instanceof Iterator<?>))
+ value = RepeatableIterator.create(value);
+ return (Iterator<?>) value;
}
public int getExpressionType() {
return TYPE_FUNCTION;
}
- public void toString(StringBuffer bld) {
+ public int getPriority() {
+ return PRIORITY_FUNCTION;
+ }
+
+ public void toString(StringBuffer bld, Variable rootVariable) {
bld.append(getOperator());
bld.append('(');
- Array.elementsToString(bld, operands);
+ elementsToString(bld, rootVariable, operands);
bld.append(')');
}
-
- final Object createInstance(String arg) {
- throw new UnsupportedOperationException();
- }
-
- Object createInstance(Object arg) {
- throw new UnsupportedOperationException();
- }
-
- int getPriority() {
- return PRIORITY_CONSTRUCTOR;
- }
-
- boolean isBoolean() {
- return false;
- }
-
- boolean isCollection() {
- return false;
- }
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/IQLConstants.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/IQLConstants.java
new file mode 100644
index 000000000..397cc13ed
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/IQLConstants.java
@@ -0,0 +1,30 @@
+package org.eclipse.equinox.internal.p2.ql.expression;
+
+public interface IQLConstants {
+ String KEYWORD_CAPABILITY_INDEX = "capabilityIndex"; //$NON-NLS-1$
+ String KEYWORD_COLLECT = "collect"; //$NON-NLS-1$
+ String KEYWORD_FIRST = "first"; //$NON-NLS-1$
+ String KEYWORD_FLATTEN = "flatten"; //$NON-NLS-1$
+ String KEYWORD_INTERSECT = "intersect"; //$NON-NLS-1$
+ String KEYWORD_IQUERY = "iquery"; //$NON-NLS-1$
+ String KEYWORD_LATEST = "latest"; //$NON-NLS-1$
+ String KEYWORD_LIMIT = "limit"; //$NON-NLS-1$
+ String KEYWORD_LOCALIZED_KEYS = "localizedKeys"; //$NON-NLS-1$
+ String KEYWORD_LOCALIZED_MAP = "localizedMap"; //$NON-NLS-1$
+ String KEYWORD_LOCALIZED_PROPERTY = "localizedProperty"; //$NON-NLS-1$
+ String KEYWORD_SATISFIES_ALL = "satisfiesAll"; //$NON-NLS-1$
+ String KEYWORD_SATISFIES_ANY = "satisfiesAny"; //$NON-NLS-1$
+ String KEYWORD_SELECT = "select"; //$NON-NLS-1$
+ String KEYWORD_SET = "set"; //$NON-NLS-1$
+ String KEYWORD_TRAVERSE = "traverse"; //$NON-NLS-1$
+ String KEYWORD_UNION = "union"; //$NON-NLS-1$
+ String KEYWORD_UNIQUE = "unique"; //$NON-NLS-1$
+
+ String VARIABLE_TRANSLATIONS = "translations"; //$NON-NLS-1$
+
+ String OPERATOR_ARRAY = "[]"; //$NON-NLS-1$
+ String OPERATOR_ASSIGN = "="; //$NON-NLS-1$
+ String OPERATOR_EACH = "_"; //$NON-NLS-1$
+ String OPERATOR_ELSE = ":"; //$NON-NLS-1$
+ String OPERATOR_IF = "?"; //$NON-NLS-1$
+}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Intersect.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Intersect.java
new file mode 100644
index 000000000..db6b81a5f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Intersect.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * 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.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
+
+/**
+ * n-ary <code>intersect</code> operator. The result is the set of elements that were found in all operands.
+ */
+final class Intersect extends Binary implements IQLConstants, IQLExpression {
+ Intersect(Expression operand, Expression param) {
+ super(operand, param);
+ }
+
+ public Object evaluate(IEvaluationContext context) {
+ return evaluateAsIterator(context);
+ }
+
+ public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
+ Set<?> resultSet = QLUtil.asSet(lhs.evaluate(context), false); // Safe since it will not be modified
+ Iterator<?> itor = rhs.evaluateAsIterator(context);
+ Set<Object> retained = new HashSet<Object>();
+ while (itor.hasNext()) {
+ Object value = itor.next();
+ if (resultSet.contains(value))
+ retained.add(value);
+ }
+ return RepeatableIterator.create(retained);
+ }
+
+ public int getExpressionType() {
+ return TYPE_INTERSECT;
+ }
+
+ public String getOperator() {
+ return KEYWORD_INTERSECT;
+ }
+
+ public int getPriority() {
+ return PRIORITY_COLLECTION;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Latest.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Latest.java
index c1557298a..b5c6c720e 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Latest.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Latest.java
@@ -11,8 +11,9 @@
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.*;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
import org.eclipse.equinox.p2.metadata.IVersionedId;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
/**
* An expression that is especially targeted towards {@link IVersionedId} instances. It will
@@ -87,7 +88,7 @@ final class Latest extends UnaryCollectionFilter {
return TYPE_LATEST;
}
- String getOperator() {
+ public String getOperator() {
return KEYWORD_LATEST;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Limit.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Limit.java
index 926a073b4..10b8051d7 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Limit.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Limit.java
@@ -12,12 +12,14 @@ package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.Iterator;
import java.util.NoSuchElementException;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
/**
* A collection filter that limits the number of entries in the collection
*/
-final class Limit extends Binary {
+final class Limit extends Binary implements IQLConstants, IQLExpression {
/**
* An iterator that stops iterating after a given number of iterations.
@@ -50,15 +52,17 @@ final class Limit extends Binary {
Limit(Expression operand, Expression param) {
super(operand, param);
- assertNotBoolean(operand, "operand"); //$NON-NLS-1$
- assertNotCollection(param, "parameter"); //$NON-NLS-1$
}
Limit(Expression operand, int limit) {
- this(operand, Constant.create(new Integer(limit)));
+ this(operand, (Expression) QLFactory.INSTANCE.constant(new Integer(limit)));
}
public Object evaluate(IEvaluationContext context) {
+ return evaluateAsIterator(context);
+ }
+
+ public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
Object rval = rhs.evaluate(context);
int limit = -1;
if (rval instanceof Integer)
@@ -72,25 +76,17 @@ final class Limit extends Binary {
return TYPE_LIMIT;
}
- public void toString(StringBuffer bld) {
- CollectionFilter.appendProlog(bld, lhs, getOperator());
- appendOperand(bld, rhs, PRIORITY_COMMA);
+ public void toString(StringBuffer bld, Variable rootVariable) {
+ CollectionFilter.appendProlog(bld, rootVariable, lhs, getOperator());
+ appendOperand(bld, rootVariable, rhs, IExpressionConstants.PRIORITY_COMMA);
bld.append(')');
}
- String getOperator() {
+ public String getOperator() {
return KEYWORD_LIMIT;
}
- int getPriority() {
+ public int getPriority() {
return PRIORITY_COLLECTION;
}
-
- boolean isCollection() {
- return true;
- }
-
- boolean isElementBoolean() {
- return lhs.isElementBoolean();
- }
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/MatchExpression.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/MatchExpression.java
deleted file mode 100644
index dadd153bb..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/MatchExpression.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * 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 org.eclipse.equinox.internal.p2.ql.*;
-import org.eclipse.equinox.p2.ql.*;
-
-/**
- * The match expression is the top expression in item queries. It introduces the
- * variable 'item' and initializes it with the item to match.
- */
-final class MatchExpression extends Unary implements IMatchExpression {
-
- MatchExpression(Expression expression) {
- super(expression);
- }
-
- public boolean isMatch(IEvaluationContext context, Object value) {
- Variable.ITEM.setValue(context, value);
- return operand.evaluate(context) == Boolean.TRUE;
- }
-
- public IEvaluationContext createContext(Object[] params) {
- return new SingleVariableContext(new ParameterContext(params), Variable.ITEM);
- }
-
- public IEvaluationContext createContext(Object[] params, ITranslationSupport ts) {
- IEvaluationContext context = new MultiVariableContext(new ParameterContext(params), new IExpression[] {Variable.ITEM, Variable.TRANSLATIONS});
- context.setValue(Variable.TRANSLATIONS, ts);
- return context;
- }
-
- public int getExpressionType() {
- return operand.getExpressionType();
- }
-
- public void toString(StringBuffer bld) {
- operand.toString(bld);
- }
-
- protected int getPriority() {
- return operand.getPriority();
- }
-
- String getOperator() {
- throw new UnsupportedOperationException();
- }
-
- Expression pipeFrom(Expression expr) {
- return new MatchExpression(operand.pipeFrom(expr));
- }
-
- boolean isBoolean() {
- return true;
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Matches.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Matches.java
index 6114347f4..eabf19fd7 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Matches.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Matches.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 Cloudsmith Inc. and others.
+ * Copyright (c) 2010 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
@@ -11,9 +11,9 @@
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.*;
+import org.eclipse.equinox.internal.p2.metadata.expression.Expression;
+import org.eclipse.equinox.internal.p2.metadata.expression.LDAPApproximation;
import org.eclipse.equinox.p2.metadata.*;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
-import org.eclipse.equinox.p2.ql.SimplePattern;
import org.osgi.framework.Filter;
/**
@@ -22,74 +22,18 @@ import org.osgi.framework.Filter;
* <p>The following things can be matched:</p>
* <table border="1" cellpadding="3">
* <tr><th>LHS</th><th>RHS</th><th>Implemented as</th></tr>
- * <tr><td>IProvidedCapability</td><td>IRequiredCapability</td><td>lhs.satisfies(rhs)</td></tr>
- * <tr><td>IInstallableUnit</td><td>IRequiredCapability</td><td>lhs.satisfies(rhs)</td></tr>
+ * <tr><td>IProvidedCapability</td><td>IRequirement</td><td>lhs.satisfies(rhs)</td></tr>
+ * <tr><td>IInstallableUnit</td><td>IRequirement</td><td>lhs.satisfies(rhs)</td></tr>
* <tr><td>Version</td><td>VersionRange</td><td>rhs.isIncluded(lhs)</td></tr>
* <tr><td>IInstallableUnit</td><td>Filter</td><td>rhs.matches(lhs.properties)</td></tr>
* <tr><td>Map</td><td>Filter</td><td>rhs.match(lhs)</td></tr>
- * <tr><td>String</td><td>Pattern</td><td>rhs.matcher(lhs).matches()</td></tr>
- * <tr><td>&lt;any&gt;</td><td>Class</td><td>rhs.isInstance(lhs)</td></tr>
- * <tr><td>Class</td><td>Class</td><td>rhs.isAssignableFrom(lhs)</td></tr>
+ * <tr><td>{@link String}</td><td>{@link SimplePattern}</td><td>rhs.isMatch(lhs)</td></tr>
+ * <tr><td>{@link String}</td><td>{@link LDAPApproximation}</td><td>rhs.isMatch(lhs)</td></tr>
+ * <tr><td>&lt;any&gt;</td><td>{@link Class}</td><td>rhs.isInstance(lhs)</td></tr>
+ * <tr><td>{@link Class}</td><td>{@link Class}</td><td>rhs.isAssignableFrom(lhs)</td></tr>
* </table>
*/
-final class Matches extends Binary {
- Matches(Expression lhs, Expression rhs) {
- super(lhs, rhs);
- assertNotBoolean(lhs, "lhs"); //$NON-NLS-1$
- assertNotBoolean(rhs, "rhs"); //$NON-NLS-1$
- assertNotCollection(rhs, "rhs"); //$NON-NLS-1$
- }
-
- public Object evaluate(IEvaluationContext context) {
- Object lval = lhs.evaluate(context);
- Object rval = rhs.evaluate(context);
-
- if (rval instanceof IRequirement) {
- IRequirement requirement = (IRequirement) rval;
- if (lval instanceof IInstallableUnit)
- return Boolean.valueOf(((IInstallableUnit) lval).satisfies(requirement));
- if (lval instanceof IProvidedCapability)
- return Boolean.valueOf(((IProvidedCapability) lval).satisfies(requirement));
-
- } else if (rval instanceof VersionRange) {
- if (lval instanceof Version)
- return Boolean.valueOf(((VersionRange) rval).isIncluded((Version) lval));
-
- } else if (rval instanceof SimplePattern) {
- if (lval instanceof CharSequence)
- return Boolean.valueOf(((SimplePattern) rval).isMatch((CharSequence) lval));
-
- } else if (rval instanceof IUpdateDescriptor) {
- if (lval instanceof IInstallableUnit)
- return Boolean.valueOf(((IUpdateDescriptor) rval).isUpdateOf((IInstallableUnit) lval));
-
- } else if (rval instanceof Filter) {
- if (lval instanceof IInstallableUnit)
- return Boolean.valueOf(((Filter) rval).match(new Hashtable<String, String>(((IInstallableUnit) lval).getProperties())));
- if (lval instanceof Dictionary<?, ?>)
- return Boolean.valueOf(((Filter) rval).match((Dictionary<?, ?>) lval));
- if (lval instanceof Map<?, ?>)
- return Boolean.valueOf(((Filter) rval).match(new Hashtable<Object, Object>((Map<?, ?>) lval)));
-
- } else if (rval instanceof Locale) {
- if (lval instanceof String)
- return Boolean.valueOf(matchLocaleVariants((Locale) rval, (String) lval));
-
- } else if (rval instanceof Class<?>) {
- Class<?> rclass = (Class<?>) rval;
- return Boolean.valueOf(lval instanceof Class<?> ? rclass.isAssignableFrom((Class<?>) lval) : rclass.isInstance(lval));
- }
-
- if (lval == null || rval == null)
- return Boolean.FALSE;
-
- throw new IllegalArgumentException("Cannot match a " + lval.getClass().getName() + " with a " + rval.getClass().getName()); //$NON-NLS-1$//$NON-NLS-2$
- }
-
- public int getExpressionType() {
- return TYPE_MATCHES;
- }
-
+final class Matches extends org.eclipse.equinox.internal.p2.metadata.expression.Matches {
private static boolean equals(String a, String b, int startPos, int endPos) {
if (endPos - startPos != b.length())
return false;
@@ -118,11 +62,35 @@ final class Matches extends Binary {
: equals(lval, rval.getCountry(), countryStart, uscore) && equals(lval, rval.getVariant(), uscore + 1, lval.length());
}
- String getOperator() {
- return OPERATOR_MATCHES;
+ Matches(Expression lhs, Expression rhs) {
+ super(lhs, rhs);
}
- boolean isBoolean() {
- return true;
+ protected boolean match(Object lval, Object rval) {
+ if (rval instanceof IRequirement) {
+ IRequirement requirement = (IRequirement) rval;
+ if (lval instanceof IInstallableUnit)
+ return Boolean.valueOf(((IInstallableUnit) lval).satisfies(requirement));
+ } else if (rval instanceof VersionRange) {
+ if (lval instanceof Version)
+ return Boolean.valueOf(((VersionRange) rval).isIncluded((Version) lval));
+
+ } else if (rval instanceof IUpdateDescriptor) {
+ if (lval instanceof IInstallableUnit)
+ return Boolean.valueOf(((IUpdateDescriptor) rval).isUpdateOf((IInstallableUnit) lval));
+
+ } else if (rval instanceof Filter) {
+ if (lval instanceof IInstallableUnit)
+ return Boolean.valueOf(((Filter) rval).match(new Hashtable<String, String>(((IInstallableUnit) lval).getProperties())));
+ if (lval instanceof Dictionary<?, ?>)
+ return Boolean.valueOf(((Filter) rval).match((Dictionary<?, ?>) lval));
+ if (lval instanceof Map<?, ?>)
+ return Boolean.valueOf(((Filter) rval).match(new Hashtable<Object, Object>((Map<?, ?>) lval)));
+
+ } else if (rval instanceof Locale) {
+ if (lval instanceof String)
+ return Boolean.valueOf(matchLocaleVariants((Locale) rval, (String) lval));
+ }
+ return super.match(lval, rval);
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Member.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Member.java
deleted file mode 100644
index 21c99e40c..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Member.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*******************************************************************************
- * 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.lang.reflect.*;
-import java.util.Iterator;
-import org.eclipse.equinox.p2.metadata.IRequirement;
-import org.eclipse.equinox.p2.ql.*;
-
-/**
- * <p>An expression that performs member calls to obtain some value
- * from some object instance. It uses standard bean semantics so
- * that an attempt to obtain &quot;value&quot; will cause an
- * attempt to call <code>getValue()</code> and if no such method
- * exists, <code>isValue()</code> and if that doesn't work either,
- * <code>value()</code>.</p>
- */
-abstract class Member extends Unary {
-
- static Member createDynamicMember(Expression operand, String name) {
- return new DynamicMember(operand, name);
- }
-
- static final Object[] NO_ARGS = new Object[0];
-
- final String name;
- final Expression[] argExpressions;
-
- static abstract class CapabilityIndexMethod extends Member {
- public CapabilityIndexMethod(Expression operand, String name, Expression[] args) {
- super(operand, name, args);
- }
-
- final ICapabilityIndex getSelf(IEvaluationContext context) {
- Object self = operand.evaluate(context);
- if (self instanceof ICapabilityIndex)
- return (ICapabilityIndex) self;
- throw new IllegalArgumentException("lhs of member expected to be an ICapabilityIndex implementation"); //$NON-NLS-1$
- }
-
- public final Object evaluate(IEvaluationContext context) {
- return evaluateAsIterator(context);
- }
-
- boolean isCollection() {
- return true;
- }
- }
-
- static final class CapabilityIndex_satisfiesAny extends CapabilityIndexMethod {
-
- public CapabilityIndex_satisfiesAny(Expression operand, Expression[] argExpressions) {
- super(operand, KEYWORD_SATISFIES_ANY, NAry.assertLength(argExpressions, 1, 1, KEYWORD_SATISFIES_ANY));
- }
-
- @SuppressWarnings("unchecked")
- public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
- return getSelf(context).satisfiesAny((Iterator<IRequirement>) argExpressions[0].evaluateAsIterator(context));
- }
- }
-
- static final class CapabilityIndex_satisfiesAll extends CapabilityIndexMethod {
-
- public CapabilityIndex_satisfiesAll(Expression operand, Expression[] argExpressions) {
- super(operand, KEYWORD_SATISFIES_ALL, NAry.assertLength(argExpressions, 1, 1, KEYWORD_SATISFIES_ALL));
- }
-
- @SuppressWarnings("unchecked")
- public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
- return getSelf(context).satisfiesAll((Iterator<IRequirement>) argExpressions[0].evaluateAsIterator(context));
- }
- }
-
- public boolean accept(IExpressionVisitor visitor) {
- if (super.accept(visitor))
- for (int idx = 0; idx < argExpressions.length; ++idx)
- if (!argExpressions[idx].accept(visitor))
- return false;
- return true;
- }
-
- Member(Expression operand, String name, Expression[] args) {
- super(operand);
- this.name = name;
- this.argExpressions = args;
- }
-
- public int getExpressionType() {
- return TYPE_MEMBER;
- }
-
- public void toString(StringBuffer bld) {
- if (operand == Variable.ITEM || operand == Variable.EVERYTHING)
- bld.append(name);
- else {
- appendOperand(bld, operand, getPriority());
- bld.append('.');
- bld.append(name);
- }
- if (argExpressions.length > 0) {
- bld.append('(');
- Array.elementsToString(bld, argExpressions);
- bld.append(')');
- }
- }
-
- String getOperator() {
- return OPERATOR_MEMBER;
- }
-
- int getPriority() {
- return PRIORITY_MEMBER;
- }
-
- static final class DynamicMember extends Member {
- private static final Class<?>[] NO_ARG_TYPES = new Class[0];
- private static final String GET_PREFIX = "get"; //$NON-NLS-1$
- private static final String IS_PREFIX = "is"; //$NON-NLS-1$
-
- DynamicMember(Expression operand, String name) {
- super(operand, name, Expression.emptyArray);
- if (!(name.startsWith(GET_PREFIX) || name.startsWith(IS_PREFIX)))
- name = GET_PREFIX + Character.toUpperCase(name.charAt(0)) + name.substring(1);
- this.methodName = name;
- }
-
- private Class<?> lastClass;
- private Method method;
- private String methodName;
-
- public Object evaluate(IEvaluationContext context) {
- return invoke(operand.evaluate(context));
- }
-
- boolean isReferencingTranslations() {
- return VARIABLE_TRANSLATIONS.equals(name);
- }
-
- Object invoke(Object self) {
- if (self == null)
- throw new IllegalArgumentException("Cannot access member " + name + " in null"); //$NON-NLS-1$//$NON-NLS-2$
-
- Class<?> c = self.getClass();
- if (lastClass == null || !lastClass.isAssignableFrom(c)) {
- Method m;
- for (;;) {
- try {
- m = c.getMethod(methodName, NO_ARG_TYPES);
- if (!Modifier.isPublic(m.getModifiers()))
- throw new NoSuchMethodException();
- break;
- } catch (NoSuchMethodException e) {
- if (methodName.startsWith(GET_PREFIX))
- // Switch from using getXxx() to isXxx()
- methodName = IS_PREFIX + Character.toUpperCase(name.charAt(0)) + name.substring(1);
- else if (methodName.startsWith(IS_PREFIX))
- // Switch from using isXxx() to xxx()
- methodName = name;
- else
- throw new IllegalArgumentException("Cannot find a public member " + name + " in a " + self.getClass().getName()); //$NON-NLS-1$//$NON-NLS-2$
- }
- }
-
- // Since we already checked that it's public. This will speed
- // up the calls a bit.
- m.setAccessible(true);
- lastClass = c;
- method = m;
- }
-
- Exception checked;
- try {
- return method.invoke(self, NO_ARGS);
- } catch (IllegalArgumentException e) {
- throw e;
- } catch (IllegalAccessException e) {
- checked = e;
- } catch (InvocationTargetException e) {
- Throwable cause = e.getTargetException();
- if (cause instanceof RuntimeException)
- throw (RuntimeException) cause;
- if (cause instanceof Error)
- throw (Error) cause;
- checked = (Exception) cause;
- }
- throw new RuntimeException("Problem invoking " + methodName + " on a " + self.getClass().getName(), checked); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/NAry.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/NAry.java
deleted file mode 100644
index 22595deb7..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/NAry.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*******************************************************************************
- * 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 org.eclipse.equinox.p2.ql.IExpressionVisitor;
-
-/**
- * The abstract baseclass for all N-ary expressions
- *
- */
-abstract class NAry extends Expression {
- static Expression[] assertLength(Expression[] operands, int length, String operand) {
- if (operands == null)
- operands = emptyArray;
- if (operands.length < length)
- throw new IllegalArgumentException("Not enough operands for " + operand); //$NON-NLS-1$
- return operands;
- }
-
- static Expression[] assertLength(Expression[] operands, int minLength, int maxLength, String operand) {
- if (operands == null)
- operands = emptyArray;
- if (operands.length < minLength)
- throw new IllegalArgumentException("Not enough operands for " + operand); //$NON-NLS-1$
- if (operands.length > maxLength)
- throw new IllegalArgumentException("Too many operands for " + operand); //$NON-NLS-1$
- return operands;
- }
-
- final Expression[] operands;
-
- NAry(Expression[] operands) {
- this.operands = operands;
- }
-
- public boolean accept(IExpressionVisitor visitor) {
- if (super.accept(visitor))
- for (int idx = 0; idx < operands.length; ++idx)
- if (!operands[idx].accept(visitor))
- return false;
- return true;
- }
-
- public void toString(StringBuffer bld) {
- appendOperand(bld, operands[0], getPriority());
- for (int idx = 1; idx < operands.length; ++idx) {
- bld.append(' ');
- bld.append(getOperator());
- bld.append(' ');
- appendOperand(bld, operands[idx], getPriority());
- }
- }
-
- int countReferenceToEverything() {
- int count = 0;
- for (int idx = 0; count < 2 && idx < operands.length; ++idx)
- count += operands[idx].countReferenceToEverything();
- return count;
- }
-
- abstract String getOperator();
-
- boolean isBoolean() {
- int idx = operands.length;
- while (--idx >= 0)
- if (!operands[idx].isBoolean())
- return false;
- return true;
- }
-
- boolean isCollection() {
- int idx = operands.length;
- while (--idx >= 0)
- if (!operands[idx].isCollection())
- return false;
- return true;
- }
-
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Not.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Not.java
deleted file mode 100644
index ab7b31f53..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Not.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
- * 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 org.eclipse.equinox.p2.ql.IEvaluationContext;
-
-/**
- * An expression that yields <code>true</code> when its operand does not.
- */
-final class Not extends Unary {
- Not(Expression operand) {
- super(operand);
- }
-
- public Object evaluate(IEvaluationContext context) {
- return Boolean.valueOf(operand.evaluate(context) != Boolean.TRUE);
- }
-
- public int getExpressionType() {
- return TYPE_NOT;
- }
-
- String getOperator() {
- return OPERATOR_NOT;
- }
-
- int getPriority() {
- return PRIORITY_NOT;
- }
-
- boolean isBoolean() {
- return true;
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Or.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Or.java
deleted file mode 100644
index 4892782be..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Or.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * 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.Iterator;
-import java.util.Set;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
-
-/**
- * n-ary OR operator. This operator evaluates its first operand and then checks
- * the class of the result. If the class is {@link Boolean} then it is assumed
- * that all other operands also evaluates to a boolean and the full evaluation is
- * <code>false</code> if none of its operands evaluate to <code>true</code>. If the
- * first result was not of class {@link Boolean}, then it is assumed that it can
- * be accessed as an {@link Iterator} and that all other operands also evaluates to
- * something that can be accessed an {@link Iterator}. The OR operator will then
- * function as a UNION operator and the result is the unique sum of all elements that
- * were found in all operands.
- */
-final class Or extends NAry {
- public Or(Expression[] operands) {
- super(assertLength(operands, 2, OPERATOR_OR));
- }
-
- public Object evaluate(IEvaluationContext context) {
- Object firstValue = operands[0].evaluate(context);
-
- // Determine operation mode
- if (firstValue instanceof Boolean) {
- // The first value was boolean. Assume that the rest are too
- if (((Boolean) firstValue).booleanValue())
- return Boolean.TRUE;
-
- for (int idx = 1; idx < operands.length; ++idx) {
- if (operands[idx].evaluate(context) == Boolean.TRUE)
- return Boolean.TRUE;
- }
- return Boolean.FALSE;
- }
-
- // Not a boolean. Assume that we can use an iterator on all values
- @SuppressWarnings("unchecked")
- Set<Object> resultSet = (Set<Object>) asSet(firstValue, true);
- for (int idx = 1; idx < operands.length; ++idx) {
- Iterator<?> itor = operands[idx].evaluateAsIterator(context);
- while (itor.hasNext())
- resultSet.add(itor.next());
- }
- return resultSet;
- }
-
- public int getExpressionType() {
- return TYPE_OR;
- }
-
- String getOperator() {
- return OPERATOR_OR;
- }
-
- int getPriority() {
- return PRIORITY_OR;
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Parameter.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Parameter.java
deleted file mode 100644
index c6374ea2e..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Parameter.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * 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 org.eclipse.equinox.p2.ql.IEvaluationContext;
-
-/**
- * The abstract base class for the indexed and keyed parameters
- */
-abstract class Parameter extends Expression {
- public int getExpressionType() {
- return TYPE_PARAMETER;
- }
-
- int getPriority() {
- return PRIORITY_PARAMETER;
- }
-
- String getOperator() {
- return OPERATOR_PARAMETER;
- }
-
- static final class Indexed extends Parameter {
- final int position;
-
- Indexed(int position) {
- this.position = position;
- }
-
- public Object evaluate(IEvaluationContext context) {
- return context.getParameter(position);
- }
-
- public void toString(StringBuffer bld) {
- bld.append('$');
- bld.append(position);
- }
- }
-
- static final class Keyed extends Parameter {
- final String key;
-
- public Keyed(String key) {
- this.key = key;
- }
-
- public Object evaluate(IEvaluationContext context) {
- return context.getParameter(key);
- }
-
- public void toString(StringBuffer bld) {
- bld.append('$');
- bld.append(key);
- }
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ExpressionFactory.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/QLFactory.java
index f603dd6e0..17bbb657a 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ExpressionFactory.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/QLFactory.java
@@ -3,13 +3,20 @@ package org.eclipse.equinox.internal.p2.ql.expression;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
-import org.eclipse.equinox.internal.p2.ql.parser.IParserConstants;
-import org.eclipse.equinox.p2.ql.*;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IExpression;
+import org.eclipse.equinox.p2.ql.IContextExpression;
+import org.eclipse.equinox.p2.ql.IQLFactory;
-public class ExpressionFactory implements IExpressionFactory, IParserConstants {
- public static final IExpressionFactory INSTANCE = new ExpressionFactory();
+public class QLFactory extends ExpressionFactory implements IQLFactory, IQLConstants {
+ @SuppressWarnings("hiding")
+ public static final IQLFactory INSTANCE = new QLFactory();
- private static final Map<String, Constructor<?>> functionMap;
+ public static final Variable EVERYTHING = new Variable(IExpressionConstants.VARIABLE_EVERYTHING);
+
+ public static final Variable TRANSLATIONS = new Variable(VARIABLE_TRANSLATIONS);
+
+ protected static final Map<String, Constructor<?>> functionMap;
static {
Class<?>[] args = new Class[] {Expression[].class};
@@ -19,8 +26,8 @@ public class ExpressionFactory implements IExpressionFactory, IParserConstants {
f.put(KEYWORD_FILTER, FilterFunction.class.getConstructor(args));
f.put(KEYWORD_VERSION, VersionFunction.class.getConstructor(args));
f.put(KEYWORD_RANGE, RangeFunction.class.getConstructor(args));
- f.put(KEYWORD_SET, SetFunction.class.getConstructor(args));
f.put(KEYWORD_CLASS, ClassFunction.class.getConstructor(args));
+ f.put(KEYWORD_SET, SetFunction.class.getConstructor(args));
f.put(KEYWORD_IQUERY, WrappedIQuery.class.getConstructor(args));
f.put(KEYWORD_CAPABILITY_INDEX, CapabilityIndexFunction.class.getConstructor(args));
functionMap = Collections.unmodifiableMap(f);
@@ -29,22 +36,12 @@ public class ExpressionFactory implements IExpressionFactory, IParserConstants {
}
}
- private static Expression[] convertArray(IExpression[] operands) {
- Expression[] ops = new Expression[operands.length];
- System.arraycopy(operands, 0, ops, 0, operands.length);
- return ops;
- }
-
- private ExpressionFactory() {
- // Maintain singleton
- }
-
- public IExpression all(IExpression collection, IExpression lambda) {
- return new All((Expression) collection, (LambdaExpression) lambda);
+ public IExpression at(IExpression target, IExpression key) {
+ return new At((Expression) target, (Expression) key);
}
- public IExpression and(IExpression[] operands) {
- return new And(convertArray(operands));
+ public IExpression intersect(IExpression c1, IExpression c2) {
+ return new Intersect((Expression) c1, (Expression) c2);
}
public IExpression array(IExpression[] operands) {
@@ -55,10 +52,6 @@ public class ExpressionFactory implements IExpressionFactory, IParserConstants {
return new Assignment((Variable) variable, (Expression) expression);
}
- public IExpression at(IExpression target, IExpression key) {
- return new At((Expression) target, (Expression) key);
- }
-
public IExpression collect(IExpression collection, IExpression lambda) {
return new Collect((Expression) collection, (LambdaExpression) lambda);
}
@@ -67,24 +60,8 @@ public class ExpressionFactory implements IExpressionFactory, IParserConstants {
return new Condition((Expression) test, (Expression) ifTrue, (Expression) ifFalse);
}
- public IExpression constant(Object value) {
- return Constant.create(value);
- }
-
- public <T> IContextExpression<T> contextExpression(Class<T> elementClass, IExpression expr) {
- return new ContextExpression<T>(elementClass, (Expression) expr);
- }
-
- public IExpression dynamicMember(IExpression target, String name) {
- return new Member.DynamicMember((Expression) target, name);
- }
-
- public IExpression equals(IExpression lhs, IExpression rhs) {
- return new Equals((Expression) lhs, (Expression) rhs, false);
- }
-
- public IExpression exists(IExpression collection, IExpression lambda) {
- return new Exists((Expression) collection, (LambdaExpression) lambda);
+ public <T> IContextExpression<T> contextExpression(Class<T> elementClass, IExpression expr, Object... parameters) {
+ return new ContextExpression<T>(elementClass, (Expression) expr, parameters);
}
public IExpression first(IExpression collection, IExpression lambda) {
@@ -95,7 +72,7 @@ public class ExpressionFactory implements IExpressionFactory, IParserConstants {
return new Flatten((Expression) collection);
}
- public IExpression function(Object function, IExpression[] args) {
+ public IExpression function(Object function, IExpression... args) {
try {
return (IExpression) ((Constructor<?>) function).newInstance(new Object[] {convertArray(args)});
} catch (IllegalArgumentException e) {
@@ -116,36 +93,18 @@ public class ExpressionFactory implements IExpressionFactory, IParserConstants {
return functionMap;
}
- public IExpression greater(IExpression lhs, IExpression rhs) {
- return new Compare((Expression) lhs, (Expression) rhs, false, false);
- }
-
- public IExpression indexedParameter(int index) {
- return new Parameter.Indexed(index);
- }
-
- public IExpression keyedParameter(String key) {
- return new Parameter.Keyed(key);
- }
-
- public IExpression lambda(IExpression variable, IExpression body) {
- return new LambdaExpression((Variable) variable, (Expression) body);
- }
-
- public IExpression lambda(IExpression variable, IExpression body, IExpression[] assignments) {
+ public IExpression lambda(IExpression variable, IExpression[] assignments, IExpression body) {
+ if (assignments.length == 0)
+ return super.lambda(variable, body);
Assignment[] asgns = new Assignment[assignments.length];
System.arraycopy(assignments, 0, asgns, 0, assignments.length);
- return new LambdaExpression((Variable) variable, (Expression) body, asgns);
+ return new CurryedLambdaExpression((Variable) variable, asgns, (Expression) body);
}
public IExpression latest(IExpression collection) {
return new Latest((Expression) collection);
}
- public IExpression less(IExpression lhs, IExpression rhs) {
- return new Compare((Expression) lhs, (Expression) rhs, true, false);
- }
-
public IExpression limit(IExpression collection, IExpression limit) {
return new Limit((Expression) collection, (Expression) limit);
}
@@ -154,60 +113,29 @@ public class ExpressionFactory implements IExpressionFactory, IParserConstants {
return new Matches((Expression) lhs, (Expression) rhs);
}
- public IMatchExpression matchExpression(IExpression expr) {
- return new MatchExpression((Expression) expr);
- }
-
- public IExpression member(IExpression target, String name) {
- return new Member.DynamicMember((Expression) target, name);
- }
-
- public IExpression memberCall(IExpression target, String name, IExpression[] args) {
+ public IExpression memberCall(IExpression target, String name, IExpression... args) {
if (args.length == 0)
return member(target, name);
Expression[] eargs = convertArray(args);
- if (KEYWORD_SATISFIES_ANY.equals(name))
- return new Member.CapabilityIndex_satisfiesAny((Expression) target, eargs);
- if (KEYWORD_SATISFIES_ALL.equals(name))
- return new Member.CapabilityIndex_satisfiesAll((Expression) target, eargs);
+ if (args.length > 0) {
+ if (KEYWORD_SATISFIES_ANY.equals(name))
+ return new CapabilityIndexFunction.SatisfiesAny((Expression) target, eargs);
+ if (KEYWORD_SATISFIES_ALL.equals(name))
+ return new CapabilityIndexFunction.SatisfiesAll((Expression) target, eargs);
+ }
StringBuffer bld = new StringBuffer();
bld.append("Don't know how to do a member call with "); //$NON-NLS-1$
bld.append(name);
bld.append('(');
- Array.elementsToString(bld, eargs);
+ Expression.elementsToString(bld, null, eargs);
bld.append(')');
throw new IllegalArgumentException(bld.toString());
}
- public IExpression not(IExpression operand) {
- if (operand instanceof Equals) {
- Equals eq = (Equals) operand;
- return new Equals(eq.lhs, eq.rhs, !eq.negate);
- }
- if (operand instanceof Compare) {
- Compare cmp = (Compare) operand;
- return new Compare(cmp.lhs, cmp.rhs, !cmp.compareLess, !cmp.equalOK);
- }
- if (operand instanceof Not)
- return ((Not) operand).operand;
-
- return new Not((Expression) operand);
- }
-
- public IExpression or(IExpression[] operands) {
- return new Or(convertArray(operands));
- }
-
- public IExpression pipe(IExpression[] operands) {
- if (operands.length == 0)
- return null;
-
- Expression pipe = (Expression) operands[0];
- for (int idx = 1; idx < operands.length; ++idx)
- pipe = ((Expression) operands[idx]).pipeFrom(pipe);
- return pipe;
+ public IExpression union(IExpression c1, IExpression c2) {
+ return new Union((Expression) c1, (Expression) c2);
}
public IExpression select(IExpression collection, IExpression lambda) {
@@ -218,11 +146,15 @@ public class ExpressionFactory implements IExpressionFactory, IParserConstants {
return new Traverse((Expression) collection, (LambdaExpression) lambda);
}
- public IExpression unique(IExpression collection, IExpression cache) {
- return new Unique((Expression) collection, (Expression) cache);
+ public IExpression variable(String name) {
+ if (name.equals(IExpressionConstants.VARIABLE_EVERYTHING))
+ return EVERYTHING;
+ if (name.equals(VARIABLE_TRANSLATIONS))
+ return TRANSLATIONS;
+ return super.variable(name);
}
- public IExpression variable(String name) {
- return Variable.create(name);
+ public IExpression unique(IExpression collection, IExpression cache) {
+ return new Unique((Expression) collection, (Expression) cache);
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/QLUtil.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/QLUtil.java
new file mode 100644
index 000000000..6d790b25b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/QLUtil.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.query.IQueryResult;
+
+/**
+ * The base class of the expression tree.
+ */
+public abstract class QLUtil implements IExpression, IQLConstants {
+
+ 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 IQueryResult<?>)
+ return ((IQueryResult<?>) provider).unmodifiableSet();
+ }
+
+ if (provider instanceof Collection<?>)
+ val = provider;
+ } else {
+ if (!forcePrivateCopy) {
+ if (val instanceof Set<?>)
+ return (Set<?>) val;
+ if (val instanceof IQueryResult<?>)
+ return ((IQueryResult<?>) val).unmodifiableSet();
+ }
+ }
+
+ HashSet<Object> result;
+ if (val instanceof Collection<?>)
+ result = new HashSet<Object>((Collection<?>) val);
+ else {
+ result = new HashSet<Object>();
+ Iterator<?> iterator = RepeatableIterator.create(val);
+ while (iterator.hasNext())
+ result.add(iterator.next());
+ }
+ return result;
+ }
+
+ /**
+ * 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 static boolean needsTranslationSupport(IExpression expression) {
+ final boolean[] translationSupportNeeded = new boolean[] {false};
+ ((Expression) expression).accept(new IExpressionVisitor() {
+ public boolean visit(IExpression expr) {
+ if (expr.getExpressionType() == TYPE_MEMBER && VARIABLE_TRANSLATIONS.equals(ExpressionUtil.getName(expr))) {
+ translationSupportNeeded[0] = true;
+ return false;
+ }
+ return true;
+ }
+ });
+ return translationSupportNeeded[0];
+ }
+
+ /**
+ * 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.
+ */
+ static boolean needsRepeadedAccessToEverything(Expression expression) {
+ final boolean[] repeatedAccessNeeded = new boolean[] {false};
+ expression.accept(new IExpressionVisitor() {
+ public boolean visit(IExpression expr) {
+ // FIXME Needs proper counting
+ if (expr == QLFactory.EVERYTHING) {
+ repeatedAccessNeeded[0] = true;
+ return false;
+ }
+ return true;
+ }
+ });
+ // return repeatedAccessNeeded[0];
+ return true;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/RangeFunction.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/RangeFunction.java
index df684b342..6733f73f9 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/RangeFunction.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/RangeFunction.java
@@ -10,17 +10,16 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
+import org.eclipse.equinox.internal.p2.metadata.expression.Expression;
import org.eclipse.equinox.p2.metadata.VersionRange;
/**
* A function that creates a {@link VersionRange} from a String
*/
-final class RangeFunction extends Function {
+public final class RangeFunction extends Function {
public RangeFunction(Expression[] operands) {
super(assertLength(operands, 1, 1, KEYWORD_RANGE));
- assertNotBoolean(operands[0], "parameter"); //$NON-NLS-1$
- assertNotCollection(operands[0], "parameter"); //$NON-NLS-1$
}
boolean assertSingleArgumentClass(Object v) {
@@ -31,7 +30,7 @@ final class RangeFunction extends Function {
return new VersionRange((String) arg);
}
- String getOperator() {
+ public String getOperator() {
return KEYWORD_RANGE;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Select.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Select.java
index f54ced61d..9ea863a0e 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Select.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Select.java
@@ -11,27 +11,25 @@
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.Iterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
import org.eclipse.equinox.internal.p2.ql.MatchIteratorFilter;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
/**
* An expression that yields a new collection consisting of all elements of the
* <code>collection</code> for which the <code>filter</code> yields <code>true</code>.
*/
-final class Select extends CollectionFilter {
+final class Select extends CollectionFilter implements IQLExpression {
Select(Expression collection, LambdaExpression lambda) {
super(collection, lambda);
}
- public int getExpressionType() {
- return TYPE_SELECT;
- }
-
- Object evaluate(IEvaluationContext context, Iterator<?> itor) {
+ protected Object evaluate(IEvaluationContext context, Iterator<?> itor) {
return evaluateAsIterator(context, itor);
}
- Iterator<?> evaluateAsIterator(final IEvaluationContext context, Iterator<?> itor) {
+ protected Iterator<?> evaluateAsIterator(final IEvaluationContext context, Iterator<?> itor) {
return new MatchIteratorFilter<Object>(itor) {
protected boolean isMatch(Object val) {
lambda.getItemVariable().setValue(context, val);
@@ -40,8 +38,12 @@ final class Select extends CollectionFilter {
};
}
- String getOperator() {
- return KEYWORD_SELECT;
+ public int getExpressionType() {
+ return TYPE_SELECT;
+ }
+
+ public String getOperator() {
+ return IQLConstants.KEYWORD_SELECT;
}
boolean isCollection() {
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/SetFunction.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/SetFunction.java
index 3b0fa5248..f83275631 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/SetFunction.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/SetFunction.java
@@ -11,9 +11,10 @@
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.HashSet;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.internal.p2.metadata.expression.Expression;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
-final class SetFunction extends Function {
+public final class SetFunction extends Function implements IQLConstants {
public SetFunction(Expression[] operands) {
super(operands);
@@ -26,7 +27,7 @@ final class SetFunction extends Function {
return result;
}
- String getOperator() {
+ public String getOperator() {
return KEYWORD_SET;
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Traverse.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Traverse.java
index fcb67d6b0..e8b0c0489 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Traverse.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Traverse.java
@@ -11,9 +11,9 @@
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.*;
-import org.eclipse.equinox.internal.p2.ql.SingleVariableContext;
-import org.eclipse.equinox.internal.p2.ql.parser.IParserConstants;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
/**
* An expression that will collect items recursively based on a <code>rule</code>.
@@ -22,43 +22,39 @@ import org.eclipse.equinox.p2.ql.IEvaluationContext;
* in the new collection. All items are collected into a set and items that are already
* in that set will not be perused again. The set becomes the result of the traversal.
*/
-final class Traverse extends CollectionFilter {
+final class Traverse extends CollectionFilter implements IQLExpression {
Traverse(Expression collection, LambdaExpression lambda) {
super(collection, lambda);
}
- public int getExpressionType() {
- return TYPE_TRAVERSE;
- }
-
- Object evaluate(IEvaluationContext context, Iterator<?> itor) {
+ public Object evaluate(IEvaluationContext context, Iterator<?> itor) {
return evaluateAsIterator(context, itor);
}
- Iterator<?> evaluateAsIterator(IEvaluationContext context, Iterator<?> iterator) {
+ public Iterator<?> evaluateAsIterator(IEvaluationContext context, Iterator<?> iterator) {
HashSet<Object> collector = new HashSet<Object>();
while (iterator.hasNext())
traverse(collector, iterator.next(), context);
return collector.iterator();
}
- String getOperator() {
- return IParserConstants.KEYWORD_TRAVERSE;
+ public int getExpressionType() {
+ return TYPE_TRAVERSE;
+ }
+
+ public String getOperator() {
+ return IQLConstants.KEYWORD_TRAVERSE;
}
void traverse(Set<Object> collector, Object parent, IEvaluationContext context) {
if (collector.add(parent)) {
Variable variable = lambda.getItemVariable();
- context = new SingleVariableContext(context, variable);
+ context = EvaluationContext.create(context, variable);
variable.setValue(context, parent);
Iterator<?> subIterator = lambda.evaluateAsIterator(context);
while (subIterator.hasNext())
traverse(collector, subIterator.next(), context);
}
}
-
- boolean isCollection() {
- return true;
- }
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Unary.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Unary.java
deleted file mode 100644
index ff4e017c6..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Unary.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************************
- * 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 org.eclipse.equinox.p2.ql.IEvaluationContext;
-import org.eclipse.equinox.p2.ql.IExpressionVisitor;
-
-/**
- * The abstract base class for all unary expressions
- */
-abstract class Unary extends Expression {
- public final Expression operand;
-
- Unary(Expression operand) {
- this.operand = operand;
- }
-
- public boolean accept(IExpressionVisitor visitor) {
- return super.accept(visitor) && operand.accept(visitor);
- }
-
- public Object evaluate(IEvaluationContext context) {
- return operand.evaluate(context);
- }
-
- public void toString(StringBuffer bld) {
- bld.append(getOperator());
- appendOperand(bld, operand, getPriority());
- }
-
- public Expression getOperand() {
- return operand;
- }
-
- int countReferenceToEverything() {
- return operand.countReferenceToEverything();
- }
-
- abstract String getOperator();
-} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/UnaryCollectionFilter.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/UnaryCollectionFilter.java
index 85d2a5527..3de55abc8 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/UnaryCollectionFilter.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/UnaryCollectionFilter.java
@@ -10,37 +10,35 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
-abstract class UnaryCollectionFilter extends Unary {
+abstract class UnaryCollectionFilter extends Unary implements IQLConstants, IQLExpression {
UnaryCollectionFilter(Expression collection) {
super(collection);
}
+ public int hashCode() {
+ return 5 * operand.hashCode();
+ }
+
public Object evaluate(IEvaluationContext context) {
return evaluateAsIterator(context);
}
- public void toString(StringBuffer bld) {
+ public void toString(StringBuffer bld, Variable rootVariable) {
if (operand instanceof Select) {
Select select = (Select) operand;
- CollectionFilter.appendProlog(bld, select.operand, getOperator());
- appendOperand(bld, select.lambda, getPriority());
+ CollectionFilter.appendProlog(bld, rootVariable, select.operand, getOperator());
+ appendOperand(bld, rootVariable, select.lambda, getPriority());
} else
- CollectionFilter.appendProlog(bld, operand, getOperator());
+ CollectionFilter.appendProlog(bld, rootVariable, operand, getOperator());
bld.append(')');
}
- int getPriority() {
+ public int getPriority() {
return PRIORITY_COLLECTION;
}
-
- boolean isCollection() {
- return true;
- }
-
- boolean isElementBoolean() {
- return operand.isElementBoolean();
- }
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Union.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Union.java
new file mode 100644
index 000000000..df8049a31
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Union.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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.Iterator;
+import java.util.Set;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
+
+/**
+ */
+final class Union extends Binary implements IQLConstants, IQLExpression {
+ Union(Expression operand, Expression param) {
+ super(operand, param);
+ }
+
+ public Object evaluate(IEvaluationContext context) {
+ return evaluateAsIterator(context);
+ }
+
+ public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
+ @SuppressWarnings("unchecked")
+ Set<Object> resultSet = (Set<Object>) QLUtil.asSet(lhs.evaluate(context), true);
+ Iterator<?> itor = rhs.evaluateAsIterator(context);
+ while (itor.hasNext())
+ resultSet.add(itor.next());
+ return RepeatableIterator.create(resultSet);
+ }
+
+ public int getExpressionType() {
+ return TYPE_UNION;
+ }
+
+ public String getOperator() {
+ return KEYWORD_UNION;
+ }
+
+ public int getPriority() {
+ return PRIORITY_COLLECTION;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Unique.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Unique.java
index 6d55ba1ec..5d4953cea 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Unique.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Unique.java
@@ -11,14 +11,16 @@
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.*;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
import org.eclipse.equinox.internal.p2.ql.MatchIteratorFilter;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.ql.IQLExpression;
/**
* An expression that ensures that the elements of its collection is only returned
* once throughout the whole query.
*/
-final class Unique extends Binary {
+final class Unique extends Binary implements IQLConstants, IQLExpression {
static class UniqueIterator<T> extends MatchIteratorFilter<T> {
private final Set<T> uniqueSet;
@@ -36,12 +38,14 @@ final class Unique extends Binary {
Unique(Expression collection, Expression explicitCache) {
super(collection, explicitCache);
- assertNotBoolean(collection, "collection"); //$NON-NLS-1$
- assertNotBoolean(explicitCache, "cache"); //$NON-NLS-1$
}
- @SuppressWarnings("unchecked")
public Object evaluate(IEvaluationContext context) {
+ return evaluateAsIterator(context);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
Object explicitCache = rhs.evaluate(context);
Set<Object> uniqueSet;
if (explicitCache == null)
@@ -59,27 +63,18 @@ final class Unique extends Binary {
return TYPE_UNIQUE;
}
- public void toString(StringBuffer bld) {
- CollectionFilter.appendProlog(bld, lhs, getOperator());
- if (rhs != Constant.NULL_CONSTANT)
- appendOperand(bld, rhs, PRIORITY_COMMA);
+ public void toString(StringBuffer bld, Variable rootVariable) {
+ CollectionFilter.appendProlog(bld, rootVariable, lhs, getOperator());
+ if (rhs != Literal.NULL_CONSTANT)
+ appendOperand(bld, rootVariable, rhs, IExpressionConstants.PRIORITY_COMMA);
bld.append(')');
}
- String getOperator() {
+ public String getOperator() {
return KEYWORD_UNIQUE;
}
- int getPriority() {
+ public int getPriority() {
return PRIORITY_COLLECTION;
}
-
- boolean isCollection() {
- return true;
- }
-
- boolean isElementBoolean() {
- return lhs.isElementBoolean();
- }
-
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Variable.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Variable.java
deleted file mode 100644
index bce472fd0..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Variable.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*******************************************************************************
- * 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.Iterator;
-import org.eclipse.equinox.internal.p2.ql.IRepeatableIterator;
-import org.eclipse.equinox.internal.p2.ql.RepeatableIterator;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
-import org.eclipse.equinox.p2.ql.IExpression;
-
-/**
- * An expression representing a variable stack in the current thread.
- */
-class Variable extends Expression {
-
- static final Variable EVERYTHING = new Variable(VARIABLE_EVERYTHING);
-
- static final Variable TRANSLATIONS = new Variable(VARIABLE_TRANSLATIONS);
-
- static final Variable ITEM = new Variable(VARIABLE_ITEM);
-
- private final String name;
-
- public static Variable create(String name) {
- if (VARIABLE_ITEM.equals(name))
- return ITEM;
- if (VARIABLE_EVERYTHING.equals(name))
- return EVERYTHING;
- if (VARIABLE_TRANSLATIONS.equals(name))
- return TRANSLATIONS;
- return new Variable(name);
- }
-
- Variable(String name) {
- this.name = name;
- }
-
- public final Object evaluate(IEvaluationContext context) {
- return context.getValue(this);
- }
-
- public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
- Object value = context.getValue(this);
- if (value instanceof IRepeatableIterator<?>)
- return ((IRepeatableIterator<?>) value).getCopy();
-
- Iterator<?> itor = RepeatableIterator.create(value);
- setValue(context, itor);
- return itor;
- }
-
- public String getName() {
- return name;
- }
-
- public final void setValue(IEvaluationContext context, Object value) {
- context.setValue(this, value);
- }
-
- public void toString(StringBuffer bld) {
- bld.append(name);
- }
-
- public int getExpressionType() {
- return TYPE_VARIABLE;
- }
-
- int countReferenceToEverything() {
- return IExpression.VARIABLE_EVERYTHING.equals(name) ? 1 : 0;
- }
-
- int getPriority() {
- return PRIORITY_VARIABLE;
- }
-
- String getOperator() {
- return "<variable>"; //$NON-NLS-1$
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/VersionFunction.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/VersionFunction.java
index 1e88287e0..cef9a70b9 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/VersionFunction.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/VersionFunction.java
@@ -10,17 +10,16 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
+import org.eclipse.equinox.internal.p2.metadata.expression.Expression;
import org.eclipse.equinox.p2.metadata.Version;
/**
* A function that creates a {@link Version} from a string
*/
-final class VersionFunction extends Function {
+public final class VersionFunction extends Function {
public VersionFunction(Expression[] operands) {
super(assertLength(operands, 1, 1, KEYWORD_VERSION));
- assertNotBoolean(operands[0], "parameter"); //$NON-NLS-1$
- assertNotCollection(operands[0], "parameter"); //$NON-NLS-1$
}
boolean assertSingleArgumentClass(Object v) {
@@ -31,7 +30,7 @@ final class VersionFunction extends Function {
return Version.create((String) arg);
}
- String getOperator() {
+ public String getOperator() {
return KEYWORD_VERSION;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/WrappedIQuery.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/WrappedIQuery.java
index 7b1d88bb9..2436976af 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/WrappedIQuery.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/WrappedIQuery.java
@@ -11,16 +11,16 @@
package org.eclipse.equinox.internal.p2.ql.expression;
import java.util.Iterator;
-import org.eclipse.equinox.p2.ql.IEvaluationContext;
+import org.eclipse.equinox.internal.p2.metadata.expression.Expression;
+import org.eclipse.equinox.internal.p2.metadata.expression.ExpressionFactory;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
import org.eclipse.equinox.p2.query.IMatchQuery;
import org.eclipse.equinox.p2.query.IQuery;
-final class WrappedIQuery extends Function {
+public final class WrappedIQuery extends Function implements IQLConstants {
public WrappedIQuery(Expression[] operands) {
super(assertLength(operands, 1, 2, KEYWORD_IQUERY));
- assertNotBoolean(operands[0], "parameter"); //$NON-NLS-1$
- assertNotCollection(operands[0], "parameter"); //$NON-NLS-1$
}
@SuppressWarnings("unchecked")
@@ -32,7 +32,7 @@ final class WrappedIQuery extends Function {
if (operands.length > 1)
value = operands[1].evaluate(context);
else
- value = Variable.ITEM.evaluate(context);
+ value = ExpressionFactory.THIS.evaluate(context);
return Boolean.valueOf(((IMatchQuery<Object>) query).isMatch(value));
}
@@ -43,12 +43,12 @@ final class WrappedIQuery extends Function {
if (operands.length > 1)
iterator = operands[1].evaluateAsIterator(context);
else
- iterator = Variable.EVERYTHING.evaluateAsIterator(context);
+ iterator = QLFactory.EVERYTHING.evaluateAsIterator(context);
return ((IQuery<Object>) query).perform((Iterator<Object>) iterator);
}
- String getOperator() {
+ public String getOperator() {
return KEYWORD_IQUERY;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/ExpressionParser.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/ExpressionParser.java
deleted file mode 100644
index bd37c6d2e..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/ExpressionParser.java
+++ /dev/null
@@ -1,847 +0,0 @@
-/*******************************************************************************
- * 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.parser;
-
-import java.util.*;
-import org.eclipse.equinox.p2.ql.*;
-
-public class ExpressionParser extends Stack<IExpression> implements IParserConstants, IExpressionParser {
- private static final long serialVersionUID = 882034383978853143L;
-
- private static final int TOKEN_OR = 1;
- private static final int TOKEN_AND = 2;
-
- private static final int TOKEN_EQUAL = 10;
- private static final int TOKEN_NOT_EQUAL = 11;
- private static final int TOKEN_LESS = 12;
- private static final int TOKEN_LESS_EQUAL = 13;
- private static final int TOKEN_GREATER = 14;
- private static final int TOKEN_GREATER_EQUAL = 15;
- private static final int TOKEN_MATCHES = 16;
-
- private static final int TOKEN_NOT = 20;
- private static final int TOKEN_DOT = 21;
- private static final int TOKEN_COMMA = 22;
- private static final int TOKEN_PIPE = 23;
- private static final int TOKEN_DOLLAR = 24;
- private static final int TOKEN_IF = 25;
- private static final int TOKEN_ELSE = 26;
-
- private static final int TOKEN_LP = 30;
- private static final int TOKEN_RP = 31;
- private static final int TOKEN_LB = 32;
- private static final int TOKEN_RB = 33;
- private static final int TOKEN_LC = 34;
- private static final int TOKEN_RC = 35;
-
- private static final int TOKEN_IDENTIFIER = 40;
- private static final int TOKEN_LITERAL = 41;
- private static final int TOKEN_ANY = 42;
-
- private static final int TOKEN_NULL = 50;
- private static final int TOKEN_TRUE = 51;
- private static final int TOKEN_FALSE = 52;
-
- private static final int TOKEN_LATEST = 60;
- private static final int TOKEN_LIMIT = 61;
- private static final int TOKEN_FIRST = 62;
- private static final int TOKEN_FLATTEN = 63;
- private static final int TOKEN_UNIQUE = 64;
- private static final int TOKEN_SELECT = 65;
- private static final int TOKEN_COLLECT = 66;
- private static final int TOKEN_TRAVERSE = 67;
- private static final int TOKEN_EXISTS = 68;
- private static final int TOKEN_ALL = 69;
-
- private static final int TOKEN_END = 0;
- private static final int TOKEN_ERROR = -1;
-
- private static final Map<String, Integer> keywords;
- static {
- keywords = new HashMap<String, Integer>();
- keywords.put(KEYWORD_ALL, new Integer(TOKEN_ALL));
- keywords.put(KEYWORD_COLLECT, new Integer(TOKEN_COLLECT));
- keywords.put(KEYWORD_EXISTS, new Integer(TOKEN_EXISTS));
- keywords.put(KEYWORD_FALSE, new Integer(TOKEN_FALSE));
- keywords.put(KEYWORD_FIRST, new Integer(TOKEN_FIRST));
- keywords.put(KEYWORD_FLATTEN, new Integer(TOKEN_FLATTEN));
- keywords.put(KEYWORD_LATEST, new Integer(TOKEN_LATEST));
- keywords.put(KEYWORD_LIMIT, new Integer(TOKEN_LIMIT));
- keywords.put(KEYWORD_NULL, new Integer(TOKEN_NULL));
- keywords.put(KEYWORD_SELECT, new Integer(TOKEN_SELECT));
- keywords.put(KEYWORD_TRAVERSE, new Integer(TOKEN_TRAVERSE));
- keywords.put(KEYWORD_TRUE, new Integer(TOKEN_TRUE));
- keywords.put(KEYWORD_UNIQUE, new Integer(TOKEN_UNIQUE));
- keywords.put(OPERATOR_EACH, new Integer(TOKEN_ANY));
- }
-
- private final IExpressionFactory factory;
-
- private String expression;
- private int tokenPos;
- private int currentToken;
- private int lastTokenPos;
- private Object tokenValue;
- private String rootVariable;
-
- public ExpressionParser(IExpressionFactory factory) {
- this.factory = factory;
- }
-
- public synchronized IMatchExpression parsePredicate(String exprString) {
- expression = exprString;
- tokenPos = 0;
- currentToken = 0;
- tokenValue = null;
- rootVariable = IExpression.VARIABLE_ITEM;
- IExpression itemVariable = factory.variable(IExpression.VARIABLE_ITEM);
- push(itemVariable);
- try {
- nextToken();
- IExpression expr = currentToken == TOKEN_END ? factory.constant(Boolean.TRUE) : parseCondition();
- assertToken(TOKEN_END);
- return factory.matchExpression(expr);
- } finally {
- popVariable(); // pop item
- }
- }
-
- public synchronized <T> IContextExpression<T> parseQuery(Class<T> elementClass, String exprString) {
- expression = exprString;
- tokenPos = 0;
- currentToken = 0;
- tokenValue = null;
- rootVariable = IExpression.VARIABLE_EVERYTHING;
- IExpression everythingVariable = factory.variable(IExpression.VARIABLE_EVERYTHING);
- push(everythingVariable);
- try {
- nextToken();
- IExpression expr = parseCondition();
- assertToken(TOKEN_END);
- return factory.contextExpression(elementClass, expr);
- } finally {
- popVariable(); // pop context
- }
- }
-
- private IExpression parseCondition() {
- IExpression expr = parseOr();
- if (currentToken == TOKEN_IF) {
- nextToken();
- IExpression ifTrue = parseOr();
- assertToken(TOKEN_ELSE);
- nextToken();
- expr = factory.condition(expr, ifTrue, parseOr());
- }
- return expr;
- }
-
- private IExpression parseOr() {
- IExpression expr = parseAnd();
- if (currentToken != TOKEN_OR)
- return expr;
-
- ArrayList<IExpression> exprs = new ArrayList<IExpression>();
- exprs.add(expr);
- do {
- nextToken();
- exprs.add(parseAnd());
- } while (currentToken == TOKEN_OR);
- return factory.or(exprs.toArray(new IExpression[exprs.size()]));
- }
-
- private IExpression parseAnd() {
- IExpression expr = parseBinary();
- if (currentToken != TOKEN_AND)
- return expr;
-
- ArrayList<IExpression> exprs = new ArrayList<IExpression>();
- exprs.add(expr);
- do {
- nextToken();
- exprs.add(parseBinary());
- } while (currentToken == TOKEN_AND);
- return factory.and(exprs.toArray(new IExpression[exprs.size()]));
- }
-
- private IExpression parseBinary() {
- IExpression expr = parseNot();
- switch (currentToken) {
- case TOKEN_OR :
- case TOKEN_AND :
- case TOKEN_RP :
- case TOKEN_RB :
- case TOKEN_RC :
- case TOKEN_COMMA :
- case TOKEN_IF :
- case TOKEN_ELSE :
- case TOKEN_END :
- break;
- case TOKEN_EQUAL :
- case TOKEN_NOT_EQUAL :
- case TOKEN_GREATER :
- case TOKEN_GREATER_EQUAL :
- case TOKEN_LESS :
- case TOKEN_LESS_EQUAL :
- case TOKEN_MATCHES :
- int realToken = currentToken;
- nextToken();
- IExpression rhs = parseNot();
- switch (realToken) {
- case TOKEN_EQUAL :
- expr = factory.equals(expr, rhs);
- break;
- case TOKEN_NOT_EQUAL :
- expr = factory.not(factory.equals(expr, rhs));
- break;
- case TOKEN_GREATER :
- expr = factory.greater(expr, rhs);
- break;
- case TOKEN_GREATER_EQUAL :
- expr = factory.not(factory.less(expr, rhs));
- break;
- case TOKEN_LESS :
- expr = factory.less(expr, rhs);
- break;
- case TOKEN_LESS_EQUAL :
- expr = factory.not(factory.greater(expr, rhs));
- break;
- default :
- expr = factory.matches(expr, rhs);
- }
- break;
- default :
- throw syntaxError();
- }
- return expr;
- }
-
- private IExpression parseNot() {
- if (currentToken == TOKEN_NOT) {
- nextToken();
- IExpression expr = parseNot();
- return factory.not(expr);
- }
- return parseCollectionExpression();
- }
-
- private IExpression parseCollectionExpression() {
- IExpression expr;
- switch (currentToken) {
- case TOKEN_SELECT :
- case TOKEN_COLLECT :
- case TOKEN_EXISTS :
- case TOKEN_FIRST :
- case TOKEN_FLATTEN :
- case TOKEN_ALL :
- case TOKEN_TRAVERSE :
- case TOKEN_LATEST :
- case TOKEN_LIMIT :
- case TOKEN_UNIQUE :
- expr = getVariableOrRootMember(rootVariable);
- break;
- default :
- expr = parseMember();
- if (currentToken != TOKEN_DOT)
- return expr;
- nextToken();
- }
-
- for (;;) {
- int filterToken = currentToken;
- nextToken();
- assertToken(TOKEN_LP);
- nextToken();
- switch (filterToken) {
- case TOKEN_SELECT :
- expr = factory.select(expr, parseLambdaDefinition());
- break;
- case TOKEN_COLLECT :
- expr = factory.collect(expr, parseLambdaDefinition());
- break;
- case TOKEN_EXISTS :
- expr = factory.exists(expr, parseLambdaDefinition());
- break;
- case TOKEN_FIRST :
- expr = factory.first(expr, parseLambdaDefinition());
- break;
- case TOKEN_ALL :
- expr = factory.all(expr, parseLambdaDefinition());
- break;
- case TOKEN_TRAVERSE :
- expr = factory.traverse(expr, parseLambdaDefinition());
- break;
- case TOKEN_LATEST :
- if (currentToken == TOKEN_RP) {
- expr = factory.latest(expr);
- assertToken(TOKEN_RP);
- nextToken();
- } else
- expr = factory.latest(factory.select(expr, parseLambdaDefinition()));
- break;
- case TOKEN_FLATTEN :
- if (currentToken == TOKEN_RP) {
- expr = factory.flatten(expr);
- assertToken(TOKEN_RP);
- nextToken();
- } else
- expr = factory.flatten(factory.select(expr, parseLambdaDefinition()));
- break;
- case TOKEN_LIMIT :
- expr = factory.limit(expr, parseCondition());
- assertToken(TOKEN_RP);
- nextToken();
- break;
- case TOKEN_UNIQUE :
- if (currentToken == TOKEN_RP)
- expr = factory.unique(expr, factory.constant(null));
- else {
- expr = factory.unique(expr, parseMember());
- assertToken(TOKEN_RP);
- nextToken();
- }
- break;
- default :
- throw syntaxError();
- }
- if (currentToken != TOKEN_DOT)
- break;
- nextToken();
- }
- return expr;
- }
-
- private IExpression parseMember() {
- IExpression expr = parseConstructor();
- String name;
- while (currentToken == TOKEN_DOT || currentToken == TOKEN_LB) {
- int savePos = tokenPos;
- int saveToken = currentToken;
- Object saveTokenValue = tokenValue;
- nextToken();
- if (saveToken == TOKEN_DOT) {
- switch (currentToken) {
- case TOKEN_SELECT :
- case TOKEN_COLLECT :
- case TOKEN_EXISTS :
- case TOKEN_FIRST :
- case TOKEN_FLATTEN :
- case TOKEN_ALL :
- case TOKEN_TRAVERSE :
- case TOKEN_LATEST :
- case TOKEN_LIMIT :
- case TOKEN_UNIQUE :
- tokenPos = savePos;
- currentToken = saveToken;
- tokenValue = saveTokenValue;
- return expr;
-
- case TOKEN_IDENTIFIER :
- name = (String) tokenValue;
- nextToken();
- if (currentToken == TOKEN_LP) {
- nextToken();
- IExpression[] callArgs = parseArray();
- assertToken(TOKEN_RP);
- nextToken();
- expr = factory.memberCall(expr, name, callArgs);
- } else
- expr = factory.memberCall(expr, name, IExpressionFactory.NO_ARGS);
- break;
-
- default :
- throw syntaxError();
- }
- } else {
- IExpression atExpr = parseMember();
- assertToken(TOKEN_RB);
- nextToken();
- expr = factory.at(expr, atExpr);
- }
- }
- return expr;
- }
-
- private IExpression parseLambdaDefinition() {
- boolean endingRC = false;
- int anyIndex = -1;
- IExpression[] initializers = IExpressionFactory.NO_ARGS;
- IExpression[] variables;
- if (currentToken == TOKEN_LC) {
- // Lambda starts without currying.
- endingRC = true;
- nextToken();
- anyIndex = 0;
- variables = parseVariables();
- if (variables == null)
- // empty means no pipe at the end.
- throw syntaxError();
- } else {
- anyIndex = 0;
- variables = parseVariables();
- if (variables == null) {
- anyIndex = -1;
- initializers = parseArray();
- assertToken(TOKEN_LC);
- nextToken();
- endingRC = true;
- for (int idx = 0; idx < initializers.length; ++idx) {
- IExpression initializer = initializers[idx];
- if (initializer.getExpressionType() == IExpression.TYPE_VARIABLE && OPERATOR_EACH.equals(initializer.toString())) {
- if (anyIndex == -1)
- anyIndex = idx;
- else
- anyIndex = -1; // Second Each. This is illegal
- break;
- }
- }
- if (anyIndex == -1)
- throw new IllegalArgumentException("Exaclty one _ must be present among the currying expressions"); //$NON-NLS-1$
-
- variables = parseVariables();
- if (variables == null)
- // empty means no pipe at the end.
- throw syntaxError();
- }
-
- }
- nextToken();
- IExpression body = parseCondition();
- if (endingRC) {
- assertToken(TOKEN_RC);
- nextToken();
- }
-
- assertToken(TOKEN_RP);
- nextToken();
- IExpression each;
- IExpression[] assignments;
- if (initializers.length == 0) {
- if (variables.length != 1)
- throw new IllegalArgumentException("Must have exactly one variable unless currying is used"); //$NON-NLS-1$
- each = variables[0];
- assignments = IExpressionFactory.NO_ARGS;
- } else {
- if (initializers.length != variables.length)
- throw new IllegalArgumentException("Number of currying expressions and variables differ"); //$NON-NLS-1$
-
- if (initializers.length == 1) {
- // This is just a map from _ to some variable
- each = variables[0];
- assignments = IExpressionFactory.NO_ARGS;
- } else {
- int idx;
- each = variables[anyIndex];
- assignments = new IExpression[initializers.length - 1];
- for (idx = 0; idx < anyIndex; ++idx)
- assignments[idx] = factory.assignment(variables[idx], initializers[idx]);
- for (++idx; idx < initializers.length; ++idx)
- assignments[idx] = factory.assignment(variables[idx], initializers[idx]);
- }
- }
- return factory.lambda(each, body, assignments);
- }
-
- private IExpression[] parseVariables() {
- int savePos = tokenPos;
- int saveToken = currentToken;
- Object saveTokenValue = tokenValue;
- List<Object> ids = null;
- while (currentToken == TOKEN_IDENTIFIER) {
- if (ids == null)
- ids = new ArrayList<Object>();
- ids.add(tokenValue);
- nextToken();
- if (currentToken == TOKEN_COMMA) {
- nextToken();
- continue;
- }
- break;
- }
-
- if (currentToken != TOKEN_PIPE) {
- // This was not a variable list
- tokenPos = savePos;
- currentToken = saveToken;
- tokenValue = saveTokenValue;
- return null;
- }
-
- if (ids == null)
- // Empty list but otherwise OK
- return IExpressionFactory.NO_ARGS;
-
- int top = ids.size();
- IExpression[] result = new IExpression[top];
- for (int idx = 0; idx < top; ++idx) {
- String name = (String) ids.get(idx);
- IExpression var = factory.variable(name);
- push(var);
- result[idx] = var;
- }
- return result;
- }
-
- private IExpression parseConstructor() {
- if (currentToken == TOKEN_IDENTIFIER) {
- int savePos = tokenPos;
- int saveToken = currentToken;
- Object saveTokenValue = tokenValue;
-
- Object function = factory.getFunctionMap().get(tokenValue);
- if (function != null) {
- nextToken();
- if (currentToken == TOKEN_LP) {
- nextToken();
- IExpression[] args = currentToken == TOKEN_RP ? IExpressionFactory.NO_ARGS : parseArray();
- assertToken(TOKEN_RP);
- nextToken();
- return factory.function(function, args);
- }
- tokenPos = savePos;
- currentToken = saveToken;
- tokenValue = saveTokenValue;
- }
- }
- return parseUnary();
- }
-
- private IExpression parseUnary() {
- IExpression expr;
- switch (currentToken) {
- case TOKEN_LP :
- nextToken();
- expr = parseCondition();
- assertToken(TOKEN_RP);
- nextToken();
- break;
- case TOKEN_LB :
- nextToken();
- expr = factory.array(parseArray());
- assertToken(TOKEN_RB);
- nextToken();
- break;
- case TOKEN_LITERAL :
- expr = factory.constant(tokenValue);
- nextToken();
- break;
- case TOKEN_DOLLAR :
- expr = parseParameter();
- break;
- case TOKEN_IDENTIFIER :
- expr = getVariableOrRootMember((String) tokenValue);
- nextToken();
- break;
- case TOKEN_ANY :
- expr = factory.variable(OPERATOR_EACH);
- nextToken();
- break;
- case TOKEN_NULL :
- expr = factory.constant(null);
- nextToken();
- break;
- case TOKEN_TRUE :
- expr = factory.constant(Boolean.TRUE);
- nextToken();
- break;
- case TOKEN_FALSE :
- expr = factory.constant(Boolean.FALSE);
- nextToken();
- break;
- default :
- throw syntaxError();
- }
- return expr;
- }
-
- private IExpression parseParameter() {
- if (currentToken == TOKEN_DOLLAR) {
- nextToken();
-
- IExpression param = null;
- if (currentToken == TOKEN_LITERAL && tokenValue instanceof Integer)
- param = factory.indexedParameter(((Integer) tokenValue).intValue());
- else if (currentToken == TOKEN_IDENTIFIER)
- param = factory.keyedParameter((String) tokenValue);
-
- if (param != null) {
- nextToken();
- return param;
- }
- }
- throw syntaxError();
- }
-
- private IExpression[] parseArray() {
- IExpression expr = parseCondition();
- if (currentToken != TOKEN_COMMA)
- return new IExpression[] {expr};
-
- ArrayList<IExpression> operands = new ArrayList<IExpression>();
- operands.add(expr);
- do {
- nextToken();
- if (currentToken == TOKEN_LC)
- // We don't allow lambdas in the array
- break;
- operands.add(parseCondition());
- } while (currentToken == TOKEN_COMMA);
- return operands.toArray(new IExpression[operands.size()]);
- }
-
- private void assertToken(int token) {
- if (currentToken != token)
- throw syntaxError();
- }
-
- private IExpression getVariableOrRootMember(String id) {
- int idx = size();
- while (--idx >= 0) {
- IExpression v = get(idx);
- if (id.equals(v.toString()))
- return v;
- }
-
- if (rootVariable.equals(id))
- throw syntaxError("No such variable: " + id); //$NON-NLS-1$
-
- return factory.memberCall(getVariableOrRootMember(rootVariable), id, IExpressionFactory.NO_ARGS);
- }
-
- private void nextToken() {
- tokenValue = null;
- int top = expression.length();
- char c = 0;
- while (tokenPos < top) {
- c = expression.charAt(tokenPos);
- if (!Character.isWhitespace(c))
- break;
- ++tokenPos;
- }
- if (tokenPos >= top) {
- lastTokenPos = top;
- currentToken = TOKEN_END;
- return;
- }
-
- lastTokenPos = tokenPos;
- switch (c) {
- case '|' :
- if (tokenPos + 1 < top && expression.charAt(tokenPos + 1) == '|') {
- tokenValue = OPERATOR_OR;
- currentToken = TOKEN_OR;
- tokenPos += 2;
- } else {
- currentToken = TOKEN_PIPE;
- ++tokenPos;
- }
- break;
-
- case '&' :
- if (tokenPos + 1 < top && expression.charAt(tokenPos + 1) == '&') {
- tokenValue = OPERATOR_ARRAY;
- currentToken = TOKEN_AND;
- tokenPos += 2;
- } else
- currentToken = TOKEN_ERROR;
- break;
-
- case '=' :
- if (tokenPos + 1 < top && expression.charAt(tokenPos + 1) == '=') {
- tokenValue = OPERATOR_EQUALS;
- currentToken = TOKEN_EQUAL;
- tokenPos += 2;
- } else
- currentToken = TOKEN_ERROR;
- break;
-
- case '!' :
- if (tokenPos + 1 < top && expression.charAt(tokenPos + 1) == '=') {
- tokenValue = OPERATOR_NOT_EQUALS;
- currentToken = TOKEN_NOT_EQUAL;
- tokenPos += 2;
- } else {
- currentToken = TOKEN_NOT;
- ++tokenPos;
- }
- break;
-
- case '~' :
- if (tokenPos + 1 < top && expression.charAt(tokenPos + 1) == '=') {
- tokenValue = IParserConstants.OPERATOR_MATCHES;
- currentToken = TOKEN_MATCHES;
- tokenPos += 2;
- } else
- currentToken = TOKEN_ERROR;
- break;
-
- case '>' :
- if (tokenPos + 1 < top && expression.charAt(tokenPos + 1) == '=') {
- tokenValue = OPERATOR_GT_EQUAL;
- currentToken = TOKEN_GREATER_EQUAL;
- tokenPos += 2;
- } else {
- currentToken = TOKEN_GREATER;
- ++tokenPos;
- }
- break;
-
- case '<' :
- if (tokenPos + 1 < top && expression.charAt(tokenPos + 1) == '=') {
- tokenValue = OPERATOR_LT_EQUAL;
- currentToken = TOKEN_LESS_EQUAL;
- tokenPos += 2;
- } else {
- currentToken = TOKEN_LESS;
- ++tokenPos;
- }
- break;
-
- case '?' :
- currentToken = TOKEN_IF;
- ++tokenPos;
- break;
-
- case ':' :
- currentToken = TOKEN_ELSE;
- ++tokenPos;
- break;
-
- case '.' :
- currentToken = TOKEN_DOT;
- ++tokenPos;
- break;
-
- case '$' :
- currentToken = TOKEN_DOLLAR;
- ++tokenPos;
- break;
-
- case '{' :
- currentToken = TOKEN_LC;
- ++tokenPos;
- break;
-
- case '}' :
- currentToken = TOKEN_RC;
- ++tokenPos;
- break;
-
- case '(' :
- currentToken = TOKEN_LP;
- ++tokenPos;
- break;
-
- case ')' :
- currentToken = TOKEN_RP;
- ++tokenPos;
- break;
-
- case '[' :
- currentToken = TOKEN_LB;
- ++tokenPos;
- break;
-
- case ']' :
- currentToken = TOKEN_RB;
- ++tokenPos;
- break;
-
- case ',' :
- currentToken = TOKEN_COMMA;
- ++tokenPos;
- break;
-
- case '"' :
- case '\'' : {
- int start = ++tokenPos;
- while (tokenPos < top && expression.charAt(tokenPos) != c)
- ++tokenPos;
- if (tokenPos == top) {
- tokenPos = start - 1;
- currentToken = TOKEN_ERROR;
- } else {
- tokenValue = expression.substring(start, tokenPos++);
- currentToken = TOKEN_LITERAL;
- }
- break;
- }
-
- case '/' : {
- int start = ++tokenPos;
- StringBuffer buf = new StringBuffer();
- while (tokenPos < top) {
- c = expression.charAt(tokenPos);
- if (c == '\\' && tokenPos + 1 < top) {
- c = expression.charAt(++tokenPos);
- if (c != '/')
- buf.append('\\');
- } else if (c == '/')
- break;
- buf.append(c);
- ++tokenPos;
- }
- if (tokenPos == top) {
- tokenPos = start - 1;
- currentToken = TOKEN_ERROR;
- } else {
- tokenValue = SimplePattern.compile(expression.substring(start, tokenPos++));
- currentToken = TOKEN_LITERAL;
- }
- break;
- }
-
- default :
- if (Character.isDigit(c)) {
- int start = tokenPos++;
- while (tokenPos < top && Character.isDigit(expression.charAt(tokenPos)))
- ++tokenPos;
- tokenValue = Integer.valueOf(expression.substring(start, tokenPos));
- currentToken = TOKEN_LITERAL;
- break;
- }
- if (Character.isJavaIdentifierStart(c)) {
- int start = tokenPos++;
- while (tokenPos < top && Character.isJavaIdentifierPart(expression.charAt(tokenPos)))
- ++tokenPos;
- String word = expression.substring(start, tokenPos);
- Integer token = keywords.get(word);
- if (token == null)
- currentToken = TOKEN_IDENTIFIER;
- else
- currentToken = token.intValue();
- tokenValue = word;
- break;
- }
- throw syntaxError();
- }
- }
-
- private void popVariable() {
- if (isEmpty())
- throw syntaxError();
- pop();
- }
-
- private QLParseException syntaxError() {
- Object tv = tokenValue;
- if (tv == null) {
- if (lastTokenPos >= expression.length())
- return syntaxError("Unexpeced end of expression"); //$NON-NLS-1$
- tv = expression.substring(lastTokenPos, lastTokenPos + 1);
- }
- return syntaxError("Unexpected token \"" + tv + '"'); //$NON-NLS-1$
- }
-
- private QLParseException syntaxError(String message) {
- return new QLParseException(expression, message, tokenPos);
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/IParserConstants.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/IParserConstants.java
deleted file mode 100644
index 381ad712b..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/IParserConstants.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*******************************************************************************
- * 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.parser;
-
-public interface IParserConstants {
-
- String KEYWORD_ALL = "all"; //$NON-NLS-1$
- String KEYWORD_BOOLEAN = "boolean"; //$NON-NLS-1$
- String KEYWORD_CAPABILITY_INDEX = "capabilityIndex"; //$NON-NLS-1$
- String KEYWORD_CLASS = "class"; //$NON-NLS-1$
- String KEYWORD_COLLECT = "collect"; //$NON-NLS-1$
- String KEYWORD_EXISTS = "exists"; //$NON-NLS-1$
- String KEYWORD_FALSE = "false"; //$NON-NLS-1$
- String KEYWORD_FILTER = "filter"; //$NON-NLS-1$
- String KEYWORD_FIRST = "first"; //$NON-NLS-1$
- String KEYWORD_FLATTEN = "flatten"; //$NON-NLS-1$
- String KEYWORD_IQUERY = "iquery"; //$NON-NLS-1$
- String KEYWORD_LATEST = "latest"; //$NON-NLS-1$
- String KEYWORD_LIMIT = "limit"; //$NON-NLS-1$
- String KEYWORD_LOCALIZED_KEYS = "localizedKeys"; //$NON-NLS-1$
- String KEYWORD_LOCALIZED_MAP = "localizedMap"; //$NON-NLS-1$
- String KEYWORD_LOCALIZED_PROPERTY = "localizedProperty"; //$NON-NLS-1$
- String KEYWORD_NULL = "null"; //$NON-NLS-1$
- String KEYWORD_RANGE = "range"; //$NON-NLS-1$
- String KEYWORD_SATISFIES_ALL = "satisfiesAll"; //$NON-NLS-1$
- String KEYWORD_SATISFIES_ANY = "satisfiesAny"; //$NON-NLS-1$
- String KEYWORD_SELECT = "select"; //$NON-NLS-1$
- String KEYWORD_SET = "set"; //$NON-NLS-1$
- String KEYWORD_TRAVERSE = "traverse"; //$NON-NLS-1$
- String KEYWORD_TRUE = "true"; //$NON-NLS-1$
- String KEYWORD_UNIQUE = "unique"; //$NON-NLS-1$
- String KEYWORD_VERSION = "version"; //$NON-NLS-1$
-
- String OPERATOR_AND = "&&"; //$NON-NLS-1$
- String OPERATOR_ARRAY = "[]"; //$NON-NLS-1$
- String OPERATOR_ASSIGN = "="; //$NON-NLS-1$
- String OPERATOR_AT = "[]"; //$NON-NLS-1$
- String OPERATOR_EACH = "_"; //$NON-NLS-1$
- String OPERATOR_ELSE = ":"; //$NON-NLS-1$
- String OPERATOR_EQUALS = "=="; //$NON-NLS-1$
- String OPERATOR_GT = ">"; //$NON-NLS-1$
- String OPERATOR_GT_EQUAL = ">="; //$NON-NLS-1$
- String OPERATOR_IF = "?"; //$NON-NLS-1$
- String OPERATOR_LT = "<"; //$NON-NLS-1$
- String OPERATOR_LT_EQUAL = "<="; //$NON-NLS-1$
- String OPERATOR_MATCHES = "~="; //$NON-NLS-1$
- String OPERATOR_MEMBER = "."; //$NON-NLS-1$
- String OPERATOR_NOT = "!"; //$NON-NLS-1$
- String OPERATOR_NOT_EQUALS = "!="; //$NON-NLS-1$
- String OPERATOR_OR = "||"; //$NON-NLS-1$
- String OPERATOR_PARAMETER = "$"; //$NON-NLS-1$
-
- int PRIORITY_PARAMETER = 1;
- int PRIORITY_VARIABLE = 1;
- int PRIORITY_LITERAL = 1;
- int PRIORITY_CONSTRUCTOR = 2;
- int PRIORITY_MEMBER = 3;
- int PRIORITY_COLLECTION = 4;
- int PRIORITY_NOT = 5;
- int PRIORITY_BINARY = 6;
- int PRIORITY_AND = 7;
- int PRIORITY_OR = 8;
- int PRIORITY_CONDITION = 9;
- int PRIORITY_ASSIGNMENT = 10;
- int PRIORITY_LAMBDA = 11;
- int PRIORITY_COMMA = 12;
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/QLParser.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/QLParser.java
new file mode 100644
index 000000000..9a281dfd8
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/QLParser.java
@@ -0,0 +1,384 @@
+/*******************************************************************************
+ * 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.parser;
+
+import java.util.*;
+import org.eclipse.equinox.internal.p2.metadata.expression.IExpressionConstants;
+import org.eclipse.equinox.internal.p2.metadata.expression.Variable;
+import org.eclipse.equinox.internal.p2.metadata.expression.parser.ExpressionParser;
+import org.eclipse.equinox.internal.p2.ql.expression.IQLConstants;
+import org.eclipse.equinox.p2.metadata.expression.IExpression;
+import org.eclipse.equinox.p2.metadata.expression.IExpressionFactory;
+import org.eclipse.equinox.p2.ql.IQLFactory;
+import org.eclipse.equinox.p2.ql.IQLParser;
+
+public class QLParser extends ExpressionParser implements IQLParser, IQLConstants {
+ private static final long serialVersionUID = 882034383978853143L;
+
+ private static final int TOKEN_ANY = 42;
+
+ private static final int TOKEN_LATEST = 70;
+ private static final int TOKEN_LIMIT = 71;
+ private static final int TOKEN_FIRST = 72;
+ private static final int TOKEN_FLATTEN = 73;
+ private static final int TOKEN_UNIQUE = 74;
+ private static final int TOKEN_SELECT = 75;
+ private static final int TOKEN_COLLECT = 76;
+ private static final int TOKEN_TRAVERSE = 77;
+ private static final int TOKEN_INTERSECT = 78;
+ private static final int TOKEN_UNION = 79;
+
+ private static final Map<String, Integer> qlKeywords;
+ static {
+ qlKeywords = new HashMap<String, Integer>();
+ qlKeywords.putAll(keywords);
+ qlKeywords.put(KEYWORD_COLLECT, new Integer(TOKEN_COLLECT));
+ qlKeywords.put(KEYWORD_FALSE, new Integer(TOKEN_FALSE));
+ qlKeywords.put(KEYWORD_FIRST, new Integer(TOKEN_FIRST));
+ qlKeywords.put(KEYWORD_FLATTEN, new Integer(TOKEN_FLATTEN));
+ qlKeywords.put(KEYWORD_LATEST, new Integer(TOKEN_LATEST));
+ qlKeywords.put(KEYWORD_LIMIT, new Integer(TOKEN_LIMIT));
+ qlKeywords.put(KEYWORD_NULL, new Integer(TOKEN_NULL));
+ qlKeywords.put(KEYWORD_SELECT, new Integer(TOKEN_SELECT));
+ qlKeywords.put(KEYWORD_TRAVERSE, new Integer(TOKEN_TRAVERSE));
+ qlKeywords.put(KEYWORD_TRUE, new Integer(TOKEN_TRUE));
+ qlKeywords.put(KEYWORD_UNIQUE, new Integer(TOKEN_UNIQUE));
+ qlKeywords.put(KEYWORD_INTERSECT, new Integer(TOKEN_INTERSECT));
+ qlKeywords.put(KEYWORD_UNION, new Integer(TOKEN_UNION));
+ qlKeywords.put(OPERATOR_EACH, new Integer(TOKEN_ANY));
+ }
+
+ public QLParser(IQLFactory factory) {
+ super(factory);
+ }
+
+ public synchronized IExpression parseQuery(String exprString) {
+ expression = exprString;
+ tokenPos = 0;
+ currentToken = 0;
+ tokenValue = null;
+ rootVariable = IExpressionConstants.VARIABLE_EVERYTHING;
+ IExpression everythingVariable = factory.variable(IExpressionConstants.VARIABLE_EVERYTHING);
+ push(everythingVariable);
+ try {
+ nextToken();
+ IExpression expr = parseCondition();
+ assertToken(TOKEN_END);
+ return expr;
+ } finally {
+ popVariable(); // pop context
+ }
+ }
+
+ protected Map<String, Integer> keywordToTokenMap() {
+ return qlKeywords;
+ }
+
+ protected IExpression parseCondition() {
+ IExpression expr = parseOr();
+ if (currentToken == TOKEN_IF) {
+ nextToken();
+ IExpression ifTrue = parseOr();
+ assertToken(TOKEN_ELSE);
+ nextToken();
+ expr = qlFactory().condition(expr, ifTrue, parseOr());
+ }
+ return expr;
+ }
+
+ protected IExpression parseMember() {
+ IExpression expr = parseFunction();
+ String name;
+ while (currentToken == TOKEN_DOT || currentToken == TOKEN_LB) {
+ int savePos = tokenPos;
+ int saveToken = currentToken;
+ Object saveTokenValue = tokenValue;
+ nextToken();
+ if (saveToken == TOKEN_DOT) {
+ switch (currentToken) {
+ case TOKEN_IDENTIFIER :
+ name = (String) tokenValue;
+ nextToken();
+ if (currentToken == TOKEN_LP) {
+ nextToken();
+ IExpression[] callArgs = parseArray();
+ assertToken(TOKEN_RP);
+ nextToken();
+ expr = qlFactory().memberCall(expr, name, callArgs);
+ } else
+ expr = factory.member(expr, name);
+ break;
+
+ default :
+ tokenPos = savePos;
+ currentToken = saveToken;
+ tokenValue = saveTokenValue;
+ return expr;
+ }
+ } else {
+ IExpression atExpr = parseMember();
+ assertToken(TOKEN_RB);
+ nextToken();
+ expr = factory.at(expr, atExpr);
+ }
+ }
+ return expr;
+ }
+
+ protected IExpression parseFunction() {
+ if (currentToken == TOKEN_IDENTIFIER) {
+ Object function = qlFactory().getFunctionMap().get(tokenValue);
+ if (function != null) {
+ int savePos = tokenPos;
+ int saveToken = currentToken;
+ Object saveTokenValue = tokenValue;
+
+ nextToken();
+ if (currentToken == TOKEN_LP) {
+ nextToken();
+ IExpression[] args = currentToken == TOKEN_RP ? IExpressionFactory.NO_ARGS : parseArray();
+ assertToken(TOKEN_RP);
+ nextToken();
+ return qlFactory().function(function, args);
+ }
+ tokenPos = savePos;
+ currentToken = saveToken;
+ tokenValue = saveTokenValue;
+ }
+ }
+ return parseUnary();
+ }
+
+ protected IQLFactory qlFactory() {
+ return (IQLFactory) factory;
+ }
+
+ protected IExpression parseCollectionLHS() {
+ IExpression expr;
+ switch (currentToken) {
+ case TOKEN_SELECT :
+ case TOKEN_COLLECT :
+ case TOKEN_FIRST :
+ case TOKEN_FLATTEN :
+ case TOKEN_TRAVERSE :
+ case TOKEN_LATEST :
+ case TOKEN_LIMIT :
+ case TOKEN_INTERSECT :
+ case TOKEN_UNION :
+ case TOKEN_UNIQUE :
+ expr = getVariableOrRootMember(rootVariable);
+ break;
+ default :
+ expr = super.parseCollectionLHS();
+ }
+ return expr;
+ }
+
+ protected IExpression parseCollectionRHS(IExpression expr, int funcToken) {
+ switch (funcToken) {
+ case TOKEN_SELECT :
+ expr = qlFactory().select(expr, parseLambdaDefinition());
+ break;
+ case TOKEN_COLLECT :
+ expr = qlFactory().collect(expr, parseLambdaDefinition());
+ break;
+ case TOKEN_FIRST :
+ expr = qlFactory().first(expr, parseLambdaDefinition());
+ break;
+ case TOKEN_TRAVERSE :
+ expr = qlFactory().traverse(expr, parseLambdaDefinition());
+ break;
+ case TOKEN_LATEST :
+ if (currentToken == TOKEN_RP) {
+ expr = qlFactory().latest(expr);
+ assertToken(TOKEN_RP);
+ nextToken();
+ } else
+ expr = qlFactory().latest(qlFactory().select(expr, parseLambdaDefinition()));
+ break;
+ case TOKEN_FLATTEN :
+ if (currentToken == TOKEN_RP) {
+ expr = qlFactory().flatten(expr);
+ assertToken(TOKEN_RP);
+ nextToken();
+ } else
+ expr = qlFactory().flatten(qlFactory().select(expr, parseLambdaDefinition()));
+ break;
+ case TOKEN_LIMIT :
+ expr = qlFactory().limit(expr, parseCondition());
+ assertToken(TOKEN_RP);
+ nextToken();
+ break;
+ case TOKEN_INTERSECT :
+ expr = qlFactory().intersect(expr, parseCondition());
+ assertToken(TOKEN_RP);
+ nextToken();
+ break;
+ case TOKEN_UNION :
+ expr = qlFactory().union(expr, parseCondition());
+ assertToken(TOKEN_RP);
+ nextToken();
+ break;
+ case TOKEN_UNIQUE :
+ if (currentToken == TOKEN_RP)
+ expr = qlFactory().unique(expr, factory.constant(null));
+ else {
+ expr = qlFactory().unique(expr, parseMember());
+ assertToken(TOKEN_RP);
+ nextToken();
+ }
+ break;
+ default :
+ expr = super.parseCollectionRHS(expr, funcToken);
+ }
+ return expr;
+ }
+
+ protected IExpression parseUnary() {
+ IExpression expr;
+ switch (currentToken) {
+ case TOKEN_LB :
+ nextToken();
+ expr = qlFactory().array(parseArray());
+ assertToken(TOKEN_RB);
+ nextToken();
+ break;
+ case TOKEN_ANY :
+ expr = factory.variable(IQLConstants.OPERATOR_EACH);
+ nextToken();
+ break;
+ default :
+ expr = super.parseUnary();
+ }
+ return expr;
+ }
+
+ protected IExpression parseLambdaDefinition() {
+ boolean endingRC = false;
+ int anyIndex = -1;
+ IExpression[] initializers = IExpressionFactory.NO_ARGS;
+ IExpression[] variables;
+ if (currentToken == TOKEN_LC) {
+ // Lambda starts without currying.
+ endingRC = true;
+ nextToken();
+ anyIndex = 0;
+ variables = parseVariables();
+ if (variables == null)
+ // empty means no pipe at the end.
+ throw syntaxError();
+ } else {
+ anyIndex = 0;
+ variables = parseVariables();
+ if (variables == null) {
+ anyIndex = -1;
+ initializers = parseArray();
+ assertToken(TOKEN_LC);
+ nextToken();
+ endingRC = true;
+ for (int idx = 0; idx < initializers.length; ++idx) {
+ IExpression initializer = initializers[idx];
+ if (initializer instanceof Variable && IQLConstants.OPERATOR_EACH.equals(initializer.toString())) {
+ if (anyIndex == -1)
+ anyIndex = idx;
+ else
+ anyIndex = -1; // Second Each. This is illegal
+ break;
+ }
+ }
+ if (anyIndex == -1)
+ throw new IllegalArgumentException("Exaclty one _ must be present among the currying expressions"); //$NON-NLS-1$
+
+ variables = parseVariables();
+ if (variables == null)
+ // empty means no pipe at the end.
+ throw syntaxError();
+ }
+
+ }
+ nextToken();
+ IExpression body = parseCondition();
+ if (endingRC) {
+ assertToken(TOKEN_RC);
+ nextToken();
+ }
+
+ assertToken(TOKEN_RP);
+ nextToken();
+ IExpression each;
+ IExpression[] assignments;
+ IQLFactory qlFactory = qlFactory();
+ if (initializers.length == 0) {
+ if (variables.length != 1)
+ throw new IllegalArgumentException("Must have exactly one variable unless currying is used"); //$NON-NLS-1$
+ each = variables[0];
+ assignments = IExpressionFactory.NO_ARGS;
+ } else {
+ if (initializers.length != variables.length)
+ throw new IllegalArgumentException("Number of currying expressions and variables differ"); //$NON-NLS-1$
+
+ if (initializers.length == 1) {
+ // This is just a map from _ to some variable
+ each = variables[0];
+ assignments = IExpressionFactory.NO_ARGS;
+ } else {
+ int idx;
+ each = variables[anyIndex];
+ assignments = new IExpression[initializers.length - 1];
+ for (idx = 0; idx < anyIndex; ++idx)
+ assignments[idx] = qlFactory.assignment(variables[idx], initializers[idx]);
+ for (++idx; idx < initializers.length; ++idx)
+ assignments[idx] = qlFactory.assignment(variables[idx], initializers[idx]);
+ }
+ }
+ return qlFactory.lambda(each, assignments, body);
+ }
+
+ private IExpression[] parseVariables() {
+ int savePos = tokenPos;
+ int saveToken = currentToken;
+ Object saveTokenValue = tokenValue;
+ List<Object> ids = null;
+ while (currentToken == TOKEN_IDENTIFIER) {
+ if (ids == null)
+ ids = new ArrayList<Object>();
+ ids.add(tokenValue);
+ nextToken();
+ if (currentToken == TOKEN_COMMA) {
+ nextToken();
+ continue;
+ }
+ break;
+ }
+
+ if (currentToken != TOKEN_PIPE) {
+ // This was not a variable list
+ tokenPos = savePos;
+ currentToken = saveToken;
+ tokenValue = saveTokenValue;
+ return null;
+ }
+
+ if (ids == null)
+ // Empty list but otherwise OK
+ return IExpressionFactory.NO_ARGS;
+
+ int top = ids.size();
+ IExpression[] result = new IExpression[top];
+ for (int idx = 0; idx < top; ++idx) {
+ String name = (String) ids.get(idx);
+ IExpression var = factory.variable(name);
+ push(var);
+ result[idx] = var;
+ }
+ return result;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IContextExpression.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IContextExpression.java
index 0b894cc92..fa0468f0f 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IContextExpression.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IContextExpression.java
@@ -11,6 +11,8 @@
package org.eclipse.equinox.p2.ql;
import java.util.Iterator;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.expression.IExpression;
/**
* This is an expression that will need access to the global variable
@@ -18,22 +20,15 @@ import java.util.Iterator;
*/
public interface IContextExpression<T> extends IExpression {
/**
- * Returns the element class
- * @return The element class
- */
- Class<T> getElementClass();
-
- /**
* <p>Creates a new context to be passed to a subsequent evaluation. The context
* will have the variable 'everything' set to an expression that represents
* the <code>everything</code> iterator filtered for instances of <code>elementClass</code>.</p>
* <p>The values of the iterator will be copied if necessary (when everything is referenced
* more then once).</p>
* @param everything The iterator that represents all queried material.
- * @param params The parameters to use for the evaluation.
* @return A new evaluation context.
*/
- IEvaluationContext createContext(Iterator<T> everything, Object[] params);
+ IEvaluationContext createContext(Iterator<T> everything);
/**
* <p>Creates a new context to be passed to a subsequent evaluation. The context
@@ -42,9 +37,27 @@ public interface IContextExpression<T> extends IExpression {
* <p>The values of the iterator will be copied if necessary (when everything is referenced
* more then once).</p>
* @param everything The iterator that represents all queried material.
- * @param params The parameters to use for the evaluation.
* @param translations A translation support object to be assigned to the variable 'translations'
* @return A new evaluation context.
*/
- IEvaluationContext createContext(Iterator<T> everything, Object[] params, ITranslationSupport translations);
+ IEvaluationContext createContext(Iterator<T> everything, ITranslationSupport translations);
+
+ /**
+ * Returns the element class
+ * @return The element class
+ */
+ Class<T> getElementClass();
+
+ /**
+ * Returns the parameters that this context expression was created with.
+ * @return An array of parameters, possibly empty but never <code>null</code>.
+ */
+ Object[] getParameters();
+
+ /**
+ * Evaluate the expression and return the expected collection result as an iterator
+ * @param context The evaluation context
+ * @return The result of the evaluation.
+ */
+ Iterator<T> iterator(IEvaluationContext context);
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IEvaluationContext.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IEvaluationContext.java
deleted file mode 100644
index efde9f3f4..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IEvaluationContext.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 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.p2.ql;
-
-/**
- * The evaluation context. Contexts can be nested and new contexts are pushed for each closure
- * during an evaluation of an expression.
- * @see IMatchExpression#createContext(Object[])
- * @see IContextExpression#createContext(java.util.Iterator, Object[])
- */
-public interface IEvaluationContext {
- /**
- * Retrieve the value of the given <code>variable</code> from this context
- * @param variable The variable who's value should be retrieved
- * @return The current value for the variable
- */
- Object getValue(IExpression variable);
-
- /**
- * Set the current value for the given <code>variable</code> to <code>value</code>
- * @param variable The variable who's value should be set
- * @param value The new value for the variable.
- */
- void setValue(IExpression variable, Object value);
-
- /**
- * Returns the value of the parameter at the given <code>position</code>
- * @param position The zero based position for the parameter
- * @return The parameter value
- */
- Object getParameter(int position);
-
- /**
- * Returns the value of the parameter at the given <code>key</code>
- * @param key The key for the parameter
- * @return The parameter value
- */
- Object getParameter(String key);
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpression.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpression.java
deleted file mode 100644
index 9f959f106..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpression.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*******************************************************************************
- * 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.p2.ql;
-
-import java.util.Iterator;
-
-/**
- * A node in the expression tree
- */
-public interface IExpression {
- int TYPE_VARIABLE = 1;
- int TYPE_PARAMETER = 2;
- int TYPE_LITERAL = 3;
- int TYPE_AND = 4;
- int TYPE_OR = 5;
- int TYPE_FUNCTION = 6;
- int TYPE_ARRAY = 7;
- int TYPE_AT = 8;
- int TYPE_MEMBER = 9;
- int TYPE_ALL = 10;
- int TYPE_EXISTS = 11;
- int TYPE_SELECT = 12;
- int TYPE_COLLECT = 13;
- int TYPE_TRAVERSE = 14;
- int TYPE_LATEST = 15;
- int TYPE_FLATTEN = 16;
- int TYPE_LIMIT = 17;
- int TYPE_FIRST = 18;
- int TYPE_LAMBDA = 19;
- int TYPE_EQUALS = 20;
- int TYPE_GREATER = 21;
- int TYPE_LESS = 22;
- int TYPE_GREATER_EQUAL = 23;
- int TYPE_LESS_EQUAL = 24;
- int TYPE_MATCHES = 25;
- int TYPE_NOT = 26;
- int TYPE_ASSIGNMENT = 27;
- int TYPE_CONDITION = 28;
- int TYPE_NOT_EQUALS = 29;
- int TYPE_UNIQUE = 30;
-
- String VARIABLE_TRANSLATIONS = "translations"; //$NON-NLS-1$
- String VARIABLE_EVERYTHING = "everything"; //$NON-NLS-1$
- String VARIABLE_ITEM = "item"; //$NON-NLS-1$
-
- /**
- * 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.
- */
- boolean accept(IExpressionVisitor visitor);
-
- /**
- * Evaluate this expression with given context and variables.
- * @param context The evaluation context
- * @return The result of the evaluation.
- */
- Object evaluate(IEvaluationContext context);
-
- /**
- * Evaluate this expression with given context and variables and return a result
- * in the form of an iterator.
- * @param context The evaluation context
- * @return The result of the evaluation.
- */
- Iterator<?> evaluateAsIterator(IEvaluationContext context);
-
- /**
- * Returns the expression type (see TYPE_xxx constants).
- */
- int getExpressionType();
-
- /**
- * Checks if this expression will need an instance of {@link ITranslationSupport} to execute
- * @return <code>true</code> if translation support is needed.
- */
- boolean needsTranslations();
-
- /**
- * A special toString method that can be used when efficient string concatenation is
- * desired. Avoids the need to create new StringBuffer instances for each concatenation
- * when traversing the expression tree.
- * @param receiver The receiver of the string representation.
- */
- void toString(StringBuffer receiver);
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpressionVisitor.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpressionVisitor.java
deleted file mode 100644
index 14a7fa038..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpressionVisitor.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*******************************************************************************
- * 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.p2.ql;
-
-/**
- * A general purpose visitor that will visit each node in an expression tree.
- */
-public interface IExpressionVisitor {
- /**
- * 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(IExpression expression);
-} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IMatchExpression.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IMatchExpression.java
deleted file mode 100644
index cd9dff4dd..000000000
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IMatchExpression.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * 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.p2.ql;
-
-/**
- * The item expression is the top expression in item queries. It introduces the
- * variable 'item' and initializes it with the item to match.
- */
-public interface IMatchExpression extends IExpression {
- /**
- * <p>Creates a new context to be passed to a subsequent evaluation. The context
- * will introduce 'item' as an uninitialized variable and make the parameters available.
- * @param params The parameters to use for the evaluation.
- * @return A new evaluation context.
- */
- IEvaluationContext createContext(Object[] params);
-
- /**
- * <p>Creates a new context to be passed to a subsequent evaluation. The context
- * will introduce 'item' as an uninitialized variable and make the parameters available.
- * @param params The parameters to use for the evaluation.
- * @param translations A translation support object to be assigned to the variable 'translations'
- * @return A new evaluation context.
- */
- IEvaluationContext createContext(Object[] params, ITranslationSupport translations);
-
- /**
- * This method assigns <code>candidate</code> to the 'item' variable of the
- * <code>context</code> and then evaluates the expression.
- * @param context A context previously created with {@link #createContext(Object[])}
- * @param candidate The object to test.
- * @return the result of the evaluation.
- */
- boolean isMatch(IEvaluationContext context, Object candidate);
-}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLExpression.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLExpression.java
new file mode 100644
index 000000000..905bb85b5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLExpression.java
@@ -0,0 +1,20 @@
+package org.eclipse.equinox.p2.ql;
+
+import org.eclipse.equinox.p2.metadata.expression.IExpression;
+
+public interface IQLExpression extends IExpression {
+ int TYPE_ARRAY = 20;
+ int TYPE_ASSIGNMENT = 21;
+ int TYPE_COLLECT = 22;
+ int TYPE_CONDITION = 23;
+ int TYPE_FIRST = 24;
+ int TYPE_FLATTEN = 25;
+ int TYPE_FUNCTION = 26;
+ int TYPE_INTERSECT = 27;
+ int TYPE_LATEST = 28;
+ int TYPE_LIMIT = 29;
+ int TYPE_SELECT = 30;
+ int TYPE_TRAVERSE = 31;
+ int TYPE_UNION = 32;
+ int TYPE_UNIQUE = 33;
+}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpressionFactory.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLFactory.java
index 3ca1ca331..501dff83f 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpressionFactory.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLFactory.java
@@ -12,30 +12,14 @@ package org.eclipse.equinox.p2.ql;
import java.util.Map;
import org.eclipse.equinox.p2.metadata.IVersionedId;
+import org.eclipse.equinox.p2.metadata.expression.IExpression;
+import org.eclipse.equinox.p2.metadata.expression.IExpressionFactory;
/**
* This inteface provides all the factory methods needed to create the all possible
* nodes of the expression tree.
*/
-public interface IExpressionFactory {
- IExpression[] NO_ARGS = new IExpression[0];
-
- /**
- * Create a collection filter that yields true if the <code>lambda</code> yields true for
- * all of the elements of the <code>collection</code>
- * @param collection The collection providing the elements to test
- * @param lambda The lambda that performs the test
- * @return A boolean expression
- */
- IExpression all(IExpression collection, IExpression lambda);
-
- /**
- * Create a logical <i>and</i> of its <code>operands</code>.
- * @param operands The boolean operands
- * @return A boolean expression
- */
- IExpression and(IExpression[] operands);
-
+public interface IQLFactory extends IExpressionFactory {
/**
* Create an array of elements.
* @param elements The elements of the array
@@ -52,15 +36,6 @@ public interface IExpressionFactory {
IExpression assignment(IExpression variable, IExpression expression);
/**
- * Create an lookup of <code>key</code> in the <code>target</code>.
- * The key expression should evaluate to a string or an integer.
- * @param target The target for the lookup
- * @param key The key to use for the lookup
- * @return A lookup expression
- */
- IExpression at(IExpression target, IExpression key);
-
- /**
* Create an expression that collects the result of evaluating each element in a new collection.
* @param collection The collection providing the elements to evaluate
* @param lambda The lambda that creates each new element
@@ -80,35 +55,13 @@ public interface IExpressionFactory {
IExpression condition(IExpression test, IExpression ifTrue, IExpression ifFalse);
/**
- * Creates an expression that evaluates to the constant <code>value</code>.
- * @param value The constant
- * @return A constant expression
- */
- IExpression constant(Object value);
-
- /**
* Creates a top level expression that represents a full query.
+ * @param elementClass The element class of the queried material
* @param expr The query
+ * @param parameters The parameters of the query
* @return A top level query expression
*/
- <T> IContextExpression<T> contextExpression(Class<T> elementClass, IExpression expr);
-
- /**
- * Create an expression that tests if <code>lhs</code> is equal to <code>rhs</code>.
- * @param lhs The left hand side value.
- * @param rhs The right hand side value.
- * @return A boolean expression
- */
- IExpression equals(IExpression lhs, IExpression rhs);
-
- /**
- * Create a collection filter that yields true if the <code>lambda</code> yields true for
- * at least one of the elements of the <code>collection</code>
- * @param collection The collection providing the elements to test
- * @param lambda The lambda that performs the test
- * @return A boolean expression
- */
- IExpression exists(IExpression collection, IExpression lambda);
+ <T> IContextExpression<T> contextExpression(Class<T> elementClass, IExpression expr, Object... parameters);
/**
* Create an expression that yields the first element of the
@@ -128,13 +81,13 @@ public interface IExpressionFactory {
IExpression flatten(IExpression collection);
/**
- * Given one of the value in the {@link Map} returned by {@link #getFunctionMap()}, this method
+ * Given one of the values in the map returned by {@link #getFunctionMap()}, this method
* returns a function expression.
* @param function The value obtained from the map.
* @param args The arguments to evaluate and pass when evaluating the function.
* @return A function expression
*/
- IExpression function(Object function, IExpression[] args);
+ IExpression function(Object function, IExpression... args);
/**
* Returns a map of functions supported by this factory. The map is keyed by
@@ -145,45 +98,22 @@ public interface IExpressionFactory {
Map<String, ? extends Object> getFunctionMap();
/**
- * Create an expression that tests if <code>lhs</code> is greater than <code>rhs</code>.
- * @param lhs The left hand side value.
- * @param rhs The right hand side value.
- * @return A boolean expression
- */
- IExpression greater(IExpression lhs, IExpression rhs);
-
- /**
- * Creates an indexed parameter expression
- * @param index The index to use
- * @return a parameter expression
- */
- IExpression indexedParameter(int index);
-
- /**
- * Creates an keyed parameter expression
- * @param key The key to use
- * @return a parameter expression
+ * Create an <i>intersection</i> of <code>c1</code> and <code>c2</code>
+ * @param c1 first collection
+ * @param c2 second collection
+ * @return An intersect expression
*/
- IExpression keyedParameter(String key);
-
- /**
- * Creates a lambda expression that takes exactly one variable. Suitable for use
- * in most collection expressions.
- * @param body The body of the lambda
- * @param variable The element variable that the lambda uses
- * @return A lambda expression
- */
- IExpression lambda(IExpression body, IExpression variable);
+ IExpression intersect(IExpression c1, IExpression c2);
/**
* Creates a lambda expression that takes more then one variable (currying). Suitable for use
* in most collection expressions.
- * @param body The body of the lambda
* @param variable The element variable that the lambda uses
+ * @param body The body of the lambda
* @param initialAssignments Assignments to evaluate once before calling the body for each element.
* @return A lambda expression with currying
*/
- IExpression lambda(IExpression body, IExpression variable, IExpression[] initialAssignments);
+ IExpression lambda(IExpression variable, IExpression[] initialAssignments, IExpression body);
/**
* Create an expression that yields a new collection consisting of the latest version of
@@ -195,14 +125,6 @@ public interface IExpressionFactory {
IExpression latest(IExpression collection);
/**
- * Create an expression that tests if <code>lhs</code> is less than <code>rhs</code>.
- * @param lhs The left hand side value.
- * @param rhs The right hand side value.
- * @return A boolean expression
- */
- IExpression less(IExpression lhs, IExpression rhs);
-
- /**
* Create an expression that yields a new collection consisting of the <i>n</i> first
* elements of the source collection where <i>n</i> is determined by <code>limit</code>.
* @param collection The source collection
@@ -211,50 +133,13 @@ public interface IExpressionFactory {
IExpression limit(IExpression collection, IExpression limit);
/**
- * Create an expression that tests if <code>lhs</code> matches <code>rhs</code>.
- * @param lhs The left hand side value.
- * @param rhs The right hand side value.
- * @return A boolean expression
- */
- IExpression matches(IExpression lhs, IExpression rhs);
-
- /**
- * Creates a top level expression suitable for predicate matching
- * @param expr The boolean expression
- * @return A top level predicate expression
- */
- IMatchExpression matchExpression(IExpression expr);
-
- /**
- * Creates a member accessor expression.
- * @param target The target for the member access
- * @param name The name of the member
- * @return A member expression
- */
- IExpression member(IExpression target, String name);
-
- /**
* Creates a member call expression.
* @param target The target for the member call
* @param name The name of the member
* @param args The arguments to use for the call
* @return A member expression
*/
- IExpression memberCall(IExpression target, String name, IExpression[] args);
-
- /**
- * Creates an expression that negates the result of evaluating its <code>operand</code>.
- * @param operand The boolean expression to negate
- * @return A boolean expression
- */
- IExpression not(IExpression operand);
-
- /**
- * Create a logical <i>or</i> of its <code>operands</code>.
- * @param operands The boolean operands
- * @return A boolean expression
- */
- IExpression or(IExpression[] operands);
+ IExpression memberCall(IExpression target, String name, IExpression... args);
/**
* Create an expression that yields a new collection consisting of all elements of the
@@ -283,6 +168,14 @@ public interface IExpressionFactory {
IExpression traverse(IExpression collection, IExpression lambda);
/**
+ * Create a <i>union</i> of <code>c1</code> and <code>c2</code>
+ * @param c1 first collection
+ * @param c2 second collection
+ * @return A union expression
+ */
+ IExpression union(IExpression c1, IExpression c2);
+
+ /**
* Create an expression that yields a new collection where each element is unique. An
* optional <code>cache</code> can be provided if the uniqueness should span a larger
* scope then just the source collection.
@@ -291,11 +184,4 @@ public interface IExpressionFactory {
* @return A collection expression
*/
IExpression unique(IExpression collection, IExpression cache);
-
- /**
- * Creates an expression that represents a variable
- * @param name The name of the variable
- * @return A variable expression
- */
- IExpression variable(String name);
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpressionParser.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLParser.java
index 5dbaf6f57..8b327a3de 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IExpressionParser.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLParser.java
@@ -10,20 +10,14 @@
*******************************************************************************/
package org.eclipse.equinox.p2.ql;
+import org.eclipse.equinox.p2.metadata.expression.IExpression;
+import org.eclipse.equinox.p2.metadata.expression.IExpressionParser;
+
/**
* A parser that produces an expression tree based on a string representation. An
- * implementation will use the {@link IExpressionFactory} to create the actual expressions
+ * implementation will use the {@link IQLFactory} to create the actual expressions
*/
-public interface IExpressionParser {
- /**
- * Create a new boolean expression. The expression will have access to the global
- * variable 'item' and to the context parameters.
- * @param exprString The string representing the boolean expression.
- * @return The resulting expression tree.
- * @throws QLParseException
- */
- IMatchExpression parsePredicate(String exprString);
-
+public interface IQLParser extends IExpressionParser {
/**
* Create an arbitrary expression. The expression will have access to the global
* variable 'everything' and to the context parameters.
@@ -31,5 +25,5 @@ public interface IExpressionParser {
* @return The resulting expression tree.
* @throws QLParseException
*/
- <T> IContextExpression<T> parseQuery(Class<T> elementClass, String exprString);
+ IExpression parseQuery(String exprString);
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QL.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QL.java
index 32633cdcd..7d34a8b9c 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QL.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QL.java
@@ -12,8 +12,8 @@ package org.eclipse.equinox.p2.ql;
import java.util.Iterator;
import org.eclipse.equinox.internal.p2.ql.QueryContext;
-import org.eclipse.equinox.internal.p2.ql.expression.ExpressionFactory;
-import org.eclipse.equinox.internal.p2.ql.parser.ExpressionParser;
+import org.eclipse.equinox.internal.p2.ql.expression.QLFactory;
+import org.eclipse.equinox.internal.p2.ql.parser.QLParser;
import org.eclipse.equinox.p2.query.IQueryable;
/**
@@ -24,16 +24,16 @@ public abstract class QL {
* Returns the default expression factory.
* @return the default expression factory.
*/
- public static IExpressionFactory getFactory() {
- return ExpressionFactory.INSTANCE;
+ public static IQLFactory getFactory() {
+ return QLFactory.INSTANCE;
}
/**
* Creates a new instance of the default expression parser.
* @return the new parser.
*/
- public static IExpressionParser newParser() {
- return new ExpressionParser(getFactory());
+ public static IQLParser newParser() {
+ return new QLParser(getFactory());
}
/**
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLContextQuery.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLContextQuery.java
index 3798627fb..83e63bbbd 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLContextQuery.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLContextQuery.java
@@ -11,6 +11,8 @@
package org.eclipse.equinox.p2.ql;
import java.util.Iterator;
+import org.eclipse.equinox.internal.p2.ql.expression.QLUtil;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
import org.eclipse.equinox.p2.query.IQueryResult;
/**
@@ -21,11 +23,10 @@ public class QLContextQuery<T> extends QLQuery<T> {
/**
* Creates a new query instance with indexed parameters.
- * @param expression The expression that represents the query.
* @param parameters Parameters to use for the query.
*/
- public QLContextQuery(IContextExpression<T> expression, Object... parameters) {
- super(expression.getElementClass(), parameters);
+ public QLContextQuery(IContextExpression<T> expression) {
+ super(expression.getElementClass());
this.expression = expression;
}
@@ -36,7 +37,7 @@ public class QLContextQuery<T> extends QLQuery<T> {
* @param parameters Parameters to use for the query.
*/
public QLContextQuery(Class<T> elementClass, String expression, Object... parameters) {
- this(parser.parseQuery(elementClass, expression), parameters);
+ this(QL.getFactory().contextExpression(elementClass, parser.parseQuery(expression), parameters));
}
public IQueryResult<T> perform(Iterator<T> iterator) {
@@ -45,13 +46,12 @@ public class QLContextQuery<T> extends QLQuery<T> {
public Iterator<T> evaluate(Iterator<T> iterator) {
IEvaluationContext ctx;
- if (expression.needsTranslations()) {
+ if (QLUtil.needsTranslationSupport(expression)) {
IQueryContext<T> queryContext = QL.newQueryContext(iterator);
- ctx = expression.createContext(iterator, parameters, queryContext.getTranslationSupport(getLocale()));
+ ctx = expression.createContext(iterator, queryContext.getTranslationSupport(getLocale()));
} else
- ctx = expression.createContext(iterator, parameters);
- @SuppressWarnings("unchecked")
- Iterator<T> result = (Iterator<T>) expression.evaluateAsIterator(ctx);
+ ctx = expression.createContext(iterator);
+ Iterator<T> result = expression.iterator(ctx);
return result;
}
@@ -64,10 +64,10 @@ public class QLContextQuery<T> extends QLQuery<T> {
// Check if we need translation support
//
IEvaluationContext ctx;
- if (expression.needsTranslations())
- ctx = expression.createContext(queryContext.iterator(), parameters, queryContext.getTranslationSupport(getLocale()));
+ if (QLUtil.needsTranslationSupport(expression))
+ ctx = expression.createContext(queryContext.iterator(), queryContext.getTranslationSupport(getLocale()));
else
- ctx = expression.createContext(queryContext.iterator(), parameters);
+ ctx = expression.createContext(queryContext.iterator());
return expression.evaluate(ctx);
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLMatchQuery.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLMatchQuery.java
index 118398a23..b06750470 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLMatchQuery.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLMatchQuery.java
@@ -12,6 +12,10 @@ package org.eclipse.equinox.p2.ql;
import java.util.ArrayList;
import java.util.Iterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.EvaluationContext;
+import org.eclipse.equinox.internal.p2.ql.expression.QLFactory;
+import org.eclipse.equinox.internal.p2.ql.expression.QLUtil;
+import org.eclipse.equinox.p2.metadata.expression.*;
import org.eclipse.equinox.p2.query.IMatchQuery;
import org.eclipse.equinox.p2.query.IQueryResult;
@@ -19,7 +23,7 @@ import org.eclipse.equinox.p2.query.IQueryResult;
* An IQuery implementation that is based on the p2 query language.
*/
public class QLMatchQuery<T> extends QLQuery<T> implements IMatchQuery<T> {
- private final IMatchExpression expression;
+ private final IMatchExpression<T> expression;
private IEvaluationContext context;
/**
@@ -28,8 +32,8 @@ public class QLMatchQuery<T> extends QLQuery<T> implements IMatchQuery<T> {
* @param expression The expression that represents the query.
* @param parameters Parameters to use for the query.
*/
- public QLMatchQuery(Class<T> instanceClass, IMatchExpression expression, Object... parameters) {
- super(instanceClass, parameters);
+ public QLMatchQuery(Class<T> instanceClass, IMatchExpression<T> expression) {
+ super(instanceClass);
this.expression = expression;
}
@@ -40,7 +44,7 @@ public class QLMatchQuery<T> extends QLQuery<T> implements IMatchQuery<T> {
* @param parameters Parameters to use for the query.
*/
public QLMatchQuery(Class<T> instanceClass, String expression, Object... parameters) {
- this(instanceClass, parser.parsePredicate(expression), parameters);
+ this(instanceClass, QL.getFactory().<T> matchExpression(parser.parse(expression), parameters));
}
/**
@@ -64,11 +68,13 @@ public class QLMatchQuery<T> extends QLQuery<T> implements IMatchQuery<T> {
}
public IQueryResult<T> perform(Iterator<T> iterator) {
- if (expression.needsTranslations()) {
+ if (QLUtil.needsTranslationSupport(expression)) {
IQueryContext<T> queryContext = QL.newQueryContext(iterator);
- context = expression.createContext(parameters, queryContext.getTranslationSupport(getLocale()));
+ IExpression translations = QLFactory.TRANSLATIONS;
+ context = EvaluationContext.create(expression.createContext(), translations);
+ context.setValue(translations, queryContext.getTranslationSupport(getLocale()));
} else
- context = expression.createContext(parameters);
+ context = expression.createContext();
prePerform();
try {
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLQuery.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLQuery.java
index a39ecb61c..07ca483fb 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLQuery.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLQuery.java
@@ -18,16 +18,12 @@ import org.eclipse.equinox.p2.query.IQuery;
* An IQuery 'context query' implementation that is based on the p2 query language.
*/
public abstract class QLQuery<T> implements IQuery<T> {
- static final IExpressionParser parser = QL.newParser();
- static final Object[] noParameters = new Object[0];
-
+ static final IQLParser parser = QL.newParser();
final Class<T> elementClass;
- final Object[] parameters;
private Locale locale;
- protected QLQuery(Class<T> elementClass, Object[] parameters) {
+ protected QLQuery(Class<T> elementClass) {
this.elementClass = elementClass;
- this.parameters = parameters;
}
public Locale getLocale() {
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QueryResult.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QueryResult.java
index e7ee396be..f42686912 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QueryResult.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QueryResult.java
@@ -3,8 +3,8 @@ package org.eclipse.equinox.p2.ql;
import java.lang.reflect.Array;
import java.util.*;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.equinox.internal.p2.ql.IRepeatableIterator;
-import org.eclipse.equinox.internal.p2.ql.RepeatableIterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.IRepeatableIterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.RepeatableIterator;
import org.eclipse.equinox.p2.query.*;
class QueryResult<T> implements IQueryResult<T> {

Back to the top