Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hallgren2010-02-19 12:13:19 +0000
committerThomas Hallgren2010-02-19 12:13:19 +0000
commit3a4abd5c6deca5395ea24bb742ab53fa21427f85 (patch)
tree9eb424ba5b281990970f584088d4ceef5bf05111
parent273e205c6904675b1b1314b6f4df5f9e962735b5 (diff)
downloadrt.equinox.p2-3a4abd5c6deca5395ea24bb742ab53fa21427f85.tar.gz
rt.equinox.p2-3a4abd5c6deca5395ea24bb742ab53fa21427f85.tar.xz
rt.equinox.p2-3a4abd5c6deca5395ea24bb742ab53fa21427f85.zip
302201 : Unify the two query approaches used in p2
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/FlatteningIterator.java64
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/KeyIndex.java84
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java34
-rw-r--r--bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/Application.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java5
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/QueryableArray.java79
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java8
-rw-r--r--bundles/org.eclipse.equinox.p2.directorywatcher/META-INF/MANIFEST.MF1
-rw-r--r--bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/CachingArtifactRepository.java4
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/query/IUProfilePropertyQuery.java21
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/query/UserVisibleRootQuery.java5
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/Generator.java5
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.repository/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/LocalMetadataRepository.java36
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/URLMetadataRepository.java33
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/.project5
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/META-INF/MANIFEST.MF5
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/OSGI-INF/expressionFactory.xml8
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/OSGI-INF/expressionParser.xml7
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/build.properties6
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/ArtifactKey.java23
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/IUMap.java25
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/Messages.java4
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/MetadataActivator.java98
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/RequiredCapability.java10
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/TranslationSupport.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CoercingComparator.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CollectionFilter.java49
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CompoundIterator.java (renamed from bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/FlattenIterator.java)31
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/ContextExpression.java73
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/EvaluationContext.java34
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Everything.java (renamed from bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/Everything.java)44
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Expression.java47
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/ExpressionFactory.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/MatchIteratorFilter.java (renamed from bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/MatchIteratorFilter.java)4
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/RepeatableIterator.java52
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/parser/ExpressionParser.java26
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/index/CapabilityIndex.java204
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/index/IdIndex.java46
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/index/Index.java123
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/messages.properties2
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/IUPropertyQuery.java45
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/LatestIUVersionQuery.java13
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/UpdateQuery.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/ExpressionUtil.java13
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IContextExpression.java44
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IEvaluationContext.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IExpressionFactory.java8
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IExpressionParser.java13
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/index/IIndex.java35
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/index/IIndexProvider.java (renamed from bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/ObjectMatchQuery.java)17
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/index/IQueryWithIndex.java18
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/CategoryMemberQuery.java33
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/CategoryQuery.java10
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/ExpressionQuery.java54
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/FragmentQuery.java23
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/GroupQuery.java10
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/InstallableUnitQuery.java63
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/PatchQuery.java10
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/CollectionResult.java53
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/AbstractPublisherAction.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/.project5
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/OSGI-INF/qlFactory.xml8
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/OSGI-INF/qlParser.xml7
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/build.properties10
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/ContextExpression.java70
-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/QLFactory.java7
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/QLUtil.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Select.java1
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Unique.java7
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/parser/QLParser.java23
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IContextExpression.java35
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLFactory.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QL.java18
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLContextQuery.java35
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLMatchQuery.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLQuery.java1
-rw-r--r--bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/ProfileSynchronizer.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/IUDescription.java8
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF1
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactKeyQuery.java69
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.ui/All p2 UI tests.launch5
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/query/QueryableMetadataRepositoryManagerTest.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/repository/CompositeMetadataRepositoryTest.java4
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/AddIUProperty.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/IUProperties.java5
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/IUPropertyRemoval.java7
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/EvaluatorTest.java31
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/PerformanceTest.java3
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/TestIndexes.java71
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/TestQueryReimplementation.java19
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java23
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/QueryProvider.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF1
-rw-r--r--bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteXMLAction.java22
97 files changed, 1651 insertions, 703 deletions
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/FlatteningIterator.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/FlatteningIterator.java
deleted file mode 100644
index 1035f1420..000000000
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/FlatteningIterator.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 IBM Corporation 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:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.equinox.internal.p2.artifact.repository;
-
-import java.util.*;
-
-/**
- * An iterator over values that are provided by iterating over collections.
- */
-public class FlatteningIterator<T> implements Iterator<T> {
- private static final Object NO_ELEMENT = new Object();
- private final Iterator<? extends Collection<T>> collectionIterator;
- private Iterator<T> currentIterator;
-
- private T nextObject = noElement();
-
- public FlatteningIterator(Iterator<? extends Collection<T>> collectionIterator) {
- this.collectionIterator = collectionIterator;
- }
-
- public boolean hasNext() {
- return positionNext();
- }
-
- public T next() {
- if (!positionNext())
- throw new NoSuchElementException();
-
- T nxt = nextObject;
- nextObject = noElement();
- return nxt;
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- private boolean positionNext() {
- if (nextObject != NO_ELEMENT)
- return true;
-
- while (currentIterator == null || !currentIterator.hasNext()) {
- if (!collectionIterator.hasNext())
- return false;
- currentIterator = collectionIterator.next().iterator();
- }
- nextObject = currentIterator.next();
- return true;
- }
-
- @SuppressWarnings("unchecked")
- private static <T> T noElement() {
- return (T) NO_ELEMENT;
- }
-} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/KeyIndex.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/KeyIndex.java
new file mode 100644
index 000000000..445543289
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/KeyIndex.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.artifact.repository.simple;
+
+import java.util.*;
+import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;
+import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
+import org.eclipse.equinox.internal.p2.metadata.index.Index;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.expression.IExpression;
+
+/**
+ * An index that maps id to IArtifactKey
+ */
+public class KeyIndex extends Index<IArtifactKey> {
+ // Memory conserving map. Stores either String -> IArtifactKey
+ // or String -> IArtifactKey[]
+ // A stored array is always length >= 2.
+ private final Map<String, Object> artifactMap;
+
+ public KeyIndex(Collection<IArtifactKey> artifactKeys) {
+ artifactMap = new HashMap<String, Object>(artifactKeys.size());
+ for (IArtifactKey ak : artifactKeys) {
+ Object prev = artifactMap.put(ak.getId(), ak);
+ if (prev != null) {
+ if (prev instanceof IArtifactKey)
+ artifactMap.put(ak.getId(), new IArtifactKey[] {(IArtifactKey) prev, ak});
+ else {
+ IArtifactKey[] prevArr = (IArtifactKey[]) prev;
+ IArtifactKey[] nxtArr = new IArtifactKey[prevArr.length + 1];
+ System.arraycopy(prevArr, 0, nxtArr, 0, prevArr.length);
+ nxtArr[prevArr.length] = ak;
+ artifactMap.put(ak.getId(), nxtArr);
+ }
+ }
+ }
+ }
+
+ public Iterator<IArtifactKey> getCandidates(IEvaluationContext ctx, IExpression variable, IExpression booleanExpr) {
+ Object queriedKeys = getQueriedIDs(ctx, variable, ArtifactKey.MEMBER_ID, booleanExpr, null);
+ if (queriedKeys == null)
+ return null;
+
+ Collection<IArtifactKey> collector = null;
+ if (queriedKeys.getClass().isArray()) {
+ Object[] keyArr = (Object[]) queriedKeys;
+ int idx = keyArr.length;
+ while (--idx >= 0) {
+ Object v = artifactMap.get(keyArr[idx]);
+ if (v == null)
+ continue;
+ if (collector == null)
+ collector = new ArrayList<IArtifactKey>();
+ if (v instanceof IArtifactKey)
+ collector.add((IArtifactKey) v);
+ else {
+ IArtifactKey[] akArr = (IArtifactKey[]) v;
+ for (IArtifactKey ak : akArr)
+ collector.add(ak);
+ }
+ }
+ if (collector == null)
+ collector = CollectionUtils.emptySet();
+ } else {
+ Object v = artifactMap.get(queriedKeys);
+ if (v == null)
+ collector = CollectionUtils.emptySet();
+ else if (v instanceof IArtifactKey)
+ collector = Collections.singleton((IArtifactKey) v);
+ else
+ collector = CollectionUtils.unmodifiableList((IArtifactKey[]) v);
+ }
+ return collector.iterator();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java
index 674df3b9d..42d5acbf2 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java
@@ -24,6 +24,8 @@ import org.eclipse.equinox.internal.p2.artifact.processors.md5.MD5Verifier;
import org.eclipse.equinox.internal.p2.artifact.repository.*;
import org.eclipse.equinox.internal.p2.artifact.repository.Messages;
import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
+import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
+import org.eclipse.equinox.internal.p2.metadata.expression.CompoundIterator;
import org.eclipse.equinox.internal.p2.repository.RepositoryTransport;
import org.eclipse.equinox.internal.p2.repository.Transport;
import org.eclipse.equinox.internal.provisional.p2.artifact.repository.processing.*;
@@ -31,6 +33,7 @@ import org.eclipse.equinox.internal.provisional.p2.repository.IStateful;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.metadata.index.*;
import org.eclipse.equinox.p2.query.*;
import org.eclipse.equinox.p2.repository.IRepository;
import org.eclipse.equinox.p2.repository.artifact.*;
@@ -38,7 +41,7 @@ import org.eclipse.equinox.p2.repository.artifact.spi.AbstractArtifactRepository
import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor;
import org.eclipse.osgi.util.NLS;
-public class SimpleArtifactRepository extends AbstractArtifactRepository implements IArtifactRepository, IFileArtifactRepository {
+public class SimpleArtifactRepository extends AbstractArtifactRepository implements IArtifactRepository, IFileArtifactRepository, IIndexProvider<IArtifactKey> {
/**
* A boolean property controlling whether mirroring is enabled.
*/
@@ -204,9 +207,10 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
/**
* Map<IArtifactKey,List<IArtifactDescriptor>> containing the index of artifacts in the repository.
*/
- protected Map<IArtifactKey, List<IArtifactDescriptor>> artifactMap = new HashMap<IArtifactKey, List<IArtifactDescriptor>>();
+ protected final Map<IArtifactKey, List<IArtifactDescriptor>> artifactMap = new HashMap<IArtifactKey, List<IArtifactDescriptor>>();
private transient BlobStore blobStore;
transient private Mapper mapper = new Mapper();
+ private KeyIndex keyIndex;
static final private String PUBLISH_PACK_FILES_AS_SIBLINGS = "publishPackFilesAsSiblings"; //$NON-NLS-1$
@@ -271,6 +275,7 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
if (descriptors == null) {
descriptors = new ArrayList<IArtifactDescriptor>();
artifactMap.put(key, descriptors);
+ keyIndex = null;
}
descriptors.add(descriptor);
}
@@ -282,8 +287,10 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
return;
descriptors.remove(descriptor);
- if (descriptors.isEmpty())
+ if (descriptors.isEmpty()) {
artifactMap.remove(key);
+ keyIndex = null;
+ }
}
public SimpleArtifactRepository(IProvisioningAgent agent, String repositoryName, URI location, Map<String, String> properties) {
@@ -906,7 +913,7 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
public void save() {
if (disableSave)
return;
- boolean compress = "true".equalsIgnoreCase((String) properties.get(PROP_COMPRESSED)); //$NON-NLS-1$
+ boolean compress = "true".equalsIgnoreCase(properties.get(PROP_COMPRESSED)); //$NON-NLS-1$
save(compress);
}
@@ -988,13 +995,17 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
return new IQueryable<IArtifactDescriptor>() {
public IQueryResult<IArtifactDescriptor> query(IQuery<IArtifactDescriptor> query, IProgressMonitor monitor) {
- return query.perform(new FlatteningIterator<IArtifactDescriptor>(descs.iterator()));
+ return query.perform(new CompoundIterator<IArtifactDescriptor>(descs.iterator()));
}
};
}
- public IQueryResult<IArtifactKey> query(IQuery<IArtifactKey> query, IProgressMonitor monitor) {
- return query.perform(artifactMap.keySet().iterator());
+ public synchronized IQueryResult<IArtifactKey> query(IQuery<IArtifactKey> query, IProgressMonitor monitor) {
+ return query instanceof IQueryWithIndex<?> ? ((IQueryWithIndex<IArtifactKey>) query).perform(this) : query.perform(artifactMap.keySet().iterator());
+ }
+
+ public Iterator<IArtifactKey> everything() {
+ return artifactMap.keySet().iterator();
}
public IStatus executeBatch(Runnable runnable) {
@@ -1021,4 +1032,13 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
result = Status.OK_STATUS;
return result;
}
+
+ public synchronized IIndex<IArtifactKey> getIndex(String memberName) {
+ if (ArtifactKey.MEMBER_ID.equals(memberName)) {
+ if (keyIndex == null)
+ keyIndex = new KeyIndex(artifactMap.keySet());
+ return keyIndex;
+ }
+ return null;
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/Application.java b/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/Application.java
index 011a67b10..673cd25c7 100644
--- a/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/Application.java
+++ b/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/Application.java
@@ -387,7 +387,7 @@ public class Application implements IApplication {
IProfile profile = initializeProfile();
query = new InstallableUnitQuery(root, version == null ? VersionRange.emptyRange : new VersionRange(version, true, version, true));
- roots = collectRootIUs(metadataRepositoryLocations, new PipedQuery<IInstallableUnit>(query, new LatestIUVersionQuery<IInstallableUnit>()));
+ roots = collectRootIUs(metadataRepositoryLocations, new LatestIUVersionQuery<IInstallableUnit>(query));
if (roots.isEmpty())
roots = profile.query(query, new NullProgressMonitor());
if (roots.isEmpty()) {
diff --git a/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java b/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java
index 860032450..c460f6cff 100644
--- a/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java
+++ b/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java
@@ -13,8 +13,6 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.director.app;
-import org.eclipse.equinox.p2.planner.IPlanner;
-
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
@@ -33,6 +31,7 @@ import org.eclipse.equinox.p2.engine.*;
import org.eclipse.equinox.p2.metadata.*;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.metadata.query.InstallableUnitQuery;
+import org.eclipse.equinox.p2.planner.IPlanner;
import org.eclipse.equinox.p2.planner.IProfileChangeRequest;
import org.eclipse.equinox.p2.query.*;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager;
@@ -255,7 +254,7 @@ public class DirectorApplication implements IApplication {
IQuery<IInstallableUnit> query = new InstallableUnitQuery(rootName.getId(), Version.emptyVersion.equals(v) ? VersionRange.emptyRange : new VersionRange(v, true, v, true));
IQueryResult<IInstallableUnit> roots = null;
if (forInstall)
- roots = collectRootIUs(new PipedQuery<IInstallableUnit>(query, new LatestIUVersionQuery<IInstallableUnit>()));
+ roots = collectRootIUs(new LatestIUVersionQuery<IInstallableUnit>(query));
if (roots == null || roots.isEmpty())
roots = profile.query(query, new NullProgressMonitor());
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/QueryableArray.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/QueryableArray.java
index d2208d6b5..fcb4bef92 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/QueryableArray.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/QueryableArray.java
@@ -10,79 +10,38 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.director;
-import java.util.*;
+import java.util.Iterator;
+import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.equinox.internal.p2.metadata.RequiredCapability;
+import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;
+import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
+import org.eclipse.equinox.internal.p2.metadata.index.CapabilityIndex;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.IProvidedCapability;
-import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
-import org.eclipse.equinox.p2.metadata.query.ExpressionQuery;
+import org.eclipse.equinox.p2.metadata.index.*;
import org.eclipse.equinox.p2.query.*;
-public class QueryableArray implements IQueryable<IInstallableUnit> {
+public class QueryableArray implements IQueryable<IInstallableUnit>, IIndexProvider<IInstallableUnit> {
private final List<IInstallableUnit> dataSet;
- private Map<String, List<IInstallableUnit>> namedCapabilityIndex;
+ private IIndex<IInstallableUnit> capabilityIndex;
public QueryableArray(IInstallableUnit[] ius) {
- dataSet = Arrays.asList(ius);
+ dataSet = CollectionUtils.unmodifiableList(ius);
}
- public IQueryResult<IInstallableUnit> query(IQuery<IInstallableUnit> query, IProgressMonitor monitor) {
- if (query instanceof ExpressionQuery<?>)
- return queryCapability((ExpressionQuery<IInstallableUnit>) query, new Collector<IInstallableUnit>(), monitor);
- return query.perform(dataSet.iterator());
+ public synchronized IQueryResult<IInstallableUnit> query(IQuery<IInstallableUnit> query, IProgressMonitor monitor) {
+ return query instanceof IQueryWithIndex<?> ? ((IQueryWithIndex<IInstallableUnit>) query).perform(this) : query.perform(dataSet.iterator());
}
- private Collector<IInstallableUnit> queryCapability(ExpressionQuery<IInstallableUnit> query, Collector<IInstallableUnit> collector, IProgressMonitor monitor) {
- generateNamedCapabilityIndex();
-
- Collection<IInstallableUnit> resultIUs = null;
- Collection<IInstallableUnit> matchingIUs = findMatchingIUs(query.getExpression());
- if (matchingIUs == null)
- return collector;
- if (resultIUs == null)
- resultIUs = matchingIUs;
- else
- resultIUs.retainAll(matchingIUs);
-
- if (resultIUs != null)
- for (Iterator<IInstallableUnit> iterator = resultIUs.iterator(); iterator.hasNext();)
- collector.accept(iterator.next());
-
- return collector;
+ public Iterator<IInstallableUnit> everything() {
+ return dataSet.iterator();
}
- private Collection<IInstallableUnit> findMatchingIUs(IMatchExpression<IInstallableUnit> requirementMatch) {
- // TODO: This is a hack. Should be replaced by use of proper indexes
- List<IInstallableUnit> ius = namedCapabilityIndex.get(RequiredCapability.extractName(requirementMatch));
- if (ius == null)
- return null;
-
- Set<IInstallableUnit> matchingIUs = new HashSet<IInstallableUnit>();
- for (IInstallableUnit iu : ius) {
- if (requirementMatch.isMatch(iu))
- matchingIUs.add(iu);
- }
- return matchingIUs;
- }
-
- private void generateNamedCapabilityIndex() {
- if (namedCapabilityIndex != null)
- return;
-
- namedCapabilityIndex = new HashMap<String, List<IInstallableUnit>>();
- for (IInstallableUnit iu : dataSet) {
-
- Collection<IProvidedCapability> providedCapabilities = iu.getProvidedCapabilities();
- for (IProvidedCapability pc : providedCapabilities) {
- String name = pc.getName();
- List<IInstallableUnit> ius = namedCapabilityIndex.get(name);
- if (ius == null) {
- ius = new ArrayList<IInstallableUnit>(5);
- namedCapabilityIndex.put(name, ius);
- }
- ius.add(iu);
- }
+ public synchronized IIndex<IInstallableUnit> getIndex(String memberName) {
+ if (InstallableUnit.MEMBER_PROVIDED_CAPABILITIES.equals(memberName)) {
+ if (capabilityIndex == null)
+ capabilityIndex = new CapabilityIndex(dataSet.iterator());
+ return capabilityIndex;
}
+ return null;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java
index 0944f9ee4..3f1779aee 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/SimplePlanner.java
@@ -114,7 +114,7 @@ public class SimplePlanner implements IPlanner {
}
//Compute the side effect changes (e.g. things installed optionally going away)
- Iterator<IInstallableUnit> includedIUs = changeRequest.getProfile().query(new IUProfilePropertyQuery(INCLUSION_RULES, null), null).iterator();
+ Iterator<IInstallableUnit> includedIUs = changeRequest.getProfile().query(new IUProfilePropertyQuery(INCLUSION_RULES, IUProfilePropertyQuery.ANY), null).iterator();
Map<IInstallableUnit, RequestStatus> sideEffectStatus = new HashMap<IInstallableUnit, RequestStatus>();
while (includedIUs.hasNext()) {
IInstallableUnit removal = includedIUs.next();
@@ -205,8 +205,8 @@ public class SimplePlanner implements IPlanner {
}
public static Collection<IInstallableUnit> findPlannerMarkedIUs(final IProfile profile) {
- IQuery<IInstallableUnit> markerQuery = new IUProfilePropertyQuery(INCLUSION_RULES, null);
- return profile.query(markerQuery, null).toSet();
+ IQuery<IInstallableUnit> markerQuery = new IUProfilePropertyQuery(INCLUSION_RULES, IUProfilePropertyQuery.ANY);
+ return profile.query(markerQuery, null).unmodifiableSet();
}
public static Dictionary<String, String> createSelectionContext(Map<String, String> properties) {
@@ -652,7 +652,7 @@ public class SimplePlanner implements IPlanner {
//It returns at index 0 a meta IU representing everything that needs to be installed
//It returns at index 1 all the IUs that are in the profile after the removal have been done, but before the addition have been done
private Object[] updatePlannerInfo(ProfileChangeRequest profileChangeRequest, ProvisioningContext context) {
- IQueryResult<IInstallableUnit> alreadyInstalled = profileChangeRequest.getProfile().query(new IUProfilePropertyQuery(INCLUSION_RULES, null), null);
+ IQueryResult<IInstallableUnit> alreadyInstalled = profileChangeRequest.getProfile().query(new IUProfilePropertyQuery(INCLUSION_RULES, IUProfilePropertyQuery.ANY), null);
Collection<IInstallableUnit> additionRequested = profileChangeRequest.getAdditions();
Collection<IInstallableUnit> removalRequested = profileChangeRequest.getRemovals();
diff --git a/bundles/org.eclipse.equinox.p2.directorywatcher/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.directorywatcher/META-INF/MANIFEST.MF
index b38923555..f81d0dbcc 100644
--- a/bundles/org.eclipse.equinox.p2.directorywatcher/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.directorywatcher/META-INF/MANIFEST.MF
@@ -8,6 +8,7 @@ Bundle-Version: 1.0.100.qualifier
Import-Package: org.eclipse.equinox.internal.p2.artifact.repository,
org.eclipse.equinox.internal.p2.artifact.repository.simple,
org.eclipse.equinox.internal.p2.core.helpers,
+ org.eclipse.equinox.internal.p2.metadata.expression,
org.eclipse.equinox.internal.p2.update,
org.eclipse.equinox.internal.provisional.p2.core,
org.eclipse.equinox.internal.provisional.p2.metadata,
diff --git a/bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/CachingArtifactRepository.java b/bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/CachingArtifactRepository.java
index 38520507b..ac8a55a41 100644
--- a/bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/CachingArtifactRepository.java
+++ b/bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/CachingArtifactRepository.java
@@ -14,7 +14,7 @@ import java.io.OutputStream;
import java.net.URI;
import java.util.*;
import org.eclipse.core.runtime.*;
-import org.eclipse.equinox.internal.p2.artifact.repository.FlatteningIterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.CompoundIterator;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.metadata.IArtifactKey;
import org.eclipse.equinox.p2.query.*;
@@ -244,7 +244,7 @@ public class CachingArtifactRepository implements IArtifactRepository, IFileArti
final Collection<List<IArtifactDescriptor>> descs = artifactMap.values();
IQueryable<IArtifactDescriptor> cached = new IQueryable<IArtifactDescriptor>() {
public IQueryResult<IArtifactDescriptor> query(IQuery<IArtifactDescriptor> query, IProgressMonitor monitor) {
- return query.perform(new FlatteningIterator<IArtifactDescriptor>(descs.iterator()));
+ return query.perform(new CompoundIterator<IArtifactDescriptor>(descs.iterator()));
}
};
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/query/IUProfilePropertyQuery.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/query/IUProfilePropertyQuery.java
index 84437a6f6..7f2a32150 100644
--- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/query/IUProfilePropertyQuery.java
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/query/IUProfilePropertyQuery.java
@@ -10,16 +10,20 @@
*******************************************************************************/
package org.eclipse.equinox.p2.engine.query;
-import org.eclipse.equinox.internal.p2.metadata.query.IUPropertyQuery;
import org.eclipse.equinox.p2.engine.IProfile;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.query.MatchQuery;
/**
* A query that searches for {@link IInstallableUnit} instances that have
* a property associated with the specified profile, whose value matches the provided value.
* @since 2.0
*/
-public class IUProfilePropertyQuery extends IUPropertyQuery {
+public class IUProfilePropertyQuery extends MatchQuery<IInstallableUnit> {
+ public static final String ANY = "*"; //$NON-NLS-1$
+
+ private final String propertyName;
+ private final String propertyValue;
private IProfile profile;
/**
@@ -34,14 +38,19 @@ public class IUProfilePropertyQuery extends IUPropertyQuery {
* Because the queryable for this query is typically the profile
* instance, we use a reference to the profile rather than the
* profile id for performance reasons.
+ * @param propertyName The name of the property to match
+ * @param propertyValue The value to compare to. A value of &quot;*&quot; means any value.
*/
public IUProfilePropertyQuery(String propertyName, String propertyValue) {
- super(propertyName, propertyValue);
+ this.propertyName = propertyName;
+ this.propertyValue = propertyValue;
}
- protected String getProperty(IInstallableUnit iu, String name) {
+ @Override
+ public boolean isMatch(IInstallableUnit candidate) {
if (profile == null)
- return null;
- return profile.getInstallableUnitProperty(iu, name);
+ return false;
+ String foundValue = profile.getInstallableUnitProperty(candidate, propertyName);
+ return foundValue == null ? propertyValue == null : (ANY.equals(propertyValue) || foundValue.equals(propertyValue));
}
}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/query/UserVisibleRootQuery.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/query/UserVisibleRootQuery.java
index 20ea0d011..d2c3318ad 100644
--- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/query/UserVisibleRootQuery.java
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/p2/engine/query/UserVisibleRootQuery.java
@@ -13,7 +13,6 @@ package org.eclipse.equinox.p2.engine.query;
import org.eclipse.equinox.p2.engine.IProfile;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-
/**
* A query matching all the {@link IInstallableUnit}s that are marked visible to the user.
* @since 2.0
@@ -32,8 +31,6 @@ public class UserVisibleRootQuery extends IUProfilePropertyQuery {
*/
public static boolean isUserVisible(IInstallableUnit iu, IProfile profile) {
String value = profile.getInstallableUnitProperty(iu, IProfile.PROP_PROFILE_ROOT_IU);
- if (value != null && (value.equals(Boolean.TRUE.toString())))
- return true;
- return false;
+ return Boolean.valueOf(value).booleanValue();
}
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/Generator.java b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/Generator.java
index 81cfd9e37..772f1887c 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/Generator.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/Generator.java
@@ -33,7 +33,8 @@ import org.eclipse.equinox.p2.metadata.*;
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil;
import org.eclipse.equinox.p2.metadata.query.InstallableUnitQuery;
-import org.eclipse.equinox.p2.query.*;
+import org.eclipse.equinox.p2.query.IQuery;
+import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.repository.IRepository;
import org.eclipse.equinox.p2.repository.artifact.*;
import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor;
@@ -189,7 +190,7 @@ public class Generator {
GeneratorResult productContents = new GeneratorResult();
ProductQuery productQuery = new ProductQuery(productFile, info.getFlavor(), result.configurationIUs, info.getVersionAdvice());
- PipedQuery query = new PipedQuery(new IQuery[] {productQuery, new LatestIUVersionQuery()});
+ IQuery query = new LatestIUVersionQuery(productQuery);
IQueryResult queryResult = info.getMetadataRepository().query(query, null);
for (Iterator iterator = queryResult.iterator(); iterator.hasNext();) {
productContents.rootIUs.add(iterator.next());
diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.metadata.repository/META-INF/MANIFEST.MF
index fcca9dedf..072902636 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.repository/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.metadata.repository/META-INF/MANIFEST.MF
@@ -19,6 +19,7 @@ Import-Package: javax.xml.parsers,
org.eclipse.equinox.app;resolution:=optional,
org.eclipse.equinox.internal.p2.core.helpers,
org.eclipse.equinox.internal.p2.metadata,
+ org.eclipse.equinox.internal.p2.metadata.index,
org.eclipse.equinox.internal.p2.persistence,
org.eclipse.equinox.internal.p2.repository,
org.eclipse.equinox.internal.p2.repository.helpers,
@@ -29,6 +30,7 @@ Import-Package: javax.xml.parsers,
org.eclipse.equinox.p2.core.spi,
org.eclipse.equinox.p2.metadata,
org.eclipse.equinox.p2.metadata.expression,
+ org.eclipse.equinox.p2.metadata.index,
org.eclipse.equinox.p2.metadata.query,
org.eclipse.equinox.p2.query,
org.eclipse.equinox.p2.repository,
diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/LocalMetadataRepository.java b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/LocalMetadataRepository.java
index b7265d817..ef82be0ef 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/LocalMetadataRepository.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/LocalMetadataRepository.java
@@ -20,12 +20,15 @@ import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.p2.metadata.IUMap;
+import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
+import org.eclipse.equinox.internal.p2.metadata.index.CapabilityIndex;
+import org.eclipse.equinox.internal.p2.metadata.index.IdIndex;
import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus;
import org.eclipse.equinox.internal.provisional.p2.repository.RepositoryEvent;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.query.InstallableUnitQuery;
+import org.eclipse.equinox.p2.metadata.index.*;
import org.eclipse.equinox.p2.query.IQuery;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.repository.IRepository;
@@ -38,7 +41,7 @@ import org.eclipse.equinox.p2.repository.spi.RepositoryReference;
* location is a directory, this implementation will traverse the directory structure
* and combine any metadata repository files that are found.
*/
-public class LocalMetadataRepository extends AbstractMetadataRepository {
+public class LocalMetadataRepository extends AbstractMetadataRepository implements IIndexProvider<IInstallableUnit> {
static final private String CONTENT_FILENAME = "content"; //$NON-NLS-1$
static final private String REPOSITORY_TYPE = LocalMetadataRepository.class.getName();
@@ -48,6 +51,8 @@ public class LocalMetadataRepository extends AbstractMetadataRepository {
protected IUMap units = new IUMap();
protected HashSet<RepositoryReference> repositories = new HashSet<RepositoryReference>();
+ private IIndex<IInstallableUnit> idIndex;
+ private IIndex<IInstallableUnit> capabilityIndex;
private static File getActualLocation(URI location, String extension) {
File spec = URIUtil.toFile(location);
@@ -92,6 +97,7 @@ public class LocalMetadataRepository extends AbstractMetadataRepository {
if (installableUnits == null || installableUnits.length == 0)
return;
units.addAll(installableUnits);
+ capabilityIndex = null; // Generated, not backed by units
save();
}
@@ -100,6 +106,21 @@ public class LocalMetadataRepository extends AbstractMetadataRepository {
repositories.add(new RepositoryReference(repositoryLocation, nickname, repositoryType, options));
}
+ public synchronized IIndex<IInstallableUnit> getIndex(String memberName) {
+ if (InstallableUnit.MEMBER_ID.equals(memberName)) {
+ if (idIndex == null)
+ idIndex = new IdIndex(units);
+ return idIndex;
+ }
+
+ if (InstallableUnit.MEMBER_PROVIDED_CAPABILITIES.equals(memberName)) {
+ if (capabilityIndex == null)
+ capabilityIndex = new CapabilityIndex(units.iterator());
+ return capabilityIndex;
+ }
+ return null;
+ }
+
public void initialize(RepositoryState state) {
synchronized (this) {
this.name = state.Name;
@@ -146,13 +167,16 @@ public class LocalMetadataRepository extends AbstractMetadataRepository {
}
public synchronized IQueryResult<IInstallableUnit> query(IQuery<IInstallableUnit> query, IProgressMonitor monitor) {
- if (query instanceof InstallableUnitQuery)
- return units.query((InstallableUnitQuery) query);
- return query.perform(units.iterator());
+ return query instanceof IQueryWithIndex<?> ? ((IQueryWithIndex<IInstallableUnit>) query).perform(this) : query.perform(units.iterator());
+ }
+
+ public Iterator<IInstallableUnit> everything() {
+ return units.iterator();
}
public synchronized void removeAll() {
units.clear();
+ capabilityIndex = null; // Generated, not backed by units.
save();
}
@@ -161,6 +185,7 @@ public class LocalMetadataRepository extends AbstractMetadataRepository {
if (installableUnits != null && installableUnits.length > 0) {
changed = true;
units.removeAll(Arrays.asList(installableUnits));
+ capabilityIndex = null; // Generated, not backed by units.
}
if (changed)
save();
@@ -219,4 +244,5 @@ public class LocalMetadataRepository extends AbstractMetadataRepository {
manager.addRepository(this);
return oldValue;
}
+
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/URLMetadataRepository.java b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/URLMetadataRepository.java
index 63d548798..0ba7cd271 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/URLMetadataRepository.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/URLMetadataRepository.java
@@ -12,13 +12,17 @@
package org.eclipse.equinox.internal.p2.metadata.repository;
import java.net.URI;
+import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.equinox.internal.p2.metadata.IUMap;
+import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
+import org.eclipse.equinox.internal.p2.metadata.index.CapabilityIndex;
+import org.eclipse.equinox.internal.p2.metadata.index.IdIndex;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.query.InstallableUnitQuery;
+import org.eclipse.equinox.p2.metadata.index.*;
import org.eclipse.equinox.p2.query.IQuery;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.repository.metadata.spi.AbstractMetadataRepository;
@@ -26,7 +30,7 @@ import org.eclipse.equinox.p2.repository.metadata.spi.AbstractMetadataRepository
/**
* A metadata repository backed by an arbitrary URL.
*/
-public class URLMetadataRepository extends AbstractMetadataRepository {
+public class URLMetadataRepository extends AbstractMetadataRepository implements IIndexProvider<IInstallableUnit> {
public static final String CONTENT_FILENAME = "content"; //$NON-NLS-1$
public static final String XML_EXTENSION = ".xml"; //$NON-NLS-1$
@@ -35,6 +39,8 @@ public class URLMetadataRepository extends AbstractMetadataRepository {
transient protected URI content;
protected IUMap units = new IUMap();
+ private IIndex<IInstallableUnit> idIndex;
+ private IIndex<IInstallableUnit> capabilityIndex;
public static URI getActualLocation(URI base) {
return getActualLocation(base, XML_EXTENSION);
@@ -82,8 +88,25 @@ public class URLMetadataRepository extends AbstractMetadataRepository {
}
public synchronized IQueryResult<IInstallableUnit> query(IQuery<IInstallableUnit> query, IProgressMonitor monitor) {
- if (query instanceof InstallableUnitQuery)
- return units.query((InstallableUnitQuery) query);
- return query.perform(units.iterator());
+ return (query instanceof IQueryWithIndex<?>) ? ((IQueryWithIndex<IInstallableUnit>) query).perform(this) : query.perform(units.iterator());
+ }
+
+ public synchronized IIndex<IInstallableUnit> getIndex(String memberName) {
+ if (InstallableUnit.MEMBER_ID.equals(memberName)) {
+ if (idIndex == null)
+ idIndex = new IdIndex(units);
+ return idIndex;
+ }
+
+ if (InstallableUnit.MEMBER_PROVIDED_CAPABILITIES.equals(memberName)) {
+ if (capabilityIndex == null)
+ capabilityIndex = new CapabilityIndex(units.iterator());
+ return capabilityIndex;
+ }
+ return null;
+ }
+
+ public Iterator<IInstallableUnit> everything() {
+ return units.iterator();
}
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/.project b/bundles/org.eclipse.equinox.p2.metadata/.project
index f697ae2d8..e81f675e0 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/.project
+++ b/bundles/org.eclipse.equinox.p2.metadata/.project
@@ -25,6 +25,11 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
diff --git a/bundles/org.eclipse.equinox.p2.metadata/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.metadata/META-INF/MANIFEST.MF
index ebd6d1ea3..bf5b7462c 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.metadata/META-INF/MANIFEST.MF
@@ -18,8 +18,9 @@ Export-Package: org.eclipse.equinox.internal.p2.metadata;
org.eclipse.equinox.p2.director,
org.eclipse.equinox.p2.director.app,
org.eclipse.equinox.p2.installer",
- org.eclipse.equinox.internal.p2.metadata.expression;x-friends:="org.eclipse.equinox.p2.ql",
+ org.eclipse.equinox.internal.p2.metadata.expression;x-friends:="org.eclipse.equinox.p2.ql,org.eclipse.equinox.p2.artifact.repository,org.eclipse.equinox.p2.directorywatcher",
org.eclipse.equinox.internal.p2.metadata.expression.parser;x-friends:="org.eclipse.equinox.p2.ql",
+ org.eclipse.equinox.internal.p2.metadata.index;x-friends:="org.eclipse.equinox.p2.director,org.eclipse.equinox.p2.metadata.repository,org.eclipse.equinox.p2.artifact.repository",
org.eclipse.equinox.internal.p2.metadata.query;
x-friends:="org.eclipse.equinox.p2.artifact.optimizers,
org.eclipse.equinox.p2.artifact.processors,
@@ -89,6 +90,7 @@ Export-Package: org.eclipse.equinox.internal.p2.metadata;
org.eclipse.pde.core",
org.eclipse.equinox.p2.metadata,
org.eclipse.equinox.p2.metadata.expression,
+ org.eclipse.equinox.p2.metadata.index,
org.eclipse.equinox.p2.metadata.query,
org.eclipse.equinox.p2.query
Import-Package: org.eclipse.osgi.service.localization;version="1.0.0",
@@ -102,3 +104,4 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5,
Require-Bundle: org.eclipse.equinox.common,
org.eclipse.equinox.p2.core,
org.eclipse.osgi;bundle-version="3.5.0"
+Service-Component: OSGI-INF/expressionFactory.xml, OSGI-INF/expressionParser.xml
diff --git a/bundles/org.eclipse.equinox.p2.metadata/OSGI-INF/expressionFactory.xml b/bundles/org.eclipse.equinox.p2.metadata/OSGI-INF/expressionFactory.xml
new file mode 100644
index 000000000..f7fede212
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/OSGI-INF/expressionFactory.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.equinox.p2.metadata.expression.factory">
+ <implementation class="org.eclipse.equinox.internal.p2.metadata.expression.ExpressionFactory"/>
+ <service>
+ <provide interface="org.eclipse.equinox.p2.metadata.expression.IExpressionFactory"/>
+ </service>
+ <property name="service.priority" type="Integer" value="1"/>
+</scr:component>
diff --git a/bundles/org.eclipse.equinox.p2.metadata/OSGI-INF/expressionParser.xml b/bundles/org.eclipse.equinox.p2.metadata/OSGI-INF/expressionParser.xml
new file mode 100644
index 000000000..7a158de22
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/OSGI-INF/expressionParser.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.equinox.p2.metadata.expression.parser">
+ <implementation class="org.eclipse.equinox.internal.p2.metadata.expression.parser.ExpressionParser"/>
+ <service>
+ <provide interface="org.eclipse.equinox.p2.metadata.expression.IExpressionParser"/>
+ </service>
+</scr:component> \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.metadata/build.properties b/bundles/org.eclipse.equinox.p2.metadata/build.properties
index 246ea6cb7..0feab6a85 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/build.properties
+++ b/bundles/org.eclipse.equinox.p2.metadata/build.properties
@@ -13,7 +13,9 @@ output.. = bin/
bin.includes = META-INF/,\
.,\
about.html,\
- plugin.properties
-src.includes = about.html
+ plugin.properties,\
+ OSGI-INF/
+src.includes = about.html,\
+ OSGI-INF/
javacTarget=jsr14
javacSource=1.5
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/ArtifactKey.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/ArtifactKey.java
index 709fa2b1c..bdd70f866 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/ArtifactKey.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/ArtifactKey.java
@@ -10,21 +10,25 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.metadata;
-import org.eclipse.equinox.p2.metadata.Version;
-
import java.util.ArrayList;
import java.util.StringTokenizer;
import org.eclipse.core.runtime.Assert;
import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.metadata.Version;
+import org.eclipse.equinox.p2.metadata.expression.IMemberProvider;
/**
* The concrete type for representing IArtifactKey's.
* <p>
* See {link IArtifact for a description of the lifecycle of artifact keys)
*/
-public class ArtifactKey implements IArtifactKey {
+public class ArtifactKey implements IArtifactKey, IMemberProvider {
private static final String SEPARATOR = ","; //$NON-NLS-1$
+ public static final String MEMBER_ID = "id"; //$NON-NLS-1$
+ public static final String MEMBER_CLASSIFIER = "classifier"; //$NON-NLS-1$
+ public static final String MEMBER_VERSION = "version"; //$NON-NLS-1$
+
private final String id;
private final String classifier;
private final Version version;
@@ -123,4 +127,17 @@ public class ArtifactKey implements IArtifactKey {
return data.toString();
}
+ public Object getMember(String memberName) {
+ // It is OK to use identity comparisons here since
+ // a) All constant valued strings are always interned
+ // b) The Member constructor always interns the name
+ //
+ if (MEMBER_ID == memberName)
+ return id;
+ if (MEMBER_VERSION == memberName)
+ return version;
+ if (MEMBER_CLASSIFIER == memberName)
+ return classifier;
+ throw new IllegalArgumentException();
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/IUMap.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/IUMap.java
index 3ce2054da..32715828f 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/IUMap.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/IUMap.java
@@ -16,7 +16,6 @@ import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.metadata.query.InstallableUnitQuery;
-import org.eclipse.equinox.p2.query.Collector;
import org.eclipse.equinox.p2.query.IQueryResult;
/**
@@ -142,16 +141,8 @@ public class IUMap {
Iterator<IInstallableUnit> candidates;
if (query.getId() == null)
candidates = iterator();
- else {
- Object bucket = units.get(query.getId());
- if (bucket == null)
- return Collector.emptyCollector();
-
- if (bucket.getClass().isArray())
- candidates = CollectionUtils.unmodifiableList((IInstallableUnit[]) bucket).iterator();
- else
- candidates = Collections.<IInstallableUnit> singletonList((IInstallableUnit) bucket).iterator();
- }
+ else
+ candidates = getUnits(query.getId()).iterator();
return query.perform(candidates);
}
@@ -160,6 +151,18 @@ public class IUMap {
return get(unit.getId(), unit.getVersion()) != null;
}
+ /**
+ * Returns a collection of units that has the given <code>id</code>.
+ * @param id The id of the desired units. Must not be <code>null</code>.
+ * @return The units corresponding to the given <code>id</code>.
+ */
+ public Collection<IInstallableUnit> getUnits(String id) {
+ Object bucket = units.get(id);
+ if (bucket == null)
+ return CollectionUtils.emptyList();
+ return bucket.getClass().isArray() ? CollectionUtils.unmodifiableList((IInstallableUnit[]) bucket) : Collections.<IInstallableUnit> singletonList((IInstallableUnit) bucket);
+ }
+
public IQueryResult<IInstallableUnit> get(String id) {
return internalGet(id, null);
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/Messages.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/Messages.java
index 0466d2676..654d4c0aa 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/Messages.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/Messages.java
@@ -131,6 +131,10 @@ public class Messages extends NLS {
public static String unbalanced_format_parenthesis;
+ public static String no_expression_factory;
+
+ public static String no_expression_parser;
+
private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.p2.metadata.messages"; //$NON-NLS-1$
static {
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/MetadataActivator.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/MetadataActivator.java
index 40881fcc0..686d11de8 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/MetadataActivator.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/MetadataActivator.java
@@ -10,23 +10,109 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.metadata;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
+import org.eclipse.equinox.p2.metadata.expression.IExpressionFactory;
+import org.eclipse.equinox.p2.metadata.expression.IExpressionParser;
+import org.osgi.framework.*;
public class MetadataActivator implements BundleActivator {
public static final String PI_METADATA = "org.eclipse.equinox.p2.metadata"; //$NON-NLS-1$
- public static BundleContext context;
+
+ public static final String SERVICE_PRIORITY = "service.priority"; //$NON-NLS-1$
+
+ public static MetadataActivator instance;
+
+ private BundleContext context;
+ private IExpressionFactory expressionFactory;
+ private ServiceReference expressionFactoryReference;
+ private IExpressionParser expressionParser;
+ private ServiceReference expressionParserReference;
public static BundleContext getContext() {
- return context;
+ MetadataActivator activator = instance;
+ return activator == null ? null : activator.context;
+ }
+
+ public static IExpressionFactory getExpressionFactory() {
+ MetadataActivator activator = instance;
+ return activator == null ? null : activator._getExpressionFactory();
+ }
+
+ public static IExpressionParser getExpressionParser() {
+ MetadataActivator activator = instance;
+ return activator == null ? null : activator._getExpressionParser();
}
public void start(BundleContext aContext) throws Exception {
- MetadataActivator.context = aContext;
+ context = aContext;
+ instance = this;
}
public void stop(BundleContext aContext) throws Exception {
- MetadataActivator.context = null;
+ instance = null;
+
+ if (expressionFactoryReference != null) {
+ aContext.ungetService(expressionFactoryReference);
+ expressionFactoryReference = null;
+ expressionFactory = null;
+ }
+ if (expressionParserReference != null) {
+ aContext.ungetService(expressionParserReference);
+ expressionParserReference = null;
+ expressionParser = null;
+ }
}
+ private ServiceReference getBestReference(Class<?> serviceInterface) {
+ ServiceReference[] refs;
+ String serviceName = serviceInterface.getName();
+ try {
+ refs = context.getAllServiceReferences(serviceName, null);
+ } catch (InvalidSyntaxException e) {
+ LogHelper.log(new Status(IStatus.ERROR, context.getBundle().getSymbolicName(), "Unable to obtain service references for service " + serviceName, e)); //$NON-NLS-1$
+ return null;
+ }
+
+ if (refs == null)
+ return null;
+
+ ServiceReference best = null;
+ int idx = refs.length;
+ while (--idx >= 0) {
+ ServiceReference ref = refs[idx];
+ if (best == null) {
+ best = ref;
+ continue;
+ }
+ Integer refPrio = (Integer) ref.getProperty(SERVICE_PRIORITY);
+ Integer bestPrio = (Integer) best.getProperty(SERVICE_PRIORITY);
+ if (refPrio == null)
+ continue;
+ if (bestPrio == null || bestPrio.intValue() < refPrio.intValue())
+ best = ref;
+ }
+ return best;
+ }
+
+ private synchronized IExpressionFactory _getExpressionFactory() {
+ if (expressionFactory == null) {
+ expressionFactoryReference = getBestReference(IExpressionFactory.class);
+ if (expressionFactoryReference == null)
+ throw new IllegalStateException(Messages.no_expression_factory);
+ expressionFactory = (IExpressionFactory) context.getService(expressionFactoryReference);
+ }
+ return expressionFactory;
+ }
+
+ private synchronized IExpressionParser _getExpressionParser() {
+ if (expressionParser == null) {
+ expressionParserReference = getBestReference(IExpressionParser.class);
+ if (expressionParserReference == null)
+ throw new IllegalStateException(Messages.no_expression_parser);
+ expressionParser = (IExpressionParser) context.getService(expressionParserReference);
+ }
+ return expressionParser;
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/RequiredCapability.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/RequiredCapability.java
index 4fcb387fc..7a43439c8 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/RequiredCapability.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/RequiredCapability.java
@@ -256,13 +256,21 @@ public class RequiredCapability implements IRequiredCapability, IMemberProvider
return new VersionRange(v, expr == range_II_Expression || expr == range_IN_Expression, h, expr == range_II_Expression || expr == range_NI_Expression);
}
+ public static boolean isSimpleRequirement(IMatchExpression<IInstallableUnit> matchExpression) {
+ return isPredefined(ExpressionUtil.getOperand(matchExpression));
+ }
+
private static IExpression assertValid(IMatchExpression<IInstallableUnit> matchExpression) {
IExpression expr = ExpressionUtil.getOperand(matchExpression);
- if (!(expr == allVersionsExpression || expr == range_II_Expression || expr == range_IN_Expression || expr == range_NI_Expression || expr == range_NN_Expression || expr == strictVersionExpression || expr == openEndedExpression || expr == openEndedNonInclusiveExpression))
+ if (!isPredefined(expr))
throw new IllegalArgumentException();
return expr;
}
+ private static boolean isPredefined(IExpression expr) {
+ return expr == allVersionsExpression || expr == range_II_Expression || expr == range_IN_Expression || expr == range_NI_Expression || expr == range_NN_Expression || expr == strictVersionExpression || expr == openEndedExpression || expr == openEndedNonInclusiveExpression;
+ }
+
public Object getMember(String memberName) {
// It is OK to use identity comparisons here since
// a) All constant valued strings are always interned
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/TranslationSupport.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/TranslationSupport.java
index e42289040..9f11ef4e3 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/TranslationSupport.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/TranslationSupport.java
@@ -193,7 +193,7 @@ public class TranslationSupport {
SoftReference<IQueryResult<IInstallableUnit>> queryResultReference = localeCollectorCache.get(locale);
if (queryResultReference != null) {
- Collector<IInstallableUnit> cached = (Collector<IInstallableUnit>) queryResultReference.get();
+ IQueryResult<IInstallableUnit> cached = queryResultReference.get();
if (cached != null)
return cached;
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CoercingComparator.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CoercingComparator.java
index c69e75e32..6a017aea3 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CoercingComparator.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CoercingComparator.java
@@ -64,7 +64,7 @@ public abstract class CoercingComparator<T> {
return (Class<?>) v;
if (v instanceof String) {
try {
- return MetadataActivator.context.getBundle().loadClass(((String) v).trim());
+ return MetadataActivator.getContext().getBundle().loadClass(((String) v).trim());
} catch (Exception e) {
//
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CollectionFilter.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CollectionFilter.java
index bb845d373..f4d320149 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CollectionFilter.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CollectionFilter.java
@@ -13,6 +13,8 @@ package org.eclipse.equinox.internal.p2.metadata.expression;
import java.util.Iterator;
import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
import org.eclipse.equinox.p2.metadata.expression.IExpressionVisitor;
+import org.eclipse.equinox.p2.metadata.index.IIndex;
+import org.eclipse.equinox.p2.metadata.index.IIndexProvider;
/**
* Some kind of operation that is performed for each element of a collection. I.e.
@@ -51,13 +53,13 @@ public abstract class CollectionFilter extends Unary {
}
public final Object evaluate(IEvaluationContext context) {
- Iterator<?> lval = operand.evaluateAsIterator(context);
+ Iterator<?> lval = getInnerIterator(context);
context = lambda.prolog(context);
return evaluate(context, lval);
}
public final Iterator<?> evaluateAsIterator(IEvaluationContext context) {
- Iterator<?> lval = operand.evaluateAsIterator(context);
+ Iterator<?> lval = getInnerIterator(context);
context = lambda.prolog(context);
return evaluateAsIterator(context, lval);
}
@@ -82,4 +84,47 @@ public abstract class CollectionFilter extends Unary {
protected Iterator<?> evaluateAsIterator(IEvaluationContext context, Iterator<?> iterator) {
throw new UnsupportedOperationException();
}
+
+ private transient IIndexProvider<?> lastIndexProvider;
+ private transient IIndex<?> lastIndex;
+
+ private IIndex<?> getIndex(Class<?> elementClass, IIndexProvider<?> indexProvider) {
+ if (lastIndexProvider == indexProvider)
+ return lastIndex;
+
+ for (String member : getIndexCandidateMembers(elementClass, lambda.getItemVariable(), lambda.getOperand())) {
+ IIndex<?> index = indexProvider.getIndex(member);
+ if (index != null)
+ lastIndex = index;
+ }
+ lastIndexProvider = indexProvider;
+ return lastIndex;
+ }
+
+ protected Iterator<?> getInnerIterator(IEvaluationContext context) {
+ Object collection = operand.evaluate(context);
+ if (collection instanceof Everything<?>) {
+ // Try to find an index
+ //
+ IIndexProvider<?> indexProvider = context.getIndexProvider();
+ if (indexProvider != null) {
+ Class<?> elementClass = ((Everything<?>) collection).getElementClass();
+ IIndex<?> index = getIndex(elementClass, indexProvider);
+ if (index != null) {
+ Iterator<?> indexed = index.getCandidates(context, lambda.getItemVariable(), lambda.getOperand());
+ if (indexed != null)
+ return indexed;
+ }
+ }
+ }
+
+ // No index. We need every element
+ if (collection instanceof IRepeatableIterator<?>)
+ return ((IRepeatableIterator<?>) collection).getCopy();
+
+ Iterator<?> itor = RepeatableIterator.create(collection);
+ if (operand instanceof Variable)
+ ((Variable) operand).setValue(context, itor);
+ return itor;
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/FlattenIterator.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CompoundIterator.java
index 179a36613..4aaf2a417 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/FlattenIterator.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/CompoundIterator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 Cloudsmith Inc. and others.
+ * 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
@@ -8,26 +8,34 @@
* Contributors:
* Cloudsmith Inc. - initial API and implementation
*******************************************************************************/
-package org.eclipse.equinox.internal.p2.ql;
-
-import org.eclipse.equinox.internal.p2.metadata.expression.RepeatableIterator;
+package org.eclipse.equinox.internal.p2.metadata.expression;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
- * A FlattenIterator will assume that its operand is an iterator that will produce
- * elements that can be represented as iterators. The elements of those iterators
- * will be returned in sequence, thus removing one iterator dimension.
+ * A CompoundIterator will assume that its contained iterator that will produce
+ * elements that in turn can be represented as iterators. The elements of those
+ * iterators will be returned in sequence, thus removing one iterator dimension.
+ * Elements of the contained iterator that are not iterators will be coerced
+ * into iterators using {@link RepeatableIterator#create(Object)}.
*/
-public class FlattenIterator<T> implements Iterator<T> {
+public class CompoundIterator<T> implements Iterator<T> {
private static final Object NO_ELEMENT = new Object();
private final Iterator<? extends Object> iteratorIterator;
private Iterator<T> currentIterator;
private T nextObject = noElement();
- public FlattenIterator(Iterator<? extends Object> iterator) {
+ /**
+ * Creates a compound iterator that will iterated over the elements
+ * of the provided <code>iterator</code>. Each element will be coerced
+ * into an iterator and its elements in turn are returned
+ * in succession by the compound iterator.
+ *
+ * @param iterator
+ */
+ public CompoundIterator(Iterator<? extends Object> iterator) {
this.iteratorIterator = iterator;
}
@@ -44,6 +52,11 @@ public class FlattenIterator<T> implements Iterator<T> {
return nxt;
}
+ /**
+ * Remove is not supported by this iterator so calling this method
+ * will always yield an exception.
+ * @throws UnsupportedOperationException
+ */
public void remove() {
throw new UnsupportedOperationException();
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/ContextExpression.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/ContextExpression.java
new file mode 100644
index 000000000..ec2394f50
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/ContextExpression.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * 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.metadata.expression;
+
+import java.util.Iterator;
+import org.eclipse.equinox.p2.metadata.expression.*;
+
+/**
+ * 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.
+ */
+public class ContextExpression<T> extends Unary implements IContextExpression<T> {
+ private static final Object[] noParams = new Object[0];
+ protected final Object[] parameters;
+
+ public ContextExpression(Expression expression, Object[] parameters) {
+ super(expression);
+ this.parameters = parameters == null ? noParams : parameters;
+ }
+
+ public boolean accept(IExpressionVisitor visitor) {
+ return visitor.visit(operand);
+ }
+
+ public void toString(StringBuffer bld, Variable rootVariable) {
+ operand.toString(bld, rootVariable);
+ }
+
+ public IEvaluationContext createContext(Class<T> elementClass, Iterator<T> iterator) {
+ Variable everything = ExpressionFactory.EVERYTHING;
+ IEvaluationContext context = EvaluationContext.create(parameters, everything);
+ context.setValue(everything, new Everything<T>(elementClass, iterator, operand));
+ return context;
+ }
+
+ public int getExpressionType() {
+ return 0;
+ }
+
+ public String getOperator() {
+ throw new UnsupportedOperationException();
+ }
+
+ public int getPriority() {
+ return operand.getPriority();
+ }
+
+ public Object[] getParameters() {
+ return parameters;
+ }
+
+ public int hashCode() {
+ return operand.hashCode();
+ }
+
+ @SuppressWarnings("unchecked")
+ public Iterator<T> iterator(IEvaluationContext context) {
+ return (Iterator<T>) evaluateAsIterator(context);
+ }
+
+ public void toString(StringBuffer bld) {
+ toString(bld, ExpressionFactory.EVERYTHING);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/EvaluationContext.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/EvaluationContext.java
index 6048a008a..49e9bbcac 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/EvaluationContext.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/EvaluationContext.java
@@ -12,17 +12,18 @@ package 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.metadata.index.IIndexProvider;
/**
* Highly specialized evaluation contexts optimized for misc purposes
*/
public class EvaluationContext implements IEvaluationContext {
- static class SingleVariableContext extends EvaluationContext {
+ public static class SingleVariableContext extends EvaluationContext {
private Object value;
private final IExpression variable;
- public SingleVariableContext(IEvaluationContext parentContext, IExpression variable, Object[] parameters) {
+ public SingleVariableContext(EvaluationContext parentContext, IExpression variable, Object[] parameters) {
super(parentContext, parameters);
this.variable = variable;
}
@@ -39,10 +40,10 @@ public class EvaluationContext implements IEvaluationContext {
}
}
- static class MultiVariableContext extends EvaluationContext {
+ public static class MultiVariableContext extends EvaluationContext {
private final Object[] values;
- public MultiVariableContext(IEvaluationContext parentContext, IExpression[] variables, Object[] parameters) {
+ public MultiVariableContext(EvaluationContext parentContext, IExpression[] variables, Object[] parameters) {
super(parentContext, parameters);
values = new Object[variables.length * 2];
for (int idx = 0, ndx = 0; ndx < variables.length; ++ndx, idx += 2)
@@ -75,7 +76,7 @@ public class EvaluationContext implements IEvaluationContext {
}
public static IEvaluationContext create(IEvaluationContext parent, IExpression variable) {
- return new SingleVariableContext(parent, variable, ((EvaluationContext) parent).parameters);
+ return new SingleVariableContext((EvaluationContext) parent, variable, ((EvaluationContext) parent).parameters);
}
public static IEvaluationContext create(IEvaluationContext parent, IExpression[] variables) {
@@ -87,13 +88,13 @@ public class EvaluationContext implements IEvaluationContext {
return create(parent, parameters);
if (parameters == null)
parameters = noParameters;
- return variables.length == 1 ? new SingleVariableContext(parent, variables[0], parameters) : new MultiVariableContext(parent, variables, parameters);
+ return variables.length == 1 ? new SingleVariableContext((EvaluationContext) parent, variables[0], parameters) : new MultiVariableContext((EvaluationContext) parent, variables, parameters);
}
public static IEvaluationContext create(IEvaluationContext parent, Object[] parameters) {
if (parameters == null)
parameters = noParameters;
- return new EvaluationContext(parent, parameters);
+ return new EvaluationContext((EvaluationContext) parent, parameters);
}
public static IEvaluationContext create(IExpression variable) {
@@ -114,11 +115,13 @@ public class EvaluationContext implements IEvaluationContext {
return create(INSTANCE, parameters, variables);
}
- final IEvaluationContext parentContext;
+ final EvaluationContext parentContext;
private final Object[] parameters;
- EvaluationContext(IEvaluationContext parentContext, Object[] parameters) {
+ private IIndexProvider<?> indexProvider;
+
+ EvaluationContext(EvaluationContext parentContext, Object[] parameters) {
this.parentContext = parentContext;
this.parameters = parameters;
}
@@ -138,4 +141,17 @@ public class EvaluationContext implements IEvaluationContext {
throw new IllegalArgumentException("No such variable: " + variable); //$NON-NLS-1$
parentContext.setValue(variable, value);
}
+
+ public IIndexProvider<?> getIndexProvider() {
+ if (indexProvider == null) {
+ if (parentContext == null)
+ return null;
+ return parentContext.getIndexProvider();
+ }
+ return indexProvider;
+ }
+
+ public void setIndexProvider(IIndexProvider<?> indexProvider) {
+ this.indexProvider = indexProvider;
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/Everything.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Everything.java
index d127bf72a..ebdb720b8 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/Everything.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Everything.java
@@ -8,15 +8,14 @@
* Contributors:
* Cloudsmith Inc. - initial API and implementation
*******************************************************************************/
-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;
+package org.eclipse.equinox.internal.p2.metadata.expression;
import java.util.Collection;
import java.util.Iterator;
import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;
+import org.eclipse.equinox.p2.metadata.expression.IExpression;
+import org.eclipse.equinox.p2.metadata.expression.IExpressionVisitor;
+import org.eclipse.equinox.p2.metadata.index.IIndexProvider;
/**
* The immutable context used when evaluating an expression.
@@ -31,7 +30,16 @@ public final class Everything<T> extends MatchIteratorFilter<T> implements IRepe
this.elementClass = elementClass;
}
- public Everything(Class<T> elementClass, Iterator<? extends T> iterator, boolean needsRepeat) {
+ public Everything(Class<T> elementClass, Iterator<? extends T> iterator, Expression expression) {
+ this(elementClass, iterator, needsRepeadedAccessToEverything(expression));
+ }
+
+ public Everything(Class<T> elementClass, IIndexProvider<? extends T> indexProvider) {
+ super(RepeatableIterator.<T> create(indexProvider));
+ this.elementClass = elementClass;
+ }
+
+ Everything(Class<T> elementClass, Iterator<? extends T> iterator, boolean needsRepeat) {
super(needsRepeat ? RepeatableIterator.create(iterator) : iterator);
this.elementClass = elementClass;
}
@@ -50,6 +58,10 @@ public final class Everything<T> extends MatchIteratorFilter<T> implements IRepe
return super.next();
}
+ public Class<T> getElementClass() {
+ return elementClass;
+ }
+
public Object getIteratorProvider() {
Iterator<? extends T> iterator = getInnerIterator();
if (iterator instanceof IRepeatableIterator<?>)
@@ -60,4 +72,24 @@ public final class Everything<T> extends MatchIteratorFilter<T> implements IRepe
protected boolean isMatch(T val) {
return elementClass.isInstance(val);
}
+
+ /**
+ * 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.
+ */
+ private 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 == ExpressionFactory.EVERYTHING) {
+ repeatedAccessNeeded[0] = true;
+ return false;
+ }
+ return true;
+ }
+ });
+ // return repeatedAccessNeeded[0];
+ return true;
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Expression.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Expression.java
index 75f47dd94..767f7c1e7 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Expression.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Expression.java
@@ -11,6 +11,8 @@
package org.eclipse.equinox.internal.p2.metadata.expression;
import java.util.*;
+import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.expression.*;
/**
@@ -93,6 +95,12 @@ public abstract class Expression implements IExpression, Comparable<Expression>,
}
}
+ public static Collection<String> getIndexCandidateMembers(Class<?> elementClass, Variable itemVariable, Expression operand) {
+ MembersFinder finder = new MembersFinder(elementClass, itemVariable);
+ operand.accept(finder);
+ return finder.getMembers();
+ }
+
/**
* Let the visitor visit this instance and all expressions that this
* instance contains.
@@ -264,6 +272,45 @@ public abstract class Expression implements IExpression, Comparable<Expression>,
}
}
+ private static class MembersFinder implements IExpressionVisitor {
+ private final ArrayList<String> members = new ArrayList<String>();
+ private final Class<?> elementClass;
+ private final IExpression operand;
+
+ MembersFinder(Class<?> elementClass, IExpression operand) {
+ this.elementClass = elementClass;
+ this.operand = operand;
+ }
+
+ public boolean visit(IExpression expression) {
+ if (expression instanceof Member) {
+ Member member = (Member) expression;
+ if (member.getOperand() == operand) {
+ String name = member.getName();
+ if (!members.contains(name))
+ members.add(member.getName());
+ return false;
+ }
+ } else if (expression instanceof Matches && IInstallableUnit.class.isAssignableFrom(elementClass)) {
+ // This one is a bit special since an
+ // IInstallableUnit ~= IRequirement often
+ // means that we can reuse the requirement
+ // expression.
+ Matches matches = (Matches) expression;
+ if (matches.lhs == operand) {
+ if (!members.contains(InstallableUnit.MEMBER_PROVIDED_CAPABILITIES))
+ members.add(InstallableUnit.MEMBER_PROVIDED_CAPABILITIES);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ Collection<String> getMembers() {
+ return members;
+ }
+ }
+
static Expression addFilter(Expression base, Expression subFilter, int expressionType) {
if (base.equals(subFilter))
return base;
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/ExpressionFactory.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/ExpressionFactory.java
index f87c1c129..fc0ab18d5 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/ExpressionFactory.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/ExpressionFactory.java
@@ -6,6 +6,7 @@ import org.eclipse.equinox.p2.metadata.expression.*;
public class ExpressionFactory implements IExpressionFactory, IExpressionConstants {
public static final IExpressionFactory INSTANCE = new ExpressionFactory();
public static final Variable THIS = new Variable(VARIABLE_THIS);
+ public static final Variable EVERYTHING = new Variable(VARIABLE_EVERYTHING);
protected static Expression[] convertArray(IExpression[] operands) {
Expression[] ops = new Expression[operands.length];
@@ -13,10 +14,6 @@ public class ExpressionFactory implements IExpressionFactory, IExpressionConstan
return ops;
}
- protected ExpressionFactory() {
- // Maintain singleton
- }
-
public IExpression all(IExpression collection, IExpression lambda) {
return new All((Expression) collection, (LambdaExpression) lambda);
}
@@ -50,6 +47,10 @@ public class ExpressionFactory implements IExpressionFactory, IExpressionConstan
return EvaluationContext.create(parameters, variables);
}
+ public <T> IContextExpression<T> contextExpression(IExpression expr, Object... parameters) {
+ return new ContextExpression<T>((Expression) expr, parameters);
+ }
+
public IFilterExpression filterExpression(IExpression expression) {
return new LDAPFilter((Expression) expression);
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/MatchIteratorFilter.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/MatchIteratorFilter.java
index 1f7b00d2a..8d21ed8f7 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/MatchIteratorFilter.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/MatchIteratorFilter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 Cloudsmith Inc. and others.
+ * 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
@@ -8,7 +8,7 @@
* Contributors:
* Cloudsmith Inc. - initial API and implementation
*******************************************************************************/
-package org.eclipse.equinox.internal.p2.ql;
+package org.eclipse.equinox.internal.p2.metadata.expression;
import java.util.Iterator;
import java.util.NoSuchElementException;
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/RepeatableIterator.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/RepeatableIterator.java
index e44a4e507..b7325286c 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/RepeatableIterator.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/RepeatableIterator.java
@@ -11,6 +11,7 @@
package org.eclipse.equinox.internal.p2.metadata.expression;
import java.util.*;
+import org.eclipse.equinox.p2.metadata.index.IIndexProvider;
import org.eclipse.equinox.p2.query.IQueryResult;
public class RepeatableIterator<T> implements IRepeatableIterator<T> {
@@ -121,14 +122,33 @@ public class RepeatableIterator<T> implements IRepeatableIterator<T> {
}
}
- static class CollectionIterator<T> implements IRepeatableIterator<T> {
- private final Collection<T> collection;
+ static abstract class DeferredIterator<T> implements IRepeatableIterator<T> {
+ private Iterator<T> iterator;
- private final Iterator<T> iterator;
+ public boolean hasNext() {
+ if (iterator == null)
+ iterator = getIterator();
+ return iterator.hasNext();
+ }
+
+ public T next() {
+ if (iterator == null)
+ iterator = getIterator();
+ return iterator.next();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ abstract Iterator<T> getIterator();
+ }
+
+ static class CollectionIterator<T> extends DeferredIterator<T> {
+ private final Collection<T> collection;
CollectionIterator(Collection<T> collection) {
this.collection = collection;
- this.iterator = collection.iterator();
}
public IRepeatableIterator<T> getCopy() {
@@ -139,16 +159,28 @@ public class RepeatableIterator<T> implements IRepeatableIterator<T> {
return collection;
}
- public boolean hasNext() {
- return iterator.hasNext();
+ Iterator<T> getIterator() {
+ return collection.iterator();
}
+ }
- public T next() {
- return iterator.next();
+ static class IndexProviderIterator<T> extends DeferredIterator<T> {
+ private final IIndexProvider<T> indexProvider;
+
+ IndexProviderIterator(IIndexProvider<T> indexProvider) {
+ this.indexProvider = indexProvider;
}
- public void remove() {
- throw new UnsupportedOperationException();
+ public IRepeatableIterator<T> getCopy() {
+ return new IndexProviderIterator<T>(indexProvider);
+ }
+
+ public Object getIteratorProvider() {
+ return indexProvider;
+ }
+
+ Iterator<T> getIterator() {
+ return indexProvider.everything();
}
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/parser/ExpressionParser.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/parser/ExpressionParser.java
index 905d0927c..322299ffc 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/parser/ExpressionParser.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/parser/ExpressionParser.java
@@ -10,10 +10,10 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.metadata.expression.parser;
-import org.eclipse.equinox.internal.p2.metadata.expression.LDAPApproximation;
-
import java.util.*;
+import org.eclipse.equinox.internal.p2.metadata.MetadataActivator;
import org.eclipse.equinox.internal.p2.metadata.expression.IExpressionConstants;
+import org.eclipse.equinox.internal.p2.metadata.expression.LDAPApproximation;
import org.eclipse.equinox.p2.metadata.expression.*;
public class ExpressionParser extends Stack<IExpression> implements IExpressionConstants, IExpressionParser {
@@ -77,8 +77,8 @@ public class ExpressionParser extends Stack<IExpression> implements IExpressionC
protected Object tokenValue;
protected String rootVariable;
- public ExpressionParser(IExpressionFactory factory) {
- this.factory = factory;
+ public ExpressionParser() {
+ factory = MetadataActivator.getExpressionFactory();
}
public synchronized IExpression parse(String exprString) {
@@ -100,6 +100,24 @@ public class ExpressionParser extends Stack<IExpression> implements IExpressionC
}
}
+ public synchronized IExpression parseQuery(String exprString) {
+ expression = exprString;
+ tokenPos = 0;
+ currentToken = 0;
+ tokenValue = null;
+ rootVariable = VARIABLE_EVERYTHING;
+ IExpression everythingVariable = factory.variable(VARIABLE_EVERYTHING);
+ push(everythingVariable);
+ try {
+ nextToken();
+ IExpression expr = parseCondition();
+ assertToken(TOKEN_END);
+ return expr;
+ } finally {
+ popVariable(); // pop context
+ }
+ }
+
protected Map<String, Integer> keywordToTokenMap() {
return keywords;
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/index/CapabilityIndex.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/index/CapabilityIndex.java
new file mode 100644
index 000000000..a26fd3034
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/index/CapabilityIndex.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.metadata.index;
+
+import java.util.*;
+import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;
+import org.eclipse.equinox.internal.p2.metadata.*;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.*;
+import org.eclipse.equinox.p2.metadata.expression.*;
+
+/**
+ * An in-memory implementation of a CapabilityIndex based on a Map.
+ */
+@SuppressWarnings("unchecked")
+public class CapabilityIndex extends Index<IInstallableUnit> {
+
+ private final Map<String, Object> capabilityMap;
+
+ public CapabilityIndex(Iterator<IInstallableUnit> itor) {
+ HashMap<String, Object> index = new HashMap<String, Object>(300);
+ while (itor.hasNext()) {
+ IInstallableUnit iu = itor.next();
+ Collection<IProvidedCapability> pcs = iu.getProvidedCapabilities();
+ for (IProvidedCapability pc : pcs) {
+ String name = pc.getName();
+ Object prev = index.put(name, iu);
+ if (prev == null || prev == iu)
+ continue;
+
+ ArrayList<IInstallableUnit> list;
+ if (prev instanceof IInstallableUnit) {
+ list = new ArrayList<IInstallableUnit>();
+ list.add((IInstallableUnit) prev);
+ } else
+ list = (ArrayList<IInstallableUnit>) prev;
+ list.add(iu);
+ index.put(name, list);
+ }
+ }
+ this.capabilityMap = index;
+ }
+
+ private Object getRequirementIDs(IEvaluationContext ctx, IExpression requirement, Object queriedKeys) {
+ switch (requirement.getExpressionType()) {
+ case IExpression.TYPE_AND :
+ // AND is OK if at least one of the branches require the queried key
+ for (IExpression expr : ExpressionUtil.getOperands(requirement)) {
+ Object test = getRequirementIDs(ctx, expr, queriedKeys);
+ if (test != null) {
+ if (test == Boolean.FALSE)
+ // Failing exists so the AND will fail altogether
+ return test;
+
+ // It's safe to break here since an and'ing several queries
+ // for different keys and the same input will yield false anyway.
+ return test;
+ }
+ }
+ return null;
+
+ case IExpression.TYPE_OR :
+ // OR is OK if all the branches require the queried key
+ for (IExpression expr : ExpressionUtil.getOperands(requirement)) {
+ Object test = getRequirementIDs(ctx, expr, queriedKeys);
+ if (test == null)
+ // This branch did not require the key so index cannot be used
+ return null;
+
+ if (test == Boolean.FALSE)
+ // Branch will always fail regardless of input, so just ignore
+ continue;
+
+ queriedKeys = test;
+ }
+ return queriedKeys;
+
+ case IExpression.TYPE_ALL :
+ case IExpression.TYPE_EXISTS :
+ CollectionFilter cf = (CollectionFilter) requirement;
+ if (isIndexedMember(cf.getOperand(), ExpressionFactory.THIS, InstallableUnit.MEMBER_PROVIDED_CAPABILITIES)) {
+ LambdaExpression lambda = cf.lambda;
+ return getQueriedIDs(ctx, lambda.getItemVariable(), ProvidedCapability.MEMBER_NAME, lambda.getOperand(), queriedKeys);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected Object getQueriedIDs(IEvaluationContext ctx, IExpression variable, String memberName, IExpression booleanExpr, Object queriedKeys) {
+ if (booleanExpr.getExpressionType() != IExpression.TYPE_MATCHES)
+ return super.getQueriedIDs(ctx, variable, memberName, booleanExpr, queriedKeys);
+
+ Matches matches = (Matches) booleanExpr;
+ if (matches.lhs != variable)
+ return null;
+
+ Object rhsObj = matches.rhs.evaluate(ctx);
+ if (!(rhsObj instanceof IRequirement))
+ return null;
+
+ // Let the requirement expression participate in the
+ // index usage query
+ //
+ IMatchExpression<IInstallableUnit> rm = ((IRequirement) rhsObj).getMatches();
+ return RequiredCapability.isSimpleRequirement(rm) ? concatenateUnique(queriedKeys, rm.getParameters()[0]) : getRequirementIDs(rm.createContext(), ((Unary) rm).operand, queriedKeys);
+ }
+
+ public Iterator<IInstallableUnit> getCandidates(IEvaluationContext ctx, IExpression variable, IExpression booleanExpr) {
+ Object queriedKeys = null;
+
+ // booleanExpression must be a collection filter on providedCapabilities
+ // or an IInstallableUnit used in a match expression.
+ //
+ IExpression expr = booleanExpr;
+ int type = booleanExpr.getExpressionType();
+ if (type == 0) {
+ // wrapper
+ expr = ((Unary) booleanExpr).operand;
+ type = expr.getExpressionType();
+ }
+
+ switch (type) {
+ case IExpression.TYPE_ALL :
+ case IExpression.TYPE_EXISTS :
+ CollectionFilter cf = (CollectionFilter) expr;
+ if (isIndexedMember(cf.getOperand(), variable, InstallableUnit.MEMBER_PROVIDED_CAPABILITIES)) {
+ // This is providedCapabilities.exists or providedCapabilites.all
+ //
+ LambdaExpression lambda = cf.lambda;
+ queriedKeys = getQueriedIDs(ctx, lambda.getItemVariable(), ProvidedCapability.MEMBER_NAME, lambda.getOperand(), queriedKeys);
+ } else {
+ // Might be the requiredCapabilities array.
+ //
+ Expression op = cf.getOperand();
+ if (op instanceof Member && InstallableUnit.MEMBER_REQUIRED_CAPABILITIES.equals(((Member) op).getName())) {
+ queriedKeys = getQueriedIDs(ctx, variable, ProvidedCapability.MEMBER_NAME, booleanExpr, queriedKeys);
+ }
+ }
+ break;
+
+ case IExpression.TYPE_MATCHES :
+ Matches matches = (Matches) expr;
+ if (matches.lhs != variable)
+ break;
+
+ Object rhsObj = matches.rhs.evaluate(ctx);
+ if (!(rhsObj instanceof IRequirement))
+ break;
+
+ // Let the requirement expression participate in the
+ // index usage query
+ //
+ IMatchExpression<IInstallableUnit> rm = ((IRequirement) rhsObj).getMatches();
+ queriedKeys = RequiredCapability.isSimpleRequirement(rm) ? concatenateUnique(queriedKeys, rm.getParameters()[0]) : getRequirementIDs(rm.createContext(), ((Unary) rm).operand, queriedKeys);
+ break;
+
+ default :
+ queriedKeys = null;
+ }
+
+ if (queriedKeys == null)
+ // Index cannot be used.
+ return null;
+
+ Collection<IInstallableUnit> matchingIUs;
+ if (queriedKeys == Boolean.FALSE) {
+ // It has been determined that the expression has no chance
+ // to succeed regardless of input
+ matchingIUs = CollectionUtils.<IInstallableUnit> emptySet();
+ } else if (queriedKeys instanceof Collection<?>) {
+ matchingIUs = new HashSet<IInstallableUnit>();
+ for (Object key : (Collection<Object>) queriedKeys)
+ collectMatchingIUs((String) key, matchingIUs);
+ } else {
+ Object v = capabilityMap.get(queriedKeys);
+ if (v == null)
+ matchingIUs = CollectionUtils.<IInstallableUnit> emptySet();
+ else if (v instanceof IInstallableUnit)
+ matchingIUs = Collections.singleton((IInstallableUnit) v);
+ else
+ matchingIUs = (Collection<IInstallableUnit>) v;
+ }
+ return matchingIUs.iterator();
+ }
+
+ private void collectMatchingIUs(String name, Collection<IInstallableUnit> collector) {
+ Object v = capabilityMap.get(name);
+ if (v == null)
+ return;
+ if (v instanceof IInstallableUnit)
+ collector.add((IInstallableUnit) v);
+ else
+ collector.addAll((Collection<IInstallableUnit>) v);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/index/IdIndex.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/index/IdIndex.java
new file mode 100644
index 000000000..a415e8ca4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/index/IdIndex.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.metadata.index;
+
+import java.util.*;
+import org.eclipse.equinox.internal.p2.metadata.IUMap;
+import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.expression.IExpression;
+
+public class IdIndex extends Index<IInstallableUnit> {
+ private final IUMap iuMap;
+
+ public IdIndex(IUMap iuMap) {
+ this.iuMap = iuMap;
+ }
+
+ public IdIndex(Iterator<IInstallableUnit> ius) {
+ iuMap = new IUMap();
+ while (ius.hasNext())
+ iuMap.add(ius.next());
+ }
+
+ public Iterator<IInstallableUnit> getCandidates(IEvaluationContext ctx, IExpression variable, IExpression booleanExpr) {
+ Object queriedKeys = getQueriedIDs(ctx, variable, InstallableUnit.MEMBER_ID, booleanExpr, null);
+ if (queriedKeys == null)
+ return null;
+
+ if (queriedKeys instanceof Collection<?>) {
+ HashSet<IInstallableUnit> collector = new HashSet<IInstallableUnit>();
+ for (Object key : (Collection<?>) queriedKeys)
+ collector.addAll(iuMap.getUnits((String) key));
+ return collector.iterator();
+ }
+ return iuMap.getUnits((String) queriedKeys).iterator();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/index/Index.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/index/Index.java
new file mode 100644
index 000000000..3c509bff2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/index/Index.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.metadata.index;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.index.IIndex;
+
+public abstract class Index<T> implements IIndex<T> {
+
+ protected static boolean isIndexedMember(IExpression expr, IExpression variable, String memberName) {
+ if (expr instanceof Member) {
+ Member member = (Member) expr;
+ return member.getOperand() == variable && member.getName().equals(memberName);
+ }
+ return false;
+ }
+
+ protected static Object concatenateUnique(Object previous, Object toAdd) {
+ if (previous == null || toAdd == null || toAdd == Boolean.FALSE)
+ return toAdd;
+
+ if (previous instanceof ArrayList<?>) {
+ @SuppressWarnings("unchecked")
+ ArrayList<Object> prevArr = (ArrayList<Object>) previous;
+ if (!prevArr.contains(toAdd))
+ prevArr.add(toAdd);
+ return previous;
+ }
+ if (previous.equals(toAdd))
+ return previous;
+
+ ArrayList<Object> arr = new ArrayList<Object>();
+ arr.add(previous);
+ arr.add(toAdd);
+ return arr;
+ }
+
+ protected Object getQueriedIDs(IEvaluationContext ctx, IExpression variable, String memberName, IExpression booleanExpr, Object queriedKeys) {
+ int type = booleanExpr.getExpressionType();
+ switch (type) {
+ case IExpression.TYPE_EQUALS :
+ Binary eqExpr = (Binary) booleanExpr;
+ IExpression lhs = eqExpr.lhs;
+ IExpression rhs = eqExpr.rhs;
+ if (isIndexedMember(lhs, variable, memberName))
+ return concatenateUnique(queriedKeys, rhs.evaluate(ctx));
+ if (isIndexedMember(rhs, variable, memberName))
+ return concatenateUnique(queriedKeys, lhs.evaluate(ctx));
+
+ // Not applicable for indexing
+ return null;
+
+ case IExpression.TYPE_AND :
+ // AND is OK if at least one of the branches require the queried key
+ for (IExpression expr : ExpressionUtil.getOperands(booleanExpr)) {
+ Object test = getQueriedIDs(ctx, variable, memberName, expr, queriedKeys);
+ if (test != null) {
+ if (test == Boolean.FALSE)
+ // Failing exists so the AND will fail altogether
+ return test;
+
+ // It's safe to break here since an and'ing several queries
+ // for different keys and the same input will yield false anyway.
+ return test;
+ }
+ }
+ return null;
+
+ case IExpression.TYPE_OR :
+ // OR is OK if all the branches require the queried key
+ for (IExpression expr : ExpressionUtil.getOperands(booleanExpr)) {
+ Object test = getQueriedIDs(ctx, variable, memberName, expr, queriedKeys);
+ if (test == null)
+ // This branch did not require the key so index cannot be used
+ return null;
+
+ if (test == Boolean.FALSE)
+ // Branch will always fail regardless of input, so just ignore
+ continue;
+
+ queriedKeys = test;
+ }
+ return queriedKeys;
+
+ case IExpression.TYPE_EXISTS :
+ case IExpression.TYPE_ALL :
+ // We must evaluate the lhs to find the referenced keys
+ //
+ CollectionFilter cf = (CollectionFilter) booleanExpr;
+ Iterator<?> values = cf.getOperand().evaluateAsIterator(ctx);
+ if (!values.hasNext())
+ // No keys are requested but we know that an exists must
+ // fail at this point. An all will however succeed regardless
+ // of what is used as input.
+ return type == IExpression.TYPE_ALL ? null : Boolean.FALSE;
+
+ LambdaExpression lambda = cf.lambda;
+ IEvaluationContext lambdaCtx = lambda.prolog(ctx);
+ Variable lambdaVar = lambda.getItemVariable();
+ IExpression filterExpr = lambda.getOperand();
+ do {
+ lambdaVar.setValue(lambdaCtx, values.next());
+ queriedKeys = getQueriedIDs(lambdaCtx, variable, memberName, filterExpr, queriedKeys);
+ if (queriedKeys == null)
+ // No use continuing. The expression does not require the key
+ return null;
+ } while (values.hasNext());
+ return queriedKeys;
+ }
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/messages.properties b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/messages.properties
index a70676f45..540b61526 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/messages.properties
@@ -48,6 +48,8 @@ only_format_specified_0=Only a format was specified: {0}
only_max_and_empty_string_defaults_can_have_translations=Only max string and empty string defaults can have translations
original_must_start_with_colon_0=Original version must start with colon: {0}
original_stated_but_missing_0=Expected original version after colon: {0}
+no_expression_factory=No Expression Factory service has been registered
+no_expression_parser=No Expression Parser service has been registered
pad_defined_more_then_once=Pad was defined more then once
performing_subquery=Performing subquery
premature_end_of_format=Premature end of format
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/IUPropertyQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/IUPropertyQuery.java
index 95f3f3375..1013e91aa 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/IUPropertyQuery.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/IUPropertyQuery.java
@@ -11,38 +11,39 @@
package org.eclipse.equinox.internal.p2.metadata.query;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.query.MatchQuery;
+import org.eclipse.equinox.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.query.ExpressionQuery;
/**
* A query that searches for {@link IInstallableUnit} instances that have
* a property whose value matches the provided value. If no property name is
* specified, then all {@link IInstallableUnit} instances are accepted.
*/
-public class IUPropertyQuery extends MatchQuery<IInstallableUnit> {
- private String propertyName;
- private String propertyValue;
+public final class IUPropertyQuery extends ExpressionQuery<IInstallableUnit> {
+ public static final String ANY = "*"; //$NON-NLS-1$
- /**
- * Creates a new query on the given property name and value.
- */
- public IUPropertyQuery(String propertyName, String propertyValue) {
- this.propertyName = propertyName;
- this.propertyValue = propertyValue;
- }
+ private static final IExpression matchTrueExpression = ExpressionUtil.parse("properties[$0] == true"); //$NON-NLS-1$
+ private static final IExpression matchNullExpression = ExpressionUtil.parse("properties[$0] == null"); //$NON-NLS-1$
+ private static final IExpression matchAnyExpression = ExpressionUtil.parse("properties[$0] != null"); //$NON-NLS-1$
+ private static final IExpression matchValueExpression = ExpressionUtil.parse("properties[$0] == $1"); //$NON-NLS-1$
- /* (non-Javadoc)
- * @see org.eclipse.equinox.p2.query2.Query#isMatch(java.lang.Object)
- */
- public boolean isMatch(IInstallableUnit candidate) {
+ public static IMatchExpression<IInstallableUnit> createMatchExpression(String propertyName, String propertyValue) {
+ IExpressionFactory factory = ExpressionUtil.getFactory();
if (propertyName == null)
- return true;
- String value = getProperty(candidate, propertyName);
- if (value != null && (value.equals(propertyValue) || propertyValue == null))
- return true;
- return false;
+ return MATCH_ALL_UNITS;
+ if (propertyValue == null)
+ return factory.<IInstallableUnit> matchExpression(matchNullExpression, propertyName);
+ if (ANY.equals(propertyValue))
+ return factory.<IInstallableUnit> matchExpression(matchAnyExpression, propertyName);
+ if (Boolean.valueOf(propertyValue).booleanValue())
+ return factory.<IInstallableUnit> matchExpression(matchTrueExpression, propertyName);
+ return factory.<IInstallableUnit> matchExpression(matchValueExpression, propertyName, propertyValue);
}
- protected String getProperty(IInstallableUnit iu, String name) {
- return iu.getProperty(name);
+ /**
+ * Creates a new query on the given property name and value.
+ */
+ public IUPropertyQuery(String propertyName, String propertyValue) {
+ super(IInstallableUnit.class, createMatchExpression(propertyName, propertyValue));
}
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/LatestIUVersionQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/LatestIUVersionQuery.java
index fe79d9404..1115e2e03 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/LatestIUVersionQuery.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/LatestIUVersionQuery.java
@@ -19,10 +19,23 @@ import org.eclipse.equinox.p2.query.*;
*/
public class LatestIUVersionQuery<T extends IVersionedId> extends ContextQuery<T> {
+ private final IQuery<T> query;
+
+ public LatestIUVersionQuery() {
+ this.query = null;
+ }
+
+ public LatestIUVersionQuery(IQuery<T> query) {
+ this.query = query;
+ }
+
/**
* Performs the LatestIUVersionQuery
*/
public IQueryResult<T> perform(Iterator<T> iterator) {
+ if (query != null)
+ iterator = query.perform(iterator).iterator();
+
HashMap<String, T> greatestIUVersion = new HashMap<String, T>();
while (iterator.hasNext()) {
T versionedID = iterator.next();
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/UpdateQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/UpdateQuery.java
index 3ca68f9a0..61f97c47f 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/UpdateQuery.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/UpdateQuery.java
@@ -10,19 +10,14 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.metadata.query;
-import org.eclipse.equinox.p2.metadata.IUpdateDescriptor;
-
-import org.eclipse.equinox.p2.metadata.IInstallableUnitPatch;
-
-import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.IRequirement;
+import org.eclipse.equinox.p2.metadata.*;
import org.eclipse.equinox.p2.query.MatchQuery;
/**
* A query that finds all IUs that are considered an "Update" of the
* specified IU.
*/
-public class UpdateQuery extends MatchQuery<IInstallableUnit> {
+public final class UpdateQuery extends MatchQuery<IInstallableUnit> {
private IInstallableUnit updateFrom;
public UpdateQuery(IInstallableUnit updateFrom) {
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/ExpressionUtil.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/ExpressionUtil.java
index 84d48eb3e..eb1adc5af 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/ExpressionUtil.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/ExpressionUtil.java
@@ -10,8 +10,8 @@
*******************************************************************************/
package org.eclipse.equinox.p2.metadata.expression;
+import org.eclipse.equinox.internal.p2.metadata.MetadataActivator;
import org.eclipse.equinox.internal.p2.metadata.expression.*;
-import org.eclipse.equinox.internal.p2.metadata.expression.parser.ExpressionParser;
import org.eclipse.equinox.internal.p2.metadata.expression.parser.LDAPFilterParser;
/**
@@ -20,22 +20,23 @@ import org.eclipse.equinox.internal.p2.metadata.expression.parser.LDAPFilterPars
*/
public abstract class ExpressionUtil {
private static final LDAPFilterParser ldapFilterParser = new LDAPFilterParser(ExpressionFactory.INSTANCE);
- private static final ExpressionParser expressionParser = new ExpressionParser(ExpressionFactory.INSTANCE);
+ public static final IExpression TRUE_EXPRESSION = getFactory().constant(Boolean.TRUE);
+ public static final IExpression FALSE_EXPRESSION = getFactory().constant(Boolean.FALSE);
/**
* Returns the global expression factory
* @return The global expression factory.
*/
public static IExpressionFactory getFactory() {
- return ExpressionFactory.INSTANCE;
+ return MetadataActivator.getExpressionFactory();
}
/**
* Creates and returns a new expression parser
* @return The new parser
*/
- public static IExpressionParser newParser() {
- return new ExpressionParser(getFactory());
+ public static IExpressionParser getParser() {
+ return MetadataActivator.getExpressionParser();
}
/**
@@ -59,7 +60,7 @@ public abstract class ExpressionUtil {
*/
public static IExpression parse(String expression) {
expression = trimmedOrNull(expression);
- return expression == null ? null : expressionParser.parse(expression);
+ return expression == null ? null : getParser().parse(expression);
}
/**
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IContextExpression.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IContextExpression.java
new file mode 100644
index 000000000..7dc24dd03
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IContextExpression.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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.metadata.expression;
+
+import java.util.Iterator;
+
+/**
+ * This is an expression that will need access to the global variable
+ * <code>everything</code>.
+ */
+public interface IContextExpression<T> extends IExpression {
+ /**
+ * <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 elementClass the class of the iterator elements
+ * @param everything The iterator that represents all queried material.
+ * @return A new evaluation context.
+ */
+ IEvaluationContext createContext(Class<T> elementClass, Iterator<T> everything);
+
+ /**
+ * 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.metadata/src/org/eclipse/equinox/p2/metadata/expression/IEvaluationContext.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IEvaluationContext.java
index 4b049c054..ee3021442 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IEvaluationContext.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IEvaluationContext.java
@@ -10,12 +10,18 @@
*******************************************************************************/
package org.eclipse.equinox.p2.metadata.expression;
+import org.eclipse.equinox.p2.metadata.index.IIndexProvider;
+
/**
* The evaluation context. Contexts can be nested and new contexts are pushed for each closure
* during an evaluation of an expression.
* @since 2.0
*/
public interface IEvaluationContext {
+ IIndexProvider<?> getIndexProvider();
+
+ void setIndexProvider(IIndexProvider<?> indexProvider);
+
/**
* Retrieve the value of the given <code>variable</code> from this context
* @param variable The variable who's value should be retrieved
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IExpressionFactory.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IExpressionFactory.java
index 47d214619..f7e275df0 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IExpressionFactory.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IExpressionFactory.java
@@ -74,6 +74,14 @@ public interface IExpressionFactory {
IExpression constant(Object value);
/**
+ * Creates a top level expression that represents a full query.
+ * @param expr The query
+ * @param parameters The parameters of the query
+ * @return A top level query expression
+ */
+ <T> IContextExpression<T> contextExpression(IExpression expr, Object... parameters);
+
+ /**
* 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.
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IExpressionParser.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IExpressionParser.java
index 6e716af06..c9f43b33c 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IExpressionParser.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/expression/IExpressionParser.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.equinox.p2.metadata.expression;
+
/**
* A parser that produces an expression tree based on a string representation. An
* implementation will use the {@link IExpressionFactory} to create the actual expressions
@@ -18,9 +19,19 @@ package org.eclipse.equinox.p2.metadata.expression;
public interface IExpressionParser {
/**
* Create a new expression. The expression will have access to the global
- * variable and to the context parameters.
+ * variable 'this' and to the context parameters.
* @param exprString The string representing the boolean expression.
* @return The resulting expression tree.
+ * @throws ExpressionParseException
*/
IExpression parse(String exprString);
+
+ /**
+ * Create an arbitrary expression. The expression will have access to the global
+ * variable 'everything' and to the context parameters.
+ * @param exprString The string representing the boolean expression.
+ * @return The resulting expression tree.
+ * @throws ExpressionParseException
+ */
+ IExpression parseQuery(String exprString);
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/index/IIndex.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/index/IIndex.java
new file mode 100644
index 000000000..b06ea05c0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/index/IIndex.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.metadata.index;
+
+import java.util.Iterator;
+import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.expression.IExpression;
+
+/**
+ * Indexed access to the elements provided by an IQueryable
+ */
+public interface IIndex<T> {
+ /**
+ * Obtains the elements that are candidates for the given <code>booleanExpr</code> when applied
+ * using the given <code>variable</code> as <code>this</code>.
+ * The returned set of elements are the elements that must be present in order for the expression
+ * to evaluate to <code>true</code>. The set may contain false positives.
+ *
+ * TODO: Write more about how the valid set of elements is determined.
+ *
+ * @param ctx The evaluation context used when examining the <code>booleanExpr</code>.
+ * @param variable The variable used as <code>this</code>.
+ * @param booleanExpr The boolean expression.
+ * @return The candidate elements or <code>null</code> if this index cannot be used.
+ */
+ Iterator<T> getCandidates(IEvaluationContext ctx, IExpression variable, IExpression booleanExpr);
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/ObjectMatchQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/index/IIndexProvider.java
index f48e50aac..543acbdaf 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/query/ObjectMatchQuery.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/index/IIndexProvider.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
@@ -8,15 +8,12 @@
* Contributors:
* Cloudsmith Inc. - initial API and implementation
*******************************************************************************/
-package org.eclipse.equinox.internal.p2.metadata.query;
+package org.eclipse.equinox.p2.metadata.index;
-import org.eclipse.equinox.p2.query.MatchQuery;
+import java.util.Iterator;
-/**
- * Special implementation for use without generic support
- */
-public abstract class ObjectMatchQuery extends MatchQuery<Object> {
- public boolean isMatch(Object candidate) {
- return true;
- }
+public interface IIndexProvider<T> {
+ IIndex<T> getIndex(String memberName);
+
+ Iterator<T> everything();
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/index/IQueryWithIndex.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/index/IQueryWithIndex.java
new file mode 100644
index 000000000..672b5df89
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/index/IQueryWithIndex.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.metadata.index;
+
+import org.eclipse.equinox.p2.query.IQuery;
+import org.eclipse.equinox.p2.query.IQueryResult;
+
+public interface IQueryWithIndex<T> extends IQuery<T> {
+ IQueryResult<T> perform(IIndexProvider<T> indexProvider);
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/CategoryMemberQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/CategoryMemberQuery.java
index dc59f605b..22bd85835 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/CategoryMemberQuery.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/CategoryMemberQuery.java
@@ -10,11 +10,8 @@
*******************************************************************************/
package org.eclipse.equinox.p2.metadata.query;
-import java.util.Collection;
-import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.IRequirement;
-import org.eclipse.equinox.p2.query.MatchQuery;
+import org.eclipse.equinox.p2.metadata.expression.*;
/**
* A query matching every {@link IInstallableUnit} that is a member
@@ -22,8 +19,13 @@ import org.eclipse.equinox.p2.query.MatchQuery;
*
* @since 2.0
*/
-public class CategoryMemberQuery extends MatchQuery<IInstallableUnit> {
- private final Collection<IRequirement> required;
+public final class CategoryMemberQuery extends ExpressionQuery<IInstallableUnit> {
+ private static final IExpression expression = ExpressionUtil.parse("$0.exists(r | $0 ~= this"); //$NON-NLS-1$
+
+ private static IMatchExpression<IInstallableUnit> createExpression(IInstallableUnit category) {
+ IExpressionFactory factory = ExpressionUtil.getFactory();
+ return CategoryQuery.isCategory(category) ? factory.<IInstallableUnit> matchExpression(expression, category.getRequiredCapabilities()) : MATCH_NO_UNIT;
+ }
/**
* Creates a new query that will return the members of the
@@ -33,23 +35,6 @@ public class CategoryMemberQuery extends MatchQuery<IInstallableUnit> {
* @param category The category
*/
public CategoryMemberQuery(IInstallableUnit category) {
- if (CategoryQuery.isCategory(category))
- this.required = category.getRequiredCapabilities();
- else
- this.required = CollectionUtils.emptyList();
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.equinox.internal.provisional.p2.metadata.query.MatchQuery#isMatch(java.lang.Object)
- */
- public boolean isMatch(IInstallableUnit candidate) {
- // since a category lists its members as requirements, then meeting
- // any requirement means the candidate is a member of the category.
- for (IRequirement req : required) {
- if (candidate.satisfies(req))
- return true;
- }
- return false;
+ super(IInstallableUnit.class, createExpression(category));
}
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/CategoryQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/CategoryQuery.java
index d1d86f912..f93fbb4ab 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/CategoryQuery.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/CategoryQuery.java
@@ -12,22 +12,16 @@ package org.eclipse.equinox.p2.metadata.query;
import org.eclipse.equinox.internal.p2.metadata.query.IUPropertyQuery;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.query.MatchQuery;
/**
* A query matching every {@link IInstallableUnit} that is a category.
* @since 2.0
*/
-public final class CategoryQuery extends MatchQuery<IInstallableUnit> {
+public final class CategoryQuery extends ExpressionQuery<IInstallableUnit> {
private static final String PROP_TYPE_CATEGORY = "org.eclipse.equinox.p2.type.category"; //$NON-NLS-1$
- private IUPropertyQuery query;
public CategoryQuery() {
- query = new IUPropertyQuery(PROP_TYPE_CATEGORY, null);
- }
-
- public boolean isMatch(IInstallableUnit candidate) {
- return query.isMatch(candidate);
+ super(IInstallableUnit.class, IUPropertyQuery.createMatchExpression(PROP_TYPE_CATEGORY, Boolean.TRUE.toString()));
}
/**
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/ExpressionQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/ExpressionQuery.java
index 90624c637..345ed618b 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/ExpressionQuery.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/ExpressionQuery.java
@@ -10,30 +10,66 @@
*******************************************************************************/
package org.eclipse.equinox.p2.metadata.query;
+import java.util.HashSet;
+import java.util.Iterator;
+import org.eclipse.equinox.internal.p2.metadata.expression.Expression;
import org.eclipse.equinox.internal.p2.metadata.expression.ExpressionFactory;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.expression.*;
-import org.eclipse.equinox.p2.query.MatchQuery;
+import org.eclipse.equinox.p2.metadata.index.*;
+import org.eclipse.equinox.p2.query.*;
/**
* A query that matches candidates against an expression.
* @since 2.0
*/
-public class ExpressionQuery<T> extends MatchQuery<T> {
+public class ExpressionQuery<T> implements IQueryWithIndex<T> {
+ public static final IMatchExpression<IInstallableUnit> MATCH_ALL_UNITS = ExpressionUtil.getFactory().matchExpression(ExpressionUtil.TRUE_EXPRESSION);
+ public static final IMatchExpression<IInstallableUnit> MATCH_NO_UNIT = ExpressionUtil.getFactory().matchExpression(ExpressionUtil.FALSE_EXPRESSION);
+
private final IMatchExpression<T> expression;
- private final IEvaluationContext context;
- private final Class<T> matchingClass;
+ private final Class<? extends T> matchingClass;
+ private IEvaluationContext context;
- public ExpressionQuery(Class<T> matchingClass, IExpression expression, Object... parameters) {
+ public ExpressionQuery(Class<? extends T> matchingClass, IExpression expression, Object... parameters) {
this(matchingClass, ExpressionUtil.getFactory().<T> matchExpression(expression, parameters));
}
- public ExpressionQuery(Class<T> matchingClass, IMatchExpression<T> expression) {
+ public ExpressionQuery(Class<? extends T> matchingClass, IMatchExpression<T> expression) {
this.matchingClass = matchingClass;
this.expression = expression;
this.context = expression.createContext();
}
- @Override
+ public IQueryResult<T> perform(IIndexProvider<T> indexProvider) {
+ Iterator<T> iterator = null;
+ for (String member : Expression.getIndexCandidateMembers(IArtifactKey.class, ExpressionFactory.THIS, (Expression) expression)) {
+ IIndex<T> index = indexProvider.getIndex(member);
+ if (index != null) {
+ iterator = index.getCandidates(context, ExpressionFactory.THIS, expression);
+ if (iterator != null)
+ break;
+ }
+ }
+ if (iterator == null)
+ iterator = indexProvider.everything();
+ return perform(iterator);
+ }
+
+ public IQueryResult<T> perform(Iterator<T> iterator) {
+ HashSet<T> result = null;
+ while (iterator.hasNext()) {
+ T value = iterator.next();
+ if (isMatch(value)) {
+ if (result == null)
+ result = new HashSet<T>();
+ result.add(value);
+ }
+ }
+ return result == null ? Collector.<T> emptyCollector() : new CollectionResult<T>(result);
+ }
+
public boolean isMatch(T candidate) {
if (!matchingClass.isInstance(candidate))
return false;
@@ -44,4 +80,8 @@ public class ExpressionQuery<T> extends MatchQuery<T> {
public IMatchExpression<T> getExpression() {
return expression;
}
+
+ public void setIndexProvider(IIndexProvider<T> indexProvider) {
+ context.setIndexProvider(indexProvider);
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/FragmentQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/FragmentQuery.java
index fc70dd9e9..de04066a3 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/FragmentQuery.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/FragmentQuery.java
@@ -10,26 +10,16 @@
*******************************************************************************/
package org.eclipse.equinox.p2.metadata.query;
-import org.eclipse.equinox.p2.metadata.IInstallableUnitFragment;
-
-import org.eclipse.equinox.internal.p2.metadata.query.IUPropertyQuery;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.query.MatchQuery;
+import org.eclipse.equinox.p2.metadata.IInstallableUnitFragment;
/**
* A query matching every {@link IInstallableUnit} that is a category.
* @since 2.0
*/
-public final class FragmentQuery extends MatchQuery<IInstallableUnit> {
- private static final String PROP_TYPE_FRAGMENT = "org.eclipse.equinox.p2.type.fragment"; //$NON-NLS-1$
- private IUPropertyQuery query;
-
+public final class FragmentQuery extends ExpressionQuery<IInstallableUnit> {
public FragmentQuery() {
- query = new IUPropertyQuery(PROP_TYPE_FRAGMENT, null);
- }
-
- public boolean isMatch(IInstallableUnit candidate) {
- return query.isMatch(candidate);
+ super(IInstallableUnitFragment.class, MATCH_ALL_UNITS);
}
/**
@@ -38,11 +28,8 @@ public final class FragmentQuery extends MatchQuery<IInstallableUnit> {
* @return <tt>true</tt> if the parameter is a fragment.
*/
public static boolean isFragment(IInstallableUnit iu) {
- if (iu instanceof IInstallableUnitFragment)
- return true;
+ return iu instanceof IInstallableUnitFragment;
// String value = iu.getProperty(PROP_TYPE_FRAGMENT);
- // if (value != null && (value.equals(Boolean.TRUE.toString())))
- // return true;
- return false;
+ // return value != null && (value.equals(Boolean.TRUE.toString()));
}
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/GroupQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/GroupQuery.java
index 298b04a2f..729920902 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/GroupQuery.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/GroupQuery.java
@@ -12,22 +12,16 @@ package org.eclipse.equinox.p2.metadata.query;
import org.eclipse.equinox.internal.p2.metadata.query.IUPropertyQuery;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.query.MatchQuery;
/**
* A query matching every {@link IInstallableUnit} that is a group.
* @since 2.0
*/
-public final class GroupQuery extends MatchQuery<IInstallableUnit> {
+public final class GroupQuery extends ExpressionQuery<IInstallableUnit> {
private static final String PROP_TYPE_GROUP = "org.eclipse.equinox.p2.type.group"; //$NON-NLS-1$
- private IUPropertyQuery query;
public GroupQuery() {
- query = new IUPropertyQuery(PROP_TYPE_GROUP, null);
- }
-
- public boolean isMatch(IInstallableUnit candidate) {
- return query.isMatch(candidate);
+ super(IInstallableUnit.class, IUPropertyQuery.createMatchExpression(PROP_TYPE_GROUP, Boolean.TRUE.toString()));
}
/**
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/InstallableUnitQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/InstallableUnitQuery.java
index ac2110b03..42f5c9915 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/InstallableUnitQuery.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/InstallableUnitQuery.java
@@ -10,26 +10,39 @@
*******************************************************************************/
package org.eclipse.equinox.p2.metadata.query;
-import org.eclipse.equinox.p2.metadata.Version;
-import org.eclipse.equinox.p2.metadata.VersionRange;
-
-import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.IVersionedId;
-import org.eclipse.equinox.p2.query.MatchQuery;
+import org.eclipse.equinox.p2.metadata.*;
+import org.eclipse.equinox.p2.metadata.expression.*;
/**
* A query that matches on the id and version of an {@link IInstallableUnit}.
* @since 2.0
*/
-public class InstallableUnitQuery extends MatchQuery<IInstallableUnit> {
+public final class InstallableUnitQuery extends ExpressionQuery<IInstallableUnit> {
/**
* A convenience query that will match any {@link IInstallableUnit}
* it encounters.
*/
public static final InstallableUnitQuery ANY = new InstallableUnitQuery((String) null);
- private String id;
- private final VersionRange range;
+ private static final IExpression matchID = ExpressionUtil.parse("id == $0"); //$NON-NLS-1$
+ private static final IExpression matchIDAndVersion = ExpressionUtil.parse("id == $0 && version == $1"); //$NON-NLS-1$
+ private static final IExpression matchIDAndRange = ExpressionUtil.parse("id == $0 && version ~= $1"); //$NON-NLS-1$
+
+ private static IMatchExpression<IInstallableUnit> createMatchExpression(String id) {
+ return id == null ? ExpressionQuery.MATCH_ALL_UNITS : ExpressionUtil.getFactory().<IInstallableUnit> matchExpression(matchID, id);
+ }
+
+ private static IMatchExpression<IInstallableUnit> createMatchExpression(String id, VersionRange range) {
+ if (range == null || range.equals(VersionRange.emptyRange))
+ return createMatchExpression(id);
+ if (range.getMinimum().equals(range.getMaximum()))
+ return createMatchExpression(id, range.getMinimum());
+ return id == null ? ExpressionQuery.MATCH_ALL_UNITS : ExpressionUtil.getFactory().<IInstallableUnit> matchExpression(matchIDAndRange, id, range);
+ }
+
+ private static IMatchExpression<IInstallableUnit> createMatchExpression(String id, Version version) {
+ return version == null || version.equals(Version.emptyVersion) ? createMatchExpression(id) : ExpressionUtil.getFactory().<IInstallableUnit> matchExpression(matchIDAndVersion, id, version);
+ }
/**
* Creates a query that will match any {@link IInstallableUnit} with the given
@@ -38,8 +51,7 @@ public class InstallableUnitQuery extends MatchQuery<IInstallableUnit> {
* @param id The installable unit id to match, or <code>null</code> to match any id
*/
public InstallableUnitQuery(String id) {
- this.id = id;
- this.range = null;
+ super(IInstallableUnit.class, createMatchExpression(id));
}
/**
@@ -50,8 +62,7 @@ public class InstallableUnitQuery extends MatchQuery<IInstallableUnit> {
* @param range The version range to match
*/
public InstallableUnitQuery(String id, VersionRange range) {
- this.id = id;
- this.range = range;
+ super(IInstallableUnit.class, createMatchExpression(id, range));
}
/**
@@ -62,8 +73,7 @@ public class InstallableUnitQuery extends MatchQuery<IInstallableUnit> {
* @param version The precise version that a matching unit must have
*/
public InstallableUnitQuery(String id, Version version) {
- this.id = id;
- this.range = (version == null || Version.emptyVersion.equals(version)) ? null : new VersionRange(version, true, version, true);
+ super(IInstallableUnit.class, createMatchExpression(id, version));
}
/**
@@ -81,26 +91,7 @@ public class InstallableUnitQuery extends MatchQuery<IInstallableUnit> {
* @return The installable unit it
*/
public String getId() {
- return id;
+ Object[] params = getExpression().getParameters();
+ return params.length > 0 ? (String) params[0] : null;
}
-
- /**
- * Returns the version range that this query will match against.
- * @return The installable unit version range.
- */
- public VersionRange getRange() {
- return range;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.equinox.p2.query2.Query#isMatch(java.lang.Object)
- */
- public boolean isMatch(IInstallableUnit candidate) {
- if (id != null && !id.equals(candidate.getId()))
- return false;
- if (range != null && !range.isIncluded(candidate.getVersion()))
- return false;
- return true;
- }
-
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/PatchQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/PatchQuery.java
index d066db376..e341d8efc 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/PatchQuery.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/PatchQuery.java
@@ -12,22 +12,16 @@ package org.eclipse.equinox.p2.metadata.query;
import org.eclipse.equinox.internal.p2.metadata.query.IUPropertyQuery;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.query.MatchQuery;
/**
* A query matching every {@link IInstallableUnit} that is a patch.
* @since 2.0
*/
-public final class PatchQuery extends MatchQuery<IInstallableUnit> {
+public final class PatchQuery extends ExpressionQuery<IInstallableUnit> {
private static final String PROP_TYPE_PATCH = "org.eclipse.equinox.p2.type.patch"; //$NON-NLS-1$
- private IUPropertyQuery query;
public PatchQuery() {
- query = new IUPropertyQuery(PROP_TYPE_PATCH, Boolean.TRUE.toString());
- }
-
- public boolean isMatch(IInstallableUnit candidate) {
- return query.isMatch(candidate);
+ super(IInstallableUnit.class, IUPropertyQuery.createMatchExpression(PROP_TYPE_PATCH, Boolean.TRUE.toString()));
}
/**
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/CollectionResult.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/CollectionResult.java
new file mode 100644
index 000000000..688fd651d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/CollectionResult.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.query;
+
+import java.lang.reflect.Array;
+import java.util.*;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;
+
+public class CollectionResult<T> implements IQueryResult<T> {
+ private final Collection<T> collection;
+
+ public CollectionResult(Collection<T> collection) {
+ this.collection = collection == null ? CollectionUtils.<T> emptySet() : collection;
+ }
+
+ public IQueryResult<T> query(IQuery<T> query, IProgressMonitor monitor) {
+ return query.perform(iterator());
+ }
+
+ public boolean isEmpty() {
+ return collection.isEmpty();
+ }
+
+ public Iterator<T> iterator() {
+ return collection.iterator();
+ }
+
+ public T[] toArray(Class<? extends T> clazz) {
+ int size = collection.size();
+ @SuppressWarnings("unchecked")
+ T[] result = (T[]) Array.newInstance(clazz, size);
+ if (size != 0)
+ collection.toArray(result);
+ return result;
+ }
+
+ public Set<T> toSet() {
+ return new HashSet<T>(collection);
+ }
+
+ public Set<T> unmodifiableSet() {
+ return collection instanceof Set<?> ? Collections.<T> unmodifiableSet((Set<T>) collection) : toSet();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/AbstractPublisherAction.java b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/AbstractPublisherAction.java
index 56999c5c6..c251d5279 100644
--- a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/AbstractPublisherAction.java
+++ b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/AbstractPublisherAction.java
@@ -495,8 +495,10 @@ public abstract class AbstractPublisherAction implements IPublisherAction {
*/
protected IInstallableUnit queryForIU(IPublisherResult publisherResult, String iuId, Version version) {
IQuery<IInstallableUnit> query = new InstallableUnitQuery(iuId, version);
- IQueryResult<IInstallableUnit> collector = Collector.emptyCollector();
+ if (version == null || Version.emptyVersion.equals(version))
+ query = new LatestIUVersionQuery<IInstallableUnit>(query);
+ IQueryResult<IInstallableUnit> collector = Collector.emptyCollector();
NullProgressMonitor progress = new NullProgressMonitor();
if (publisherResult != null)
collector = publisherResult.query(query, progress);
@@ -504,11 +506,6 @@ public abstract class AbstractPublisherAction implements IPublisherAction {
collector = info.getMetadataRepository().query(query, progress);
if (collector.isEmpty() && info.getContextMetadataRepository() != null)
collector = info.getContextMetadataRepository().query(query, progress);
-
- if (version == null || Version.emptyVersion.equals(version)) {
- query = new LatestIUVersionQuery<IInstallableUnit>();
- collector = collector.query(query, null);
- }
if (!collector.isEmpty())
return collector.iterator().next();
return null;
diff --git a/bundles/org.eclipse.equinox.p2.ql/.project b/bundles/org.eclipse.equinox.p2.ql/.project
index 6140e1be9..bf129f044 100644
--- a/bundles/org.eclipse.equinox.p2.ql/.project
+++ b/bundles/org.eclipse.equinox.p2.ql/.project
@@ -25,6 +25,11 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
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 5d307b505..7e0335f87 100644
--- a/bundles/org.eclipse.equinox.p2.ql/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.ql/META-INF/MANIFEST.MF
@@ -17,6 +17,7 @@ Import-Package: org.eclipse.equinox.internal.p2.core.helpers,
org.eclipse.equinox.internal.provisional.p2.metadata,
org.eclipse.equinox.p2.metadata,
org.eclipse.equinox.p2.metadata.expression,
+ org.eclipse.equinox.p2.metadata.index,
org.eclipse.equinox.p2.metadata.query,
org.eclipse.equinox.p2.query,
org.eclipse.equinox.p2.repository.artifact,
@@ -26,3 +27,4 @@ Export-Package: org.eclipse.equinox.internal.p2.ql.expression;x-internal:=true,
org.eclipse.equinox.p2.ql
Bundle-Activator: org.eclipse.equinox.internal.p2.ql.QLActivator
Require-Bundle: org.eclipse.equinox.common;bundle-version="3.5.1"
+Service-Component: OSGI-INF/qlFactory.xml, OSGI-INF/qlParser.xml
diff --git a/bundles/org.eclipse.equinox.p2.ql/OSGI-INF/qlFactory.xml b/bundles/org.eclipse.equinox.p2.ql/OSGI-INF/qlFactory.xml
new file mode 100644
index 000000000..407aa9704
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ql/OSGI-INF/qlFactory.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.equinox.p2.ql.factory">
+ <implementation class="org.eclipse.equinox.internal.p2.ql.expression.QLFactory"/>
+ <service>
+ <provide interface="org.eclipse.equinox.p2.metadata.expression.IExpressionFactory"/>
+ </service>
+ <property name="service.priority" type="Integer" value="2"/>
+</scr:component>
diff --git a/bundles/org.eclipse.equinox.p2.ql/OSGI-INF/qlParser.xml b/bundles/org.eclipse.equinox.p2.ql/OSGI-INF/qlParser.xml
new file mode 100644
index 000000000..8617fa747
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ql/OSGI-INF/qlParser.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.equinox.p2.ql.parser">
+ <implementation class="org.eclipse.equinox.internal.p2.ql.parser.QLParser"/>
+ <service>
+ <provide interface="org.eclipse.equinox.p2.metadata.expression.IExpressionParser"/>
+ </service>
+</scr:component> \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.ql/build.properties b/bundles/org.eclipse.equinox.p2.ql/build.properties
index 06b4caead..e0cf562f5 100644
--- a/bundles/org.eclipse.equinox.p2.ql/build.properties
+++ b/bundles/org.eclipse.equinox.p2.ql/build.properties
@@ -2,17 +2,19 @@
# <copyright>
# </copyright>
#
-# $Id: build.properties,v 1.2 2009/12/29 11:09:34 thallgren Exp $
+# $Id: build.properties,v 1.3 2010/01/23 22:21:13 johna Exp $
bin.includes = .,\
META-INF/,\
plugin.properties,\
- about.html
+ about.html,\
+ OSGI-INF/
jars.compile.order = .
source.. = src/
output.. = bin/
src.includes = about.html,\
- model/
+ model/,\
+ OSGI-INF/
javacTarget=jsr14
javacSource=1.5
-javacWarnings..=+fieldHiding \ No newline at end of file
+javacWarnings..=+fieldHiding
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 26cbce481..e7c3bc7ec 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
@@ -12,8 +12,8 @@ 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.Everything;
-import org.eclipse.equinox.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.IContextExpression;
import org.eclipse.equinox.p2.ql.ITranslationSupport;
@@ -22,71 +22,17 @@ import org.eclipse.equinox.p2.ql.ITranslationSupport;
* variable 'everything' and initialized it with the iterator that represents all
* available items.
*/
-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;
-
- public ContextExpression(Class<T> elementClass, Expression expression, Object[] parameters) {
- super(expression);
- this.elementClass = elementClass;
- this.parameters = parameters == null ? noParams : parameters;
- }
-
- 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) {
- Variable everything = QLFactory.EVERYTHING;
- IEvaluationContext context = EvaluationContext.create(parameters, everything);
- context.setValue(everything, new Everything<T>(elementClass, iterator, QLUtil.needsRepeadedAccessToEverything(operand)));
- return context;
+public final class ContextExpression<T> extends org.eclipse.equinox.internal.p2.metadata.expression.ContextExpression<T> implements IContextExpression<T> {
+ public ContextExpression(Expression expression, Object[] parameters) {
+ super(expression, parameters);
}
- public IEvaluationContext createContext(Iterator<T> iterator, ITranslationSupport ts) {
- Variable everything = QLFactory.EVERYTHING;
+ public IEvaluationContext createContext(Class<T> elementClass, Iterator<T> iterator, ITranslationSupport ts) {
+ Variable everything = ExpressionFactory.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(everything, new Everything<T>(elementClass, iterator, operand));
context.setValue(translations, ts);
return context;
}
-
- public Class<T> getElementClass() {
- return elementClass;
- }
-
- public int getExpressionType() {
- return 0;
- }
-
- public String getOperator() {
- throw new UnsupportedOperationException();
- }
-
- public int getPriority() {
- return operand.getPriority();
- }
-
- public Object[] getParameters() {
- return parameters;
- }
-
- public int hashCode() {
- return operand.hashCode();
- }
-
- @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/Flatten.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Flatten.java
index b0ff4122c..8aa33622c 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
@@ -10,9 +10,10 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql.expression;
+import org.eclipse.equinox.internal.p2.metadata.expression.CompoundIterator;
+
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.metadata.expression.IEvaluationContext;
/**
@@ -25,7 +26,7 @@ final class Flatten extends UnaryCollectionFilter {
}
public Iterator<?> evaluateAsIterator(IEvaluationContext context) {
- return new FlattenIterator<Object>(operand.evaluateAsIterator(context));
+ return new CompoundIterator<Object>(operand.evaluateAsIterator(context));
}
public int getExpressionType() {
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/QLFactory.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/QLFactory.java
index 17bbb657a..8568e680c 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/QLFactory.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/QLFactory.java
@@ -5,15 +5,12 @@ import java.lang.reflect.InvocationTargetException;
import java.util.*;
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 QLFactory extends ExpressionFactory implements IQLFactory, IQLConstants {
@SuppressWarnings("hiding")
public static final IQLFactory INSTANCE = new QLFactory();
- 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;
@@ -60,8 +57,8 @@ public class QLFactory extends ExpressionFactory implements IQLFactory, IQLConst
return new Condition((Expression) test, (Expression) ifTrue, (Expression) ifFalse);
}
- public <T> IContextExpression<T> contextExpression(Class<T> elementClass, IExpression expr, Object... parameters) {
- return new ContextExpression<T>(elementClass, (Expression) expr, parameters);
+ public <T> org.eclipse.equinox.p2.metadata.expression.IContextExpression<T> contextExpression(IExpression expr, Object... parameters) {
+ return new ContextExpression<T>((Expression) expr, parameters);
}
public IExpression first(IExpression collection, IExpression lambda) {
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
index 6d790b25b..5ae9b8c6b 100644
--- 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
@@ -73,24 +73,4 @@ public abstract class QLUtil implements IExpression, IQLConstants {
});
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/Select.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/internal/p2/ql/expression/Select.java
index 9ea863a0e..300d8d390 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
@@ -12,7 +12,6 @@ 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.metadata.expression.IEvaluationContext;
import org.eclipse.equinox.p2.ql.IQLExpression;
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 5d4953cea..270ac2b5e 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
@@ -12,7 +12,6 @@ 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.metadata.expression.IEvaluationContext;
import org.eclipse.equinox.p2.ql.IQLExpression;
@@ -21,8 +20,12 @@ import org.eclipse.equinox.p2.ql.IQLExpression;
* once throughout the whole query.
*/
final class Unique extends Binary implements IQLConstants, IQLExpression {
+ /**
+ * A UniqueIterator that uses a set as a discriminator, ensuring that
+ * no element is returned twice.
+ */
static class UniqueIterator<T> extends MatchIteratorFilter<T> {
- private final Set<T> uniqueSet;
+ final Set<T> uniqueSet;
public UniqueIterator(Iterator<? extends T> iterator, Set<T> uniqueSet) {
super(iterator);
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
index 9a281dfd8..712e94a14 100644
--- 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
@@ -11,7 +11,6 @@
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;
@@ -56,28 +55,6 @@ public class QLParser extends ExpressionParser implements IQLParser, IQLConstant
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;
}
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 fa0468f0f..fa588b58e 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
@@ -12,24 +12,12 @@ 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
* <code>everything</code>.
*/
-public interface IContextExpression<T> extends IExpression {
- /**
- * <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.
- * @return A new evaluation context.
- */
- IEvaluationContext createContext(Iterator<T> everything);
-
+public interface IContextExpression<T> extends org.eclipse.equinox.p2.metadata.expression.IContextExpression<T> {
/**
* <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
@@ -40,24 +28,5 @@ public interface IContextExpression<T> extends IExpression {
* @param translations A translation support object to be assigned to the variable 'translations'
* @return A new evaluation context.
*/
- 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);
+ IEvaluationContext createContext(Class<T> elementClass, Iterator<T> everything, ITranslationSupport translations);
}
diff --git a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLFactory.java b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLFactory.java
index 501dff83f..8afa1822f 100644
--- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLFactory.java
+++ b/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/IQLFactory.java
@@ -55,15 +55,6 @@ public interface IQLFactory extends IExpressionFactory {
IExpression condition(IExpression test, IExpression ifTrue, IExpression ifFalse);
/**
- * 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, Object... parameters);
-
- /**
* Create an expression that yields the first element of the
* <code>collection</code> for which the <code>lambda</code> yields <code>true</code>.
* @param collection The collection providing the elements to test
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 7d34a8b9c..d3f0a911b 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,6 @@ 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.QLFactory;
-import org.eclipse.equinox.internal.p2.ql.parser.QLParser;
import org.eclipse.equinox.p2.query.IQueryable;
/**
@@ -21,22 +19,6 @@ import org.eclipse.equinox.p2.query.IQueryable;
*/
public abstract class QL {
/**
- * Returns the default expression factory.
- * @return the default expression factory.
- */
- public static IQLFactory getFactory() {
- return QLFactory.INSTANCE;
- }
-
- /**
- * Creates a new instance of the default expression parser.
- * @return the new parser.
- */
- public static IQLParser newParser() {
- return new QLParser(getFactory());
- }
-
- /**
* Creates a query context based on the given queryable
* @param queryable The queryable to use for the creation of the context
* @return A new context
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 97d89e135..b8733d63c 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
@@ -12,22 +12,26 @@ 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.ExpressionUtil;
import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
+import org.eclipse.equinox.p2.metadata.index.IIndexProvider;
+import org.eclipse.equinox.p2.metadata.index.IQueryWithIndex;
import org.eclipse.equinox.p2.query.IQueryResult;
/**
* An IQuery 'context query' implementation that is based on the p2 query language.
*/
-public class QLContextQuery<T> extends QLQuery<T> {
+public class QLContextQuery<T> extends QLQuery<T> implements IQueryWithIndex<T> {
private final IContextExpression<T> expression;
+ private IIndexProvider indexProvider;
/**
* Creates a new query instance with indexed parameters.
* @param expression The expression to use for the query.
*/
- public QLContextQuery(IContextExpression<T> expression) {
- super(expression.getElementClass());
- this.expression = expression;
+ public QLContextQuery(Class<T> elementClass, org.eclipse.equinox.p2.metadata.expression.IContextExpression<T> expression) {
+ super(elementClass);
+ this.expression = (IContextExpression<T>) expression;
}
/**
@@ -37,7 +41,14 @@ 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(QL.getFactory().contextExpression(elementClass, parser.parseQuery(expression), parameters));
+ this(elementClass, ExpressionUtil.getFactory().<T> contextExpression(ExpressionUtil.getParser().parseQuery(expression), parameters));
+ }
+
+ public IQueryResult<T> perform(IIndexProvider<T> idxProvider) {
+ indexProvider = idxProvider;
+
+ // TODO Fix so that we don't request everything here.
+ return new QueryResult<T>(evaluate(idxProvider.everything()));
}
public IQueryResult<T> perform(Iterator<T> iterator) {
@@ -48,9 +59,10 @@ public class QLContextQuery<T> extends QLQuery<T> {
IEvaluationContext ctx;
if (QLUtil.needsTranslationSupport(expression)) {
IQueryContext<T> queryContext = QL.newQueryContext(iterator);
- ctx = expression.createContext(iterator, queryContext.getTranslationSupport(getLocale()));
+ ctx = expression.createContext(elementClass, iterator, queryContext.getTranslationSupport(getLocale()));
} else
- ctx = expression.createContext(iterator);
+ ctx = expression.createContext(elementClass, iterator);
+ ctx.setIndexProvider(indexProvider);
Iterator<T> result = expression.iterator(ctx);
return result;
}
@@ -65,9 +77,14 @@ public class QLContextQuery<T> extends QLQuery<T> {
//
IEvaluationContext ctx;
if (QLUtil.needsTranslationSupport(expression))
- ctx = expression.createContext(queryContext.iterator(), queryContext.getTranslationSupport(getLocale()));
+ ctx = expression.createContext(elementClass, queryContext.iterator(), queryContext.getTranslationSupport(getLocale()));
else
- ctx = expression.createContext(queryContext.iterator());
+ ctx = expression.createContext(elementClass, queryContext.iterator());
+ ctx.setIndexProvider(indexProvider);
return expression.evaluate(ctx);
}
+
+ public void setIndexProvider(IIndexProvider indexProvider) {
+ this.indexProvider = indexProvider;
+ }
}
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 2e8adbf66..8cd491ab8 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
@@ -43,7 +43,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, QL.getFactory().<T> matchExpression(parser.parse(expression), parameters));
+ this(instanceClass, ExpressionUtil.getFactory().<T> matchExpression(ExpressionUtil.getParser().parse(expression), parameters));
}
/**
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 b8d48f64a..9987cdc7b 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
@@ -17,7 +17,6 @@ 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 IQLParser parser = QL.newParser();
final Class<T> elementClass;
private Locale locale;
diff --git a/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/ProfileSynchronizer.java b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/ProfileSynchronizer.java
index d07e03da0..d5c9ee1bb 100644
--- a/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/ProfileSynchronizer.java
+++ b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/ProfileSynchronizer.java
@@ -327,7 +327,7 @@ public class ProfileSynchronizer {
}
// get all IUs from profile with marked property (existing)
- IQueryResult<IInstallableUnit> dropinIUs = profile.query(new IUProfilePropertyQuery(PROP_FROM_DROPINS, Boolean.toString(true)), null);
+ IQueryResult<IInstallableUnit> dropinIUs = profile.query(new IUProfilePropertyQuery(PROP_FROM_DROPINS, Boolean.TRUE.toString()), null);
Set<IInstallableUnit> all = allIUs.unmodifiableSet();
for (Iterator<IInstallableUnit> iter = dropinIUs.iterator(); iter.hasNext();) {
IInstallableUnit iu = iter.next();
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/IUDescription.java b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/IUDescription.java
index f02a2b74a..d38685e70 100644
--- a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/IUDescription.java
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/IUDescription.java
@@ -10,8 +10,6 @@
*******************************************************************************/
package org.eclipse.equinox.p2.internal.repository.tools.tasks;
-import org.eclipse.equinox.p2.metadata.Version;
-
import java.util.*;
import org.apache.tools.ant.types.DataType;
import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;
@@ -19,6 +17,7 @@ import org.eclipse.equinox.internal.p2.metadata.query.IUPropertyQuery;
import org.eclipse.equinox.internal.p2.metadata.query.LatestIUVersionQuery;
import org.eclipse.equinox.p2.internal.repository.tools.Activator;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.metadata.query.InstallableUnitQuery;
import org.eclipse.equinox.p2.query.IQuery;
import org.eclipse.equinox.p2.query.PipedQuery;
@@ -112,8 +111,7 @@ public class IUDescription extends DataType {
if (id != null) {
if (version == null || version.length() == 0) {
// Get the latest version of the iu
- queries.add(new InstallableUnitQuery(id));
- queries.add(new LatestIUVersionQuery<IInstallableUnit>());
+ queries.add(new LatestIUVersionQuery<IInstallableUnit>(new InstallableUnitQuery(id)));
} else {
Version iuVersion = Version.parseVersion(version);
queries.add(new InstallableUnitQuery(id, iuVersion));
@@ -146,6 +144,8 @@ public class IUDescription extends DataType {
String value = attributes.get(QUERY_VALUE);
if (name == null)
return null;
+ if (value == null)
+ value = IUPropertyQuery.ANY;
return new IUPropertyQuery(name, value);
}
diff --git a/bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF
index 42f94454b..06554245a 100644
--- a/bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF
@@ -27,6 +27,7 @@ Import-Package: javax.xml.parsers,
org.eclipse.equinox.p2.core,
org.eclipse.equinox.p2.core.spi,
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.security.storage,
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactKeyQuery.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactKeyQuery.java
index 0d48ccabf..4470a2499 100644
--- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactKeyQuery.java
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactKeyQuery.java
@@ -11,22 +11,35 @@
package org.eclipse.equinox.p2.repository.artifact;
-import org.eclipse.equinox.p2.metadata.VersionRange;
-
import org.eclipse.equinox.p2.metadata.IArtifactKey;
-import org.eclipse.equinox.p2.query.MatchQuery;
+import org.eclipse.equinox.p2.metadata.VersionRange;
+import org.eclipse.equinox.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.query.ExpressionQuery;
/**
* An IArtifactQuery returning matching IArtifactKey objects.
* @since 2.0
*/
-public class ArtifactKeyQuery extends MatchQuery<IArtifactKey> {
- public static final ArtifactKeyQuery ALL_KEYS = new ArtifactKeyQuery();
+public class ArtifactKeyQuery extends ExpressionQuery<IArtifactKey> {
+ private static IMatchExpression<IArtifactKey> MATCH_ALL_KEYS = ExpressionUtil.getFactory().matchExpression(ExpressionUtil.TRUE_EXPRESSION);
+ private static final IExpression matchKey = ExpressionUtil.parse("this == $0"); //$NON-NLS-1$
+ private static final IExpression matchID = ExpressionUtil.parse("id == $0"); //$NON-NLS-1$
+ private static final IExpression matchIDClassifierRange = ExpressionUtil.parse("id == $0 && version ~= $2 && (null == $1 || classifier == $1)"); //$NON-NLS-1$
+
+ private static IMatchExpression<IArtifactKey> createMatchExpression(IArtifactKey key) {
+ return key == null ? MATCH_ALL_KEYS : ExpressionUtil.getFactory().<IArtifactKey> matchExpression(matchKey, key);
+ }
- private String id;
- private String classifier;
- private VersionRange range;
- private IArtifactKey artifactKey;
+ private static IMatchExpression<IArtifactKey> createMatchExpression(String classifier, String id, VersionRange range) {
+ if (range == null) {
+ if (classifier == null)
+ return id == null ? MATCH_ALL_KEYS : ExpressionUtil.getFactory().<IArtifactKey> matchExpression(matchID, id);
+ range = VersionRange.emptyRange;
+ }
+ return ExpressionUtil.getFactory().<IArtifactKey> matchExpression(matchIDClassifierRange, id, classifier, range);
+ }
+
+ public static final ArtifactKeyQuery ALL_KEYS = new ArtifactKeyQuery();
/**
* Pass the id and/or version range to match IArtifactKeys against.
@@ -36,46 +49,14 @@ public class ArtifactKeyQuery extends MatchQuery<IArtifactKey> {
* @param range A version range, or <code>null</code>
*/
public ArtifactKeyQuery(String classifier, String id, VersionRange range) {
- this.id = id;
- this.classifier = classifier;
- this.range = range;
+ super(IArtifactKey.class, createMatchExpression(classifier, id, range));
}
public ArtifactKeyQuery() {
- //matches everything
+ super(IArtifactKey.class, MATCH_ALL_KEYS);
}
public ArtifactKeyQuery(IArtifactKey key) {
- this.artifactKey = key;
- }
-
- public boolean isMatch(IArtifactKey key) {
- if (artifactKey != null)
- return matchKey(key);
-
- if (classifier != null && !key.getClassifier().equals(classifier))
- return false;
-
- if (id != null && !key.getId().equals(id))
- return false;
-
- if (range != null && !range.isIncluded(key.getVersion()))
- return false;
-
- return true;
- }
-
- protected boolean matchKey(IArtifactKey candidate) {
- return artifactKey.equals(candidate);
- }
-
- // We are interested in IArtifactKey objects
- public Boolean getExcludeArtifactKeys() {
- return Boolean.FALSE;
- }
-
- // We are not interested in IArtifactDescriptor objects
- public Boolean getExcludeArtifactDescriptors() {
- return Boolean.TRUE;
+ super(IArtifactKey.class, createMatchExpression(key));
}
}
diff --git a/bundles/org.eclipse.equinox.p2.tests.ui/All p2 UI tests.launch b/bundles/org.eclipse.equinox.p2.tests.ui/All p2 UI tests.launch
index 2bd7dd67b..0d7edbbce 100644
--- a/bundles/org.eclipse.equinox.p2.tests.ui/All p2 UI tests.launch
+++ b/bundles/org.eclipse.equinox.p2.tests.ui/All p2 UI tests.launch
@@ -61,10 +61,11 @@
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="product" value="org.eclipse.sdk.ide"/>
<booleanAttribute key="run_in_ui_thread" value="true"/>
-<stringAttribute key="selected_target_plugins" value="org.eclipse.jdt.junit.core@default:default,org.eclipse.help.base@default:default,org.eclipse.ecf.filetransfer@default:default,org.eclipse.jdt.doc.user@default:default,org.eclipse.equinox.http.jetty@default:default,org.eclipse.jdt.junit.runtime@default:default,org.apache.commons.httpclient@default:default,org.apache.commons.logging@default:default,com.jcraft.jsch@default:default,org.junit*3.8.2.v20090203-1005@default:default,org.apache.ant@default:default,org.junit*4.8.1.v4_8_1_v20100114-1600@default:default,org.eclipse.jdt.apt.ui@default:default,org.eclipse.cvs@default:default,org.eclipse.text@default:default,org.eclipse.ecf.identity@default:default,org.eclipse.equinox.concurrent@default:default,org.eclipse.core.commands@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.compare.core@default:default,org.eclipse.equinox.app@default:default,org.eclipse.ui.intro.universal@default:default,org.eclipse.pde.build@default:default,org.eclipse.update.configurator@3:true,org.sat4j.pb@default:default,org.eclipse.pde@default:default,org.eclipse.rcp@default:default,org.eclipse.help@default:default,org.objectweb.asm@default:default,org.eclipse.core.filesystem@default:default,org.eclipse.ui.views@default:default,org.eclipse.help.webapp@default:default,org.eclipse.core.jobs@default:default,org.apache.lucene@default:default,org.eclipse.ui.externaltools@default:default,org.eclipse.pde.api.tools@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.equinox.jsp.jasper@default:default,org.eclipse.core.runtime@default:true,org.eclipse.pde.ds.ui@default:default,org.eclipse.equinox.security.ui@default:default,org.eclipse.core.resources@default:default,org.eclipse.debug.core@default:default,org.eclipse.equinox.common@2:true,org.eclipse.platform@default:default,org.eclipse.equinox.http.registry@default:default,org.eclipse.jdt@default:default,org.junit4@default:default,org.eclipse.ui.net@default:default,org.eclipse.core.externaltools@default:default,org.eclipse.jdt.doc.isv@default:default,org.eclipse.core.variables@default:default,org.eclipse.jdt.junit4.runtime@default:default,org.eclipse.jdt.ui@default:default,org.eclipse.pde.core@default:default,org.eclipse.jsch.ui@default:default,org.eclipse.jdt.debug@default:default,org.eclipse.pde.ua.core@default:default,org.eclipse.ecf.ssl@default:false,org.eclipse.pde.ds.core@default:default,org.eclipse.ecf.provider.filetransfer@default:default,org.eclipse.team.ui@default:default,org.eclipse.search@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.pde.doc.user@default:default,org.eclipse.ecf.provider.filetransfer.httpclient@default:default,org.eclipse.jdt.core@default:default,org.eclipse.equinox.launcher.gtk.linux.x86_64@default:false,org.eclipse.equinox.security@default:default,org.eclipse.core.filebuffers@default:default,org.eclipse.jdt.launching@default:default,org.eclipse.jdt.debug.ui@default:default,org.eclipse.ui.workbench.compatibility@default:false,org.eclipse.ui.navigator.resources@default:default,org.eclipse.swt.gtk.linux.x86_64@default:false,org.eclipse.pde.junit.runtime@default:default,org.eclipse.ui.presentations.r21@default:default,org.eclipse.ui.ide@default:default,org.eclipse.ecf@default:default,org.eclipse.team.cvs.core@default:default,org.eclipse.ui.navigator@default:default,org.eclipse.ui.workbench.texteditor@default:default,javax.servlet.jsp@default:default,org.eclipse.jdt.core.manipulation@default:default,org.eclipse.equinox.jsp.jasper.registry@default:default,org.apache.commons.codec@default:default,org.mortbay.jetty.util@default:default,org.eclipse.core.runtime.compatibility.auth@default:default,org.eclipse.pde.api.tools.ui@default:default,org.eclipse.ui.intro@default:default,org.eclipse.jdt.apt.pluggable.core@default:default,org.apache.commons.el@default:default,org.eclipse.swt@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.sdk@default:default,org.eclipse.pde.runtime@default:default,com.ibm.icu@default:default,org.eclipse.core.runtime.compatibility@default:default,org.eclipse.update.core@default:default,org.eclipse.pde.ui.templates@default:default,org.eclipse.ui.views.log@default:default,org.eclipse.core.boot@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.pde.ui@default:default,org.eclipse.core.databinding.beans@default:default,org.eclipse.jdt.junit@default:default,org.eclipse.ui.views.properties.tabbed@default:default,org.eclipse.osgi@-1:true,org.eclipse.ecf.provider.filetransfer.httpclient.ssl@default:false,org.eclipse.ant.ui@default:default,org.eclipse.ui.ide.application@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.update.ui@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.update.scheduler@default:default,org.eclipse.help.appserver@default:default,org.eclipse.core.expressions@default:default,org.eclipse.ant.core@default:default,org.eclipse.debug.ui@default:default,org.eclipse.core.net.linux.x86_64@default:false,org.eclipse.ui.browser@default:default,org.apache.jasper@default:default,org.eclipse.equinox.launcher@default:default,org.eclipse.team.cvs.ui@default:default,org.eclipse.core.net@default:default,org.eclipse.ui.editors@default:default,org.eclipse.jdt.compiler.apt@default:false,org.eclipse.jdt.compiler.tool@default:false,org.eclipse.ui@default:default,org.eclipse.compare@default:default,org.eclipse.ui.cheatsheets@default:default,org.eclipse.pde.launching@default:default,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.http.servlet@default:default,org.eclipse.ltk.ui.refactoring@default:default,org.eclipse.jface.text@default:default,org.eclipse.ltk.core.refactoring@default:default,org.eclipse.team.cvs.ssh2@default:default,org.eclipse.equinox.util@default:default,org.eclipse.ant.launching@default:default,org.eclipse.jdt.apt.core@default:default,org.sat4j.core@default:default,org.eclipse.equinox.event@default:default,org.eclipse.ui.console@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.team.core@default:default,org.eclipse.ui.forms@default:default,org.eclipse.jface@default:default,org.eclipse.help.ui@default:default,org.eclipse.core.filesystem.linux.x86_64@default:false,org.mortbay.jetty.server@default:default,org.eclipse.osgi.services@default:default,javax.servlet@default:default,org.eclipse.pde.ua.ui@default:default,org.apache.lucene.analysis@default:default,org.eclipse.core.databinding@default:default,org.eclipse.osgi.util@default:default,org.eclipse.jsch.core@default:default,org.hamcrest.core@default:default,org.eclipse.ecf.provider.filetransfer.ssl@default:false"/>
-<stringAttribute key="selected_workspace_plugins" value="org.eclipse.equinox.p2.garbagecollector@default:default,org.eclipse.equinox.simpleconfigurator.manipulator@default:default,org.eclipse.equinox.p2.console@default:default,org.eclipse.equinox.p2.metadata.generator@default:default,org.eclipse.equinox.frameworkadmin@default:default,org.eclipse.equinox.p2.director.app@default:default,org.eclipse.equinox.p2.artifact.optimizers@default:default,org.eclipse.equinox.p2.repository.tools@default:default,org.eclipse.equinox.p2.tests.verifier@default:default,org.eclipse.equinox.p2.extensionlocation@default:default,org.eclipse.test.performance@default:default,org.eclipse.equinox.p2.ql@default:default,org.eclipse.equinox.p2.ui.sdk.scheduler@default:default,org.eclipse.equinox.p2.tests@default:default,org.eclipse.core.tests.harness@default:default,org.eclipse.equinox.p2.artifact.repository@default:default,org.eclipse.equinox.frameworkadmin.equinox@default:default,org.eclipse.equinox.p2.operations@default:default,org.eclipse.equinox.p2.reconciler.dropins@default:default,org.eclipse.equinox.p2.tests.ui@default:default,org.sat4j.pb@default:default,org.eclipse.equinox.p2.updatesite@default:default,org.eclipse.equinox.p2.core@default:default,org.eclipse.equinox.simpleconfigurator@1:true,ie.wombat.jbdiff@default:default,org.eclipse.equinox.p2.touchpoint.natives@default:default,org.sat4j.core@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,org.eclipse.equinox.frameworkadmin.test@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.equinox.p2.repository@default:default,org.eclipse.equinox.p2.publisher@default:default,org.eclipse.equinox.p2.jarprocessor@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.p2.exemplarysetup@default:default,org.eclipse.equinox.p2.touchpoint.eclipse@default:default,org.eclipse.equinox.p2.artifact.processors@default:default,org.eclipse.equinox.p2.installer@default:default,org.eclipse.equinox.p2.updatechecker@default:default,org.eclipse.equinox.p2.director@default:default,org.eclipse.equinox.p2.directorywatcher@default:default,org.eclipse.equinox.p2.ui@default:default,org.easymock@default:default,org.eclipse.equinox.p2.sar@default:default,ie.wombat.jbdiff.test@default:default,org.eclipse.equinox.p2.ui.sdk@default:default"/>
+<stringAttribute key="selected_target_plugins" value="org.eclipse.ui.workbench.compatibility@default:false,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.concurrent@default:default,org.eclipse.team.cvs.ssh2@default:default,org.eclipse.equinox.common@2:true,org.eclipse.update.scheduler@default:default,org.eclipse.ui.externaltools@default:default,org.eclipse.ltk.core.refactoring@default:default,org.eclipse.pde@default:default,org.eclipse.jdt.junit.runtime@default:default,org.eclipse.ui.presentations.r21@default:default,org.eclipse.help.ui@default:default,org.eclipse.compare.core@default:default,org.eclipse.ecf@default:default,org.eclipse.ui.views@default:default,org.eclipse.ui.ide.application@default:default,org.eclipse.swt.gtk.linux.x86_64@default:false,org.eclipse.core.boot@default:default,org.eclipse.equinox.security.ui@default:default,org.eclipse.core.variables@default:default,org.eclipse.osgi.util@default:default,org.eclipse.equinox.jsp.jasper.registry@default:default,org.eclipse.core.runtime@default:true,org.eclipse.core.externaltools@default:default,org.eclipse.equinox.launcher.gtk.linux.x86_64@default:false,org.eclipse.jdt.apt.pluggable.core@default:default,org.eclipse.debug.core@default:default,org.eclipse.jdt.compiler.apt@default:false,org.eclipse.pde.ua.ui@default:default,org.eclipse.update.core@default:default,org.eclipse.sdk@default:default,org.eclipse.ant.core@default:default,org.eclipse.jdt.junit@default:default,org.eclipse.update.configurator@3:true,org.eclipse.pde.api.tools@default:default,org.eclipse.pde.ds.core@default:default,org.eclipse.pde.junit.runtime@default:default,org.eclipse.rcp@default:default,org.apache.commons.codec@default:default,org.eclipse.pde.ui.templates@default:default,org.eclipse.jdt.doc.user@default:default,javax.servlet@default:default,org.mortbay.jetty.util@default:default,org.eclipse.osgi.services@default:default,org.eclipse.ecf.provider.filetransfer.httpclient@default:default,org.mortbay.jetty.server@default:default,org.eclipse.equinox.launcher@default:default,org.eclipse.ltk.ui.refactoring@default:default,org.eclipse.team.cvs.ui@default:default,org.eclipse.ecf.ssl@default:false,org.eclipse.ecf.provider.filetransfer@default:default,org.eclipse.platform@default:default,org.eclipse.help.appserver@default:default,org.eclipse.ecf.filetransfer@default:default,org.eclipse.core.expressions@default:default,org.eclipse.help@default:default,org.eclipse.swt@default:default,org.eclipse.jdt.launching@default:default,org.eclipse.jdt.core@default:default,org.eclipse.core.resources@default:default,org.eclipse.text@default:default,org.junit*3.8.2.v20090203-1005@default:default,org.eclipse.jface@default:default,org.eclipse.equinox.app@default:default,org.eclipse.team.core@default:default,org.eclipse.pde.ui@default:default,org.eclipse.ant.ui@default:default,org.eclipse.core.filebuffers@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.cvs@default:default,org.eclipse.ui.forms@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.jdt.apt.ui@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.net@default:default,org.eclipse.core.jobs@default:default,org.eclipse.ecf.provider.filetransfer.ssl@default:false,javax.servlet.jsp@default:default,org.eclipse.pde.launching@default:default,org.eclipse.pde.api.tools.ui@default:default,org.eclipse.ecf.identity@default:default,org.eclipse.jdt.doc.isv@default:default,org.eclipse.update.ui@default:default,org.eclipse.jdt@default:default,org.eclipse.pde.runtime@default:default,org.sat4j.pb@default:default,org.objectweb.asm@default:default,org.eclipse.jdt.junit.core@default:default,org.apache.commons.httpclient@default:default,org.eclipse.ui.console@default:default,org.eclipse.core.databinding@default:default,org.eclipse.ui.intro.universal@default:default,org.eclipse.core.contenttype@default:default,org.sat4j.core@default:default,org.apache.lucene.analysis@default:default,org.junit4@default:default,org.eclipse.ui.net@default:default,org.eclipse.ecf.provider.filetransfer.httpclient.ssl@default:false,org.eclipse.pde.ua.core@default:default,org.eclipse.ui.navigator.resources@default:default,org.eclipse.pde.doc.user@default:default,org.eclipse.jdt.compiler.tool@default:false,org.eclipse.ui.views.properties.tabbed@default:default,org.eclipse.pde.ds.ui@default:default,org.eclipse.ant.launching@default:default,com.jcraft.jsch@default:default,org.eclipse.team.ui@default:default,org.hamcrest.core@default:default,org.eclipse.help.base@default:default,org.eclipse.jsch.core@default:default,org.eclipse.equinox.jsp.jasper@default:default,org.eclipse.core.runtime.compatibility.auth@default:default,org.eclipse.core.databinding.beans@default:default,org.eclipse.jdt.ui@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.equinox.event@default:default,org.eclipse.help.webapp@default:default,org.apache.commons.logging@default:default,org.eclipse.ui.cheatsheets@default:default,org.apache.lucene@default:default,org.eclipse.pde.core@default:default,org.eclipse.ui.ide@default:default,org.eclipse.core.runtime.compatibility@default:default,org.apache.jasper@default:default,org.eclipse.core.commands@default:default,org.eclipse.jdt.debug@default:default,org.eclipse.osgi@-1:true,org.eclipse.equinox.http.jetty@default:default,org.eclipse.ui.views.log@default:default,org.eclipse.ui.editors@default:default,org.eclipse.core.filesystem.linux.x86_64@default:false,org.eclipse.jface.text@default:default,org.eclipse.ui.workbench.texteditor@default:default,org.eclipse.ui.browser@default:default,org.eclipse.pde.build@default:default,org.eclipse.jdt.junit4.runtime@default:default,org.apache.commons.el@default:default,org.eclipse.ui.intro@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.compare@default:default,org.eclipse.jdt.core.manipulation@default:default,org.eclipse.equinox.http.registry@default:default,org.apache.ant@default:default,org.eclipse.ui.navigator@default:default,org.eclipse.team.cvs.core@default:default,org.junit*4.8.1.v4_8_1_v20100114-1600@default:default,org.eclipse.debug.ui@default:default,org.eclipse.jdt.apt.core@default:default,org.eclipse.equinox.security@default:default,com.ibm.icu@default:default,org.eclipse.core.filesystem@default:default,org.eclipse.search@default:default,org.eclipse.jsch.ui@default:default,org.eclipse.ui@default:default,org.eclipse.core.net.linux.x86_64@default:false,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.equinox.util@default:default,org.eclipse.equinox.http.servlet@default:default,org.eclipse.jdt.debug.ui@default:default"/>
+<stringAttribute key="selected_workspace_plugins" value="org.sat4j.core@default:default,org.eclipse.equinox.p2.core@default:default,org.eclipse.equinox.p2.exemplarysetup@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.p2.updatechecker@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.equinox.p2.touchpoint.natives@default:default,org.eclipse.equinox.p2.ui.sdk.scheduler@default:default,org.eclipse.equinox.p2.repository@default:default,org.eclipse.equinox.p2.artifact.repository@default:default,org.eclipse.equinox.p2.artifact.processors@default:default,org.eclipse.equinox.p2.publisher@default:default,org.sat4j.pb@default:default,org.eclipse.equinox.p2.director@default:default,org.eclipse.equinox.simpleconfigurator.manipulator@default:default,org.eclipse.equinox.p2.updatesite@default:default,org.eclipse.equinox.p2.ui.sdk@default:default,org.eclipse.equinox.p2.garbagecollector@default:default,org.eclipse.equinox.p2.metadata.generator@default:default,ie.wombat.jbdiff.test@default:default,org.eclipse.equinox.p2.tests.verifier@default:default,org.eclipse.test.performance@default:default,org.eclipse.equinox.simpleconfigurator@1:true,org.eclipse.equinox.p2.jarprocessor@default:default,org.eclipse.equinox.frameworkadmin.equinox@default:default,org.eclipse.equinox.p2.extensionlocation@default:default,org.eclipse.equinox.p2.console@default:default,org.eclipse.equinox.p2.ql@default:default,org.eclipse.equinox.p2.reconciler.dropins@default:default,org.eclipse.equinox.p2.artifact.optimizers@default:default,ie.wombat.jbdiff@default:default,org.eclipse.equinox.p2.sar@default:default,org.eclipse.equinox.frameworkadmin@default:default,org.eclipse.equinox.p2.ui@default:default,org.eclipse.equinox.p2.tests.ui@default:default,org.eclipse.equinox.frameworkadmin.test@default:default,org.eclipse.equinox.p2.repository.tools@default:default,org.eclipse.equinox.p2.directorywatcher@default:default,org.eclipse.equinox.p2.director.app@default:default,org.eclipse.core.tests.harness@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,org.eclipse.equinox.p2.operations@default:default,org.eclipse.equinox.p2.touchpoint.eclipse@default:default,org.eclipse.equinox.p2.tests@default:default,org.eclipse.equinox.p2.installer@default:default,org.easymock@default:default"/>
<booleanAttribute key="show_selected_only" value="false"/>
<booleanAttribute key="tracing" value="false"/>
+<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfig" value="true"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
<booleanAttribute key="useProduct" value="false"/>
diff --git a/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/query/QueryableMetadataRepositoryManagerTest.java b/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/query/QueryableMetadataRepositoryManagerTest.java
index 1dcda22d3..ceb273c84 100644
--- a/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/query/QueryableMetadataRepositoryManagerTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/query/QueryableMetadataRepositoryManagerTest.java
@@ -193,7 +193,7 @@ public class QueryableMetadataRepositoryManagerTest extends AbstractQueryTest {
// null IUPropertyQuery collects all IUs
result = manager.query(new InstallableUnitQuery((String) null), getMonitor());
int iuCount = queryResultSize(result);
- result = manager.query(new IUPropertyQuery(null, null), getMonitor());
+ result = manager.query(new IUPropertyQuery(null, IUPropertyQuery.ANY), getMonitor());
assertEquals("2.2", iuCount, queryResultSize(result));
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/repository/CompositeMetadataRepositoryTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/repository/CompositeMetadataRepositoryTest.java
index f54645f55..a4e2084c7 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/repository/CompositeMetadataRepositoryTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/repository/CompositeMetadataRepositoryTest.java
@@ -474,7 +474,7 @@ public class CompositeMetadataRepositoryTest extends AbstractProvisioningTest {
CompositeMetadataRepository compositeRepo = createRepo(false);
compositeRepo.addChild(location1);
compositeRepo.addChild(location2);
- PipedQuery cQuery = new PipedQuery(new MatchQuery() {
+ IQuery cQuery = new LatestIUVersionQuery(new MatchQuery() {
public boolean isMatch(Object candidate) {
if (candidate instanceof IInstallableUnit) {
IInstallableUnit iInstallableUnit = (IInstallableUnit) candidate;
@@ -483,7 +483,7 @@ public class CompositeMetadataRepositoryTest extends AbstractProvisioningTest {
}
return false;
}
- }, new LatestIUVersionQuery());
+ });
IQueryResult queryResult = compositeRepo.query(cQuery, monitor);
assertEquals("1.0", 1, queryResultSize(queryResult));
assertEquals("1.1", Version.createOSGi(2, 2, 0), ((IInstallableUnit) queryResult.iterator().next()).getVersion());
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/AddIUProperty.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/AddIUProperty.java
index 9453e95be..faac57f10 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/AddIUProperty.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/AddIUProperty.java
@@ -89,7 +89,7 @@ public class AddIUProperty extends AbstractProvisioningTest {
allProfileIUs = profile.query(InstallableUnitQuery.ANY, null);
assertEquals(queryResultSize(allProfileIUs), 1);
- IQueryResult iuProfileProperties = profile.query(new IUProfilePropertyQuery(SimplePlanner.INCLUSION_RULES, null), null);
+ IQueryResult iuProfileProperties = profile.query(new IUProfilePropertyQuery(SimplePlanner.INCLUSION_RULES, IUProfilePropertyQuery.ANY), null);
assertEquals(queryResultSize(iuProfileProperties), 1);
//Remove a1 optionality - should be a no-op
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/IUProperties.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/IUProperties.java
index 8482dc581..0a872dd8c 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/IUProperties.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/IUProperties.java
@@ -8,10 +8,9 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.planner;
-import org.eclipse.equinox.internal.p2.engine.ProvisioningPlan;
-
import org.eclipse.core.runtime.IStatus;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
+import org.eclipse.equinox.internal.p2.engine.ProvisioningPlan;
import org.eclipse.equinox.internal.provisional.p2.director.ProfileChangeRequest;
import org.eclipse.equinox.p2.engine.*;
import org.eclipse.equinox.p2.engine.query.IUProfilePropertyQuery;
@@ -59,7 +58,7 @@ public class IUProperties extends AbstractProvisioningTest {
IStatus s = engine.perform(pp1, null);
if (!s.isOK())
LogHelper.log(s);
- IQueryResult queryResult = getProfile(profileId).query(new IUProfilePropertyQuery("FOO", null), null);
+ IQueryResult queryResult = getProfile(profileId).query(new IUProfilePropertyQuery("FOO", IUProfilePropertyQuery.ANY), null);
assertEquals(1, queryResultSize(queryResult));
ProfileChangeRequest req2 = new ProfileChangeRequest(profile);
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/IUPropertyRemoval.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/IUPropertyRemoval.java
index 206e018e1..8badf906e 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/IUPropertyRemoval.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/IUPropertyRemoval.java
@@ -8,9 +8,8 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.planner;
-import org.eclipse.equinox.internal.p2.engine.ProvisioningPlan;
-
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.p2.engine.ProvisioningPlan;
import org.eclipse.equinox.internal.provisional.p2.director.ProfileChangeRequest;
import org.eclipse.equinox.p2.engine.*;
import org.eclipse.equinox.p2.engine.query.IUProfilePropertyQuery;
@@ -50,7 +49,7 @@ public class IUPropertyRemoval extends AbstractProvisioningTest {
IProvisioningPlan pp1 = planner.getProvisioningPlan(req1, null, null);
assertEquals(IStatus.OK, pp1.getStatus().getSeverity());
engine.perform(pp1, null);
- IQueryResult res = getProfile(profileId).query(new IUProfilePropertyQuery("FOO", null), null);
+ IQueryResult res = getProfile(profileId).query(new IUProfilePropertyQuery("FOO", IUProfilePropertyQuery.ANY), null);
assertEquals(2, queryResultSize(res));
ProfileChangeRequest req2 = new ProfileChangeRequest(profile);
@@ -58,7 +57,7 @@ public class IUPropertyRemoval extends AbstractProvisioningTest {
ProvisioningPlan pp2 = (ProvisioningPlan) planner.getProvisioningPlan(req2, null, null);
assertEquals(1, pp2.getOperands().length);
engine.perform(pp2, null);
- IQueryResult res2 = getProfile(profileId).query(new IUProfilePropertyQuery("FOO", null), null);
+ IQueryResult res2 = getProfile(profileId).query(new IUProfilePropertyQuery("FOO", IUProfilePropertyQuery.ANY), null);
assertEquals(1, queryResultSize(res2));
}
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/EvaluatorTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/EvaluatorTest.java
index a46c4e426..137922078 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/EvaluatorTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/EvaluatorTest.java
@@ -19,6 +19,7 @@ import org.eclipse.equinox.internal.p2.metadata.IRequiredCapability;
import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory;
import org.eclipse.equinox.p2.metadata.*;
import org.eclipse.equinox.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.expression.IContextExpression;
import org.eclipse.equinox.p2.metadata.query.InstallableUnitQuery;
import org.eclipse.equinox.p2.publisher.PublisherInfo;
import org.eclipse.equinox.p2.publisher.PublisherResult;
@@ -34,8 +35,8 @@ import org.eclipse.equinox.p2.tests.TestActivator;
import org.osgi.framework.Filter;
public class EvaluatorTest extends AbstractProvisioningTest {
- private static final IQLParser parser = QL.newParser();
- private static final IQLFactory factory = QL.getFactory();
+ private static final IExpressionParser parser = ExpressionUtil.getParser();
+ private static final IExpressionFactory factory = ExpressionUtil.getFactory();
public void testArguments() throws Exception {
IExpression expr = parser.parse("'a' == $0 && 'b' == $1 && 'c' == $2");
@@ -100,7 +101,7 @@ public class EvaluatorTest extends AbstractProvisioningTest {
"parent.requiredCapabilities.unique(requirementsCache).select(rc | rc.filter == null || $2 ~= filter(rc.filter)), _, " + //
"{rcs, child | rcs.exists(rc | child ~= rc)})}).limit(10)";
- IContextExpression expr = factory.contextExpression(IInstallableUnit.class, parser.parseQuery(exprString));
+ IContextExpression expr = factory.contextExpression(parser.parseQuery(exprString));
System.out.println(expr.toString());
assertEquals(exprString, expr.toString());
}
@@ -114,12 +115,12 @@ public class EvaluatorTest extends AbstractProvisioningTest {
IExpression cmp2 = factory.equals(factory.at(factory.member(item, "properties"), factory.indexedParameter(1)), factory.indexedParameter(2));
IExpression lambda = factory.lambda(item, factory.and(cmp1, cmp2));
- IExpression latest = factory.latest(factory.select(factory.variable("everything"), lambda));
+ IExpression latest = ((IQLFactory) factory).latest(((IQLFactory) factory).select(factory.variable("everything"), lambda));
// Create the query
- IContextExpression e3 = factory.contextExpression(IInstallableUnit.class, latest, "test.bundle", "org.eclipse.equinox.p2.type.group", "true");
+ IContextExpression<IInstallableUnit> e3 = factory.contextExpression(latest, "test.bundle", "org.eclipse.equinox.p2.type.group", "true");
IMetadataRepository repo = getMDR("/testData/metadataRepo/multipleversions1");
- IQueryResult result = repo.query(new QLContextQuery(e3), new NullProgressMonitor());
+ IQueryResult result = repo.query(new QLContextQuery(IInstallableUnit.class, e3), new NullProgressMonitor());
assertEquals(queryResultSize(result), 1);
}
@@ -213,11 +214,11 @@ public class EvaluatorTest extends AbstractProvisioningTest {
env.put("osgi.ws", "gtk");
env.put("osgi.arch", "x86");
- IContextExpression expr = factory.contextExpression(IInstallableUnit.class, parser.parseQuery("" + //
+ IContextExpression<IInstallableUnit> expr = factory.contextExpression(parser.parseQuery("" + //
"select(x | x.id == $0 && x.version == $1).traverse(capabilityIndex(everything), _, { index, parent |" + //
"index.satisfiesAny(parent.requiredCapabilities.select(rc | rc.filter == null || $2 ~= rc.filter))})"), "org.eclipse.sdk.feature.group", Version.create("3.5.0.v20090423-7Q7bA7DPR-wM38__Q4iRsmx9z0KOjbpx3AbyvXd-Uq7J2"), env);
- QLContextQuery query = new QLContextQuery(expr);
+ QLContextQuery query = new QLContextQuery(IInstallableUnit.class, expr);
IMetadataRepository repo = getMDR("/testData/galileoM7");
IQueryResult result = repo.query(query, new NullProgressMonitor());
assertEquals(queryResultSize(result), 411);
@@ -235,7 +236,7 @@ public class EvaluatorTest extends AbstractProvisioningTest {
env.put("osgi.ws", "gtk");
env.put("osgi.arch", "x86");
- IContextExpression expr = factory.contextExpression(IInstallableUnit.class, parser.parseQuery("" + //
+ IContextExpression<IInstallableUnit> expr = factory.contextExpression(parser.parseQuery("" + //
"select(x | x.id == $0 && x.version == $1).traverse(parent |" + //
"$5.satisfiesAny(parent.requiredCapabilities.select(rc | rc.filter == null || $4 ~= rc.filter))).intersect(" + //
"select(x | x.id == $2 && x.version == $3).traverse(parent |" + //
@@ -247,7 +248,7 @@ public class EvaluatorTest extends AbstractProvisioningTest {
env,//
index);
- QLContextQuery query = new QLContextQuery(expr);
+ QLContextQuery query = new QLContextQuery(IInstallableUnit.class, expr);
IQueryResult result = repo.query(query, new NullProgressMonitor());
assertEquals(queryResultSize(result), 184);
}
@@ -301,10 +302,10 @@ public class EvaluatorTest extends AbstractProvisioningTest {
IExpression everything = factory.variable("everything");
IExpression lambda = factory.lambda(item, cmp1);
- IContextExpression e3 = factory.contextExpression(Object.class, factory.select(everything, lambda));
+ IContextExpression e3 = factory.contextExpression(((IQLFactory) factory).select(everything, lambda));
- IContextExpression<Object> contextExpression = factory.contextExpression(Object.class, parser.parseQuery(e3.toString()), "ian bull");
- QLContextQuery qlContextQuery = new QLContextQuery(contextExpression);
+ IContextExpression<Object> contextExpression = factory.contextExpression(parser.parseQuery(e3.toString()), "ian bull");
+ QLContextQuery qlContextQuery = new QLContextQuery(IInstallableUnit.class, contextExpression);
System.out.println(e3);
IQueryResult queryResult = qlContextQuery.perform(items.iterator());
@@ -317,7 +318,7 @@ public class EvaluatorTest extends AbstractProvisioningTest {
public void testMatchQueryInjectionInContext() throws Exception {
IMetadataRepository repo = getMDR("/testData/galileoM7");
- IContextExpression expr = factory.contextExpression(IInstallableUnit.class, parser.parseQuery("select(x | iquery($0, x) || iquery($1, x)).latest()"), new MatchQuery() {
+ IContextExpression<IInstallableUnit> expr = factory.contextExpression(parser.parseQuery("select(x | iquery($0, x) || iquery($1, x)).latest()"), new MatchQuery() {
@Override
public boolean isMatch(Object candidate) {
return "true".equals(((IInstallableUnit) candidate).getProperty("org.eclipse.equinox.p2.type.category"));
@@ -328,7 +329,7 @@ public class EvaluatorTest extends AbstractProvisioningTest {
return "true".equals(((IInstallableUnit) candidate).getProperty("org.eclipse.equinox.p2.type.group"));
}
});
- IQueryResult result = repo.query(new QLContextQuery(expr), new NullProgressMonitor());
+ IQueryResult result = repo.query(new QLContextQuery(IInstallableUnit.class, expr), new NullProgressMonitor());
assertEquals(queryResultSize(result), 497);
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/PerformanceTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/PerformanceTest.java
index 972a701fb..174433938 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/PerformanceTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/PerformanceTest.java
@@ -134,8 +134,7 @@ public class PerformanceTest extends AbstractProvisioningTest {
IInstallableUnit[] roots = new IInstallableUnit[] {(IInstallableUnit) itor.next()};
IQuery query = new QLContextQuery(IInstallableUnit.class, "" + //
- "$0.traverse(set(), capabilityIndex(everything), _, {rqCache, index, parent | " + //
- "index.satisfiesAny(parent.requiredCapabilities.unique(rqCache).select(rc | rc.filter == null || $1 ~= rc.filter))})", roots, env);
+ "$0.traverse(set(), _, { cache, parent | parent.requiredCapabilities.unique(cache).select(rc | rc.filter == null || $1 ~= rc.filter).collect(rc | everything.select(iu | iu ~= rc)).flatten()})", roots, env);
long sliceTime = 0;
long traverseTime = 0;
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/TestIndexes.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/TestIndexes.java
new file mode 100644
index 000000000..2fe2ebf99
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/TestIndexes.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * 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.tests.ql;
+
+import java.net.URI;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.IRequirement;
+import org.eclipse.equinox.p2.ql.QLContextQuery;
+import org.eclipse.equinox.p2.query.IQuery;
+import org.eclipse.equinox.p2.query.IQueryResult;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+
+public class TestIndexes extends AbstractProvisioningTest {
+
+ public void testIdIndexSimple() throws Exception {
+ IMetadataRepository repo = getMDR("/testData/galileoM7");
+ IQuery<IInstallableUnit> query = new QLContextQuery<IInstallableUnit>(IInstallableUnit.class, "select(x | x.id == $0)", "org.eclipse.sdk.feature.group");
+ IQueryResult<IInstallableUnit> result = repo.query(query, getMonitor());
+ assertEquals(queryResultSize(result), 1);
+ }
+
+ public void testIdIndexWithOR() throws Exception {
+ IMetadataRepository repo = getMDR("/testData/galileoM7");
+ IQuery<IInstallableUnit> query = new QLContextQuery<IInstallableUnit>(IInstallableUnit.class, "select(x | x.id == $0 || x.id == $1)", "org.eclipse.sdk.feature.group", "org.eclipse.sdk.feature.jar");
+ IQueryResult<IInstallableUnit> result = repo.query(query, getMonitor());
+ assertEquals(queryResultSize(result), 2);
+ }
+
+ public void testIdIndexWithNot() throws Exception {
+ IMetadataRepository repo = getMDR("/testData/galileoM7");
+ IQuery<IInstallableUnit> query = new QLContextQuery<IInstallableUnit>(IInstallableUnit.class, "select(x | x.id == $0 || x.id != $1)", "org.eclipse.sdk.feature.group", "org.eclipse.sdk.feature.jar");
+ IQueryResult<IInstallableUnit> result = repo.query(query, getMonitor());
+ assertEquals(queryResultSize(result), 3464);
+ }
+
+ public void testCapabilityIndexSimple() throws Exception {
+ IMetadataRepository repo = getMDR("/testData/galileoM7");
+ IQuery<IInstallableUnit> query = new QLContextQuery<IInstallableUnit>(IInstallableUnit.class, "select(x | x.providedCapabilities.exists(pc | pc.namespace == 'org.eclipse.equinox.p2.iu' && pc.name == $0))", "org.eclipse.core.resources");
+ IQueryResult<IInstallableUnit> result = repo.query(query, getMonitor());
+ assertEquals(queryResultSize(result), 1);
+ }
+
+ public void testCapabilityIndexMatches() throws Exception {
+ IMetadataRepository repo = getMDR("/testData/galileoM7");
+ IRequirement requirement = MetadataFactory.createRequiredCapability("org.eclipse.equinox.p2.iu", "org.eclipse.core.resources", null, null, 1, 2, true);
+ IQuery<IInstallableUnit> query = new QLContextQuery<IInstallableUnit>(IInstallableUnit.class, "select(x | x ~= $0)", requirement);
+ IQueryResult<IInstallableUnit> result = repo.query(query, getMonitor());
+ assertEquals(queryResultSize(result), 1);
+ }
+
+ private IMetadataRepository getMDR(String uri) throws Exception {
+ URI metadataRepo = getTestData("1.1", uri).toURI();
+
+ IMetadataRepositoryManager metadataManager = (IMetadataRepositoryManager) getAgent().getService(IMetadataRepositoryManager.SERVICE_NAME);
+ assertNotNull(metadataManager);
+
+ return metadataManager.loadRepository(metadataRepo, new NullProgressMonitor());
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/TestQueryReimplementation.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/TestQueryReimplementation.java
index 9a51eda88..6010bee0b 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/TestQueryReimplementation.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ql/TestQueryReimplementation.java
@@ -12,9 +12,8 @@ package org.eclipse.equinox.p2.tests.ql;
import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory;
import org.eclipse.equinox.p2.metadata.*;
-import org.eclipse.equinox.p2.metadata.expression.IExpression;
-import org.eclipse.equinox.p2.metadata.expression.IExpressionParser;
-import org.eclipse.equinox.p2.ql.*;
+import org.eclipse.equinox.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.ql.QLMatchQuery;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
@@ -26,7 +25,7 @@ public class TestQueryReimplementation extends AbstractProvisioningTest {
private static final IExpression expr2;
static {
- IQLParser parser = QL.newParser();
+ IExpressionParser parser = ExpressionUtil.getParser();
// This expression is used in case the updateFrom is an IInstallableUnitPatch
//
@@ -41,15 +40,15 @@ public class TestQueryReimplementation extends AbstractProvisioningTest {
}
public UpdateQuery(IInstallableUnit updateFrom) {
- super(IInstallableUnit.class, QL.getFactory().matchExpression(updateFrom instanceof IInstallableUnitPatch ? expr1 : expr2, updateFrom, IInstallableUnitPatch.class));
+ super(IInstallableUnit.class, ExpressionUtil.getFactory().matchExpression(updateFrom instanceof IInstallableUnitPatch ? expr1 : expr2, updateFrom, IInstallableUnitPatch.class));
}
}
public static class IUPropertyQuery extends QLMatchQuery {
- private static final IExpression expr = QL.newParser().parse("properties[$0] == $1");
+ private static final IExpression expr = ExpressionUtil.getParser().parse("properties[$0] == $1");
public IUPropertyQuery(String propertyName, String propertyValue) {
- super(IInstallableUnit.class, QL.getFactory().matchExpression(expr, propertyName, propertyValue));
+ super(IInstallableUnit.class, ExpressionUtil.getFactory().matchExpression(expr, propertyName, propertyValue));
}
}
@@ -64,7 +63,7 @@ public class TestQueryReimplementation extends AbstractProvisioningTest {
private static final IExpression idRangeQuery;
static {
- IExpressionParser parser = QL.newParser();
+ IExpressionParser parser = ExpressionUtil.getParser();
idVersionQuery = parser.parse("($0 == null || $0 == id) && ($1 == null || $1 == version)");
idRangeQuery = parser.parse("($0 == null || $0 == id) && ($1 == null || version ~= $1)");
}
@@ -87,7 +86,7 @@ public class TestQueryReimplementation extends AbstractProvisioningTest {
* @param range The version range to match
*/
public InstallableUnitQuery(String id, VersionRange range) {
- super(IInstallableUnit.class, QL.getFactory().matchExpression(idRangeQuery, id, range));
+ super(IInstallableUnit.class, ExpressionUtil.getFactory().matchExpression(idRangeQuery, id, range));
}
/**
@@ -98,7 +97,7 @@ public class TestQueryReimplementation extends AbstractProvisioningTest {
* @param version The precise version that a matching unit must have
*/
public InstallableUnitQuery(String id, Version version) {
- super(IInstallableUnit.class, QL.getFactory().matchExpression(idVersionQuery, id, version));
+ super(IInstallableUnit.class, ExpressionUtil.getFactory().matchExpression(idVersionQuery, id, version));
}
/**
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java
index c126460e7..b422333d7 100644
--- a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java
@@ -14,13 +14,13 @@ import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
-import org.eclipse.equinox.internal.p2.metadata.query.IUPropertyQuery;
import org.eclipse.equinox.internal.provisional.p2.updatechecker.*;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.engine.IProfile;
import org.eclipse.equinox.p2.engine.IProfileRegistry;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.query.IQuery;
+import org.eclipse.equinox.p2.query.MatchQuery;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.IStartup;
import org.eclipse.ui.statushandlers.StatusManager;
@@ -69,21 +69,15 @@ public class AutomaticUpdateScheduler implements IStartup {
* this query to the automatic update checker and it will be referenced during
* the life of the platform.
*/
- private class IUProfilePropertyByIdQuery extends IUPropertyQuery {
+ private class IUProfilePropertyByIdQuery extends MatchQuery<IInstallableUnit> {
+ private final String propertyName;
private IProfile cachedProfile;
/**
* Creates a new query on the given property name and value.
*/
- public IUProfilePropertyByIdQuery(String propertyName, String propertyValue) {
- super(propertyName, propertyValue);
- }
-
- protected String getProperty(IInstallableUnit iu, String name) {
- IProfile profile = getProfile();
- if (profile == null)
- return null;
- return profile.getInstallableUnitProperty(iu, name);
+ public IUProfilePropertyByIdQuery(String propertyName) {
+ this.propertyName = propertyName;
}
private IProfile getProfile() {
@@ -100,6 +94,11 @@ public class AutomaticUpdateScheduler implements IStartup {
public void postPerform() {
cachedProfile = null;
}
+
+ public boolean isMatch(IInstallableUnit candidate) {
+ IProfile profile = getProfile();
+ return profile != null && Boolean.valueOf(profile.getInstallableUnitProperty(candidate, propertyName)).booleanValue();
+ }
}
/**
@@ -171,7 +170,7 @@ public class AutomaticUpdateScheduler implements IStartup {
private IQuery<IInstallableUnit> getProfileQuery() {
// We specifically avoid using the default policy's root property so that we don't load all the
// p2 UI classes in doing so.
- return new IUProfilePropertyByIdQuery(IProfile.PROP_PROFILE_ROOT_IU, Boolean.toString(true));
+ return new IUProfilePropertyByIdQuery(IProfile.PROP_PROFILE_ROOT_IU);
}
private int getDay(IPreferenceStore pref) {
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/QueryProvider.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/QueryProvider.java
index adf89d3b3..8b5793947 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/QueryProvider.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/QueryProvider.java
@@ -92,7 +92,7 @@ public class QueryProvider {
if (context.getViewType() == IUViewQueryContext.AVAILABLE_VIEW_FLAT || !context.getUseCategories()) {
AvailableIUWrapper wrapper = new AvailableIUWrapper(queryable, element, false, context.getShowAvailableChildren());
if (showLatest)
- topLevelQuery = new PipedQuery<IInstallableUnit>(topLevelQuery, new LatestIUVersionQuery<IInstallableUnit>());
+ topLevelQuery = new LatestIUVersionQuery<IInstallableUnit>(topLevelQuery);
if (targetProfile != null)
wrapper.markInstalledIUs(targetProfile, hideInstalled);
return new ElementQueryDescriptor(queryable, topLevelQuery, new Collector<Object>(), wrapper);
@@ -114,14 +114,14 @@ public class QueryProvider {
// if it's a category, there is a special query.
if (element instanceof CategoryElement) {
if (showLatest)
- memberOfCategoryQuery = new PipedQuery<IInstallableUnit>(memberOfCategoryQuery, new LatestIUVersionQuery<IInstallableUnit>());
+ memberOfCategoryQuery = new LatestIUVersionQuery<IInstallableUnit>(memberOfCategoryQuery);
return new ElementQueryDescriptor(queryable, memberOfCategoryQuery, new Collector<Object>(), availableIUWrapper);
}
// It is not a category, we want to traverse the requirements that are groups.
@SuppressWarnings("unchecked")
IQuery<IInstallableUnit> query = CompoundQuery.createCompoundQuery(new IQuery[] {topLevelQuery, new RequiredIUsQuery(((IIUElement) element).getIU())}, true);
if (showLatest)
- query = new PipedQuery<IInstallableUnit>(query, new LatestIUVersionQuery<IInstallableUnit>());
+ query = new LatestIUVersionQuery<IInstallableUnit>(query);
// If it's not a category, these are generic requirements and should be filtered by the visibility property (topLevelQuery)
return new ElementQueryDescriptor(queryable, query, new Collector<Object>(), availableIUWrapper);
}
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF
index bc52dc44f..d410b84cb 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF
@@ -20,6 +20,7 @@ Import-Package: javax.xml.parsers,
org.eclipse.equinox.internal.provisional.p2.metadata,
org.eclipse.equinox.p2.core,
org.eclipse.equinox.p2.metadata,
+ org.eclipse.equinox.p2.metadata.expression,
org.eclipse.equinox.p2.metadata.query,
org.eclipse.equinox.p2.publisher,
org.eclipse.equinox.p2.publisher.actions,
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteXMLAction.java b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteXMLAction.java
index 886f5579d..ebd5b07c3 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteXMLAction.java
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteXMLAction.java
@@ -23,6 +23,8 @@ import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory;
import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory.InstallableUnitDescription;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.*;
+import org.eclipse.equinox.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.metadata.query.ExpressionQuery;
import org.eclipse.equinox.p2.metadata.query.InstallableUnitQuery;
import org.eclipse.equinox.p2.publisher.*;
import org.eclipse.equinox.p2.publisher.eclipse.URLEntry;
@@ -125,13 +127,15 @@ public class SiteXMLAction extends AbstractPublisherAction {
return Status.OK_STATUS;
}
+ private static final IExpression qualifierMatchExpr = ExpressionUtil.parse("id == $0 && version ~= $1"); //$NON-NLS-1$
+
private IInstallableUnit getFeatureIU(SiteFeature feature, IPublisherInfo publisherInfo, IPublisherResult results) {
String id = feature.getFeatureIdentifier() + ".feature.group"; //$NON-NLS-1$
String versionString = feature.getFeatureVersion();
Version version = versionString != null && versionString.length() > 0 ? Version.create(versionString) : Version.emptyVersion;
IQuery<IInstallableUnit> query = null;
if (version.equals(Version.emptyVersion)) {
- query = new PipedQuery<IInstallableUnit>(new InstallableUnitQuery(id), new LatestIUVersionQuery<IInstallableUnit>());
+ query = new LatestIUVersionQuery<IInstallableUnit>(new InstallableUnitQuery(id));
} else {
String qualifier;
try {
@@ -140,18 +144,10 @@ public class SiteXMLAction extends AbstractPublisherAction {
qualifier = null;
}
if (qualifier != null && qualifier.endsWith(QUALIFIER)) {
- final String v = versionString.substring(0, versionString.indexOf(QUALIFIER));
- IQuery<IInstallableUnit> qualifierQuery = new InstallableUnitQuery(id) {
- private String qualifierVersion = v.endsWith(".") ? v.substring(0, v.length() - 1) : v; //$NON-NLS-1$
-
- public boolean isMatch(IInstallableUnit candidate) {
- if (super.isMatch(candidate)) {
- return candidate.getVersion().toString().startsWith(qualifierVersion);
- }
- return false;
- }
- };
- query = new PipedQuery<IInstallableUnit>(qualifierQuery, new LatestIUVersionQuery<IInstallableUnit>());
+ String v = versionString.substring(0, versionString.indexOf(QUALIFIER));
+ String qualifierVersion = v.endsWith(".") ? v.substring(0, v.length() - 1) : v; //$NON-NLS-1$
+ IQuery<IInstallableUnit> qualifierQuery = new ExpressionQuery<IInstallableUnit>(IInstallableUnit.class, qualifierMatchExpr, id, SimplePattern.compile(qualifierVersion + '*'));
+ query = new LatestIUVersionQuery<IInstallableUnit>(qualifierQuery);
} else {
query = new LimitQuery<IInstallableUnit>(new InstallableUnitQuery(id, version), 1);
}

Back to the top