diff options
author | Thomas Hallgren | 2010-02-22 01:10:11 +0000 |
---|---|---|
committer | Thomas Hallgren | 2010-02-22 01:10:11 +0000 |
commit | 8aa5a700fd1df2f75541c1329747668a0eb1716e (patch) | |
tree | 85a71b311400712ede104e6ebc524662633f745f /bundles | |
parent | 9dc753efb1afeb1c6778b8338f01c80919e8b143 (diff) | |
download | rt.equinox.p2-8aa5a700fd1df2f75541c1329747668a0eb1716e.tar.gz rt.equinox.p2-8aa5a700fd1df2f75541c1329747668a0eb1716e.tar.xz rt.equinox.p2-8aa5a700fd1df2f75541c1329747668a0eb1716e.zip |
302201 : Unify the two query approaches used in p2, step 3.
Diffstat (limited to 'bundles')
34 files changed, 281 insertions, 406 deletions
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/ApplicablePatchQuery.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/ApplicablePatchQuery.java index 4e6f0ba6f..37b347b7d 100644 --- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/ApplicablePatchQuery.java +++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/ApplicablePatchQuery.java @@ -7,20 +7,22 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.internal.p2.director; -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.query.MatchQuery; +import org.eclipse.equinox.p2.metadata.IInstallableUnitPatch; +import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil; +import org.eclipse.equinox.p2.metadata.expression.IExpression; +import org.eclipse.equinox.p2.metadata.query.ExpressionQuery; /** * A query that accepts any patch that applies to a given installable unit. */ -public class ApplicablePatchQuery extends MatchQuery<IInstallableUnit> { - IInstallableUnit iu; +public class ApplicablePatchQuery extends ExpressionQuery<IInstallableUnit> { + private static final IExpression applicablePatches = ExpressionUtil.parse(// + "applicabilityScope.empty || applicabilityScope.exists(rqArr | rqArr.all(rq | $0 ~= rq))"); //$NON-NLS-1$ /** * Creates a new patch query on the given installable unit. Patches that can @@ -28,26 +30,6 @@ public class ApplicablePatchQuery extends MatchQuery<IInstallableUnit> { * @param iu The unit to compare patches against */ public ApplicablePatchQuery(IInstallableUnit iu) { - this.iu = iu; - } - - public boolean isMatch(IInstallableUnit candidate) { - if (!(candidate instanceof IInstallableUnitPatch)) - return false; - IInstallableUnitPatch patchIU = (IInstallableUnitPatch) candidate; - IRequirement[][] scopeDescription = patchIU.getApplicabilityScope(); - if (scopeDescription.length == 0) - return true; - - for (int i = 0; i < scopeDescription.length; i++) { - int matchedScopeEntry = scopeDescription[i].length; - for (int j = 0; j < scopeDescription[i].length; j++) { - if (iu.satisfies(scopeDescription[i][j])) - matchedScopeEntry--; - } - if (matchedScopeEntry == 0) - return true; - } - return false; + super(IInstallableUnitPatch.class, applicablePatches, iu); } } diff --git a/bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/RepositoryListener.java b/bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/RepositoryListener.java index dcf0dd358..3d7c91ba8 100644 --- a/bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/RepositoryListener.java +++ b/bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/RepositoryListener.java @@ -20,11 +20,13 @@ import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; import org.eclipse.equinox.internal.p2.update.Site; import org.eclipse.equinox.p2.core.ProvisionException; import org.eclipse.equinox.p2.metadata.IInstallableUnit; +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.BundlesAction; import org.eclipse.equinox.p2.publisher.eclipse.FeaturesAction; -import org.eclipse.equinox.p2.query.*; +import org.eclipse.equinox.p2.query.IMatchQuery; +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.metadata.IMetadataRepository; @@ -212,19 +214,11 @@ public class RepositoryListener extends DirectoryChangeListener { if (!removedFiles.isEmpty() || !changes.isEmpty()) { metadataRepository.removeInstallableUnits(changes.toArray(new IInstallableUnit[changes.size()]), null); - // create a query that will identify all ius related to removed files - IMatchQuery<IInstallableUnit> removeQuery = new MatchQuery<IInstallableUnit>() { - public boolean isMatch(IInstallableUnit iu) { - String filename = iu.getProperty(FILE_NAME); - if (filename == null) { - String message = NLS.bind(Messages.filename_missing, "installable unit", iu.getId()); //$NON-NLS-1$ - LogHelper.log(new Status(IStatus.ERROR, Activator.ID, message, null)); - return false; - } - File iuFile = new File(filename); - return removedFiles.contains(iuFile); - } - }; + // create a query that will identify all ius related to removed files. + // It's safe to compare a String with a File since the auto coercion will + // first convert the String into a File. + IMatchQuery<IInstallableUnit> removeQuery = new ExpressionQuery<IInstallableUnit>(IInstallableUnit.class, // + "$1.exists(x | properties[$0] == x)", FILE_NAME, removedFiles); //$NON-NLS-1$ IQueryResult<IInstallableUnit> toRemove = metadataRepository.query(removeQuery, null); metadataRepository.removeInstallableUnits(toRemove.toArray(IInstallableUnit.class), null); } 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 7c7510130..485094bf2 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.p2.engine.query; 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 d2c3318ad..a43ab9a40 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.p2.engine.query; diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/InstallableUnitPatch.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/InstallableUnitPatch.java index 6dee5de7b..6d6ab11b6 100644 --- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/InstallableUnitPatch.java +++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/InstallableUnitPatch.java @@ -13,6 +13,10 @@ import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils; import org.eclipse.equinox.p2.metadata.*; public class InstallableUnitPatch extends InstallableUnit implements IInstallableUnitPatch { + public static final String MEMBER_APPLICABILITY_SCOPE = "applicabilityScope"; //$NON-NLS-1$ + public static final String MEMBER_LIFECYCLE = "lifeCycle"; //$NON-NLS-1$ + public static final String MEMBER_REQUIREMENTS_CHANGE = "requirementsChange"; //$NON-NLS-1$ + private IRequirementChange[] changes; private IRequirement lifeCycle; private IRequirement[][] scope; @@ -55,9 +59,11 @@ public class InstallableUnitPatch extends InstallableUnit implements IInstallabl } public Object getMember(String memberName) { - if ("lifeCycle".equals(memberName)) //$NON-NLS-1$ + if (MEMBER_APPLICABILITY_SCOPE == memberName) + return scope; + if (MEMBER_LIFECYCLE == memberName) return lifeCycle; - if ("requirementsChange".equals(memberName)) //$NON-NLS-1$ + if (MEMBER_REQUIREMENTS_CHANGE == memberName) return changes; return super.getMember(memberName); } 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 862d15014..9701bfb4b 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 @@ -19,10 +19,8 @@ import org.eclipse.core.runtime.Status; import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory; import org.eclipse.equinox.p2.metadata.*; -import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil; -import org.eclipse.equinox.p2.metadata.expression.IExpression; +import org.eclipse.equinox.p2.metadata.expression.*; import org.eclipse.equinox.p2.metadata.query.ExpressionQuery; -import org.eclipse.equinox.p2.metadata.query.FragmentQuery; import org.eclipse.equinox.p2.query.*; import org.eclipse.osgi.service.localization.LocaleProvider; @@ -42,7 +40,8 @@ public class TranslationSupport { static final String NAMESPACE_IU_LOCALIZATION = "org.eclipse.equinox.p2.localization"; //$NON-NLS-1$ private IQueryable<IInstallableUnit> fragmentSource; - private static IExpression capabilityMatch = ExpressionUtil.parse("providedCapabilities.exists(x | x.name == $0 && x.namespace == $1)"); //$NON-NLS-1$ + private static IExpression capabilityMatch = ExpressionUtil.parse("providedCapabilities.exists(x | x.namespace == $0 && $1.exists(n | x.name == n))"); //$NON-NLS-1$ + private static IExpression haveHostMatch = ExpressionUtil.parse("host.exists(h | $0 ~= h)"); //$NON-NLS-1$ // Cache the IU fragments that provide localizations for a given locale. // Map<String,SoftReference<IQueryResult>>: locale => soft reference to a queryResult @@ -222,15 +221,7 @@ public class TranslationSupport { return cached; } - final List<String> locales = localeVariants; - - @SuppressWarnings("unchecked") - IQuery<IInstallableUnit>[] localeQuery = new IQuery[locales.size()]; - for (int j = 0; j < locales.size(); j++) { - localeQuery[j] = new ExpressionQuery<IInstallableUnit>(IInstallableUnit.class, capabilityMatch, locales.get(j), NAMESPACE_IU_LOCALIZATION); - } - - IQuery<IInstallableUnit> iuQuery = PipedQuery.createPipe(new FragmentQuery(), CompoundQuery.createCompoundQuery(localeQuery, false)); + IQuery<IInstallableUnit> iuQuery = new ExpressionQuery<IInstallableUnit>(IInstallableUnitFragment.class, capabilityMatch, NAMESPACE_IU_LOCALIZATION, localeVariants); IQueryResult<IInstallableUnit> collected = fragmentSource.query(iuQuery, null); localeCollectorCache.put(locale, new SoftReference<IQueryResult<IInstallableUnit>>(collected)); return collected; @@ -254,24 +245,8 @@ public class TranslationSupport { IQueryResult<IInstallableUnit> localizationFragments = getLocalizationFragments(locales, locale); - IQuery<IInstallableUnit> hostLocalizationQuery = new MatchQuery<IInstallableUnit>() { - public boolean isMatch(IInstallableUnit object) { - boolean haveHost = false; - if (object instanceof IInstallableUnitFragment) { - IInstallableUnitFragment fragment = (IInstallableUnitFragment) object; - IRequirement[] hosts = fragment.getHost(); - for (int i = 0; i < hosts.length; i++) { - if (theUnit.satisfies(hosts[i])) { - haveHost = true; - break; - } - } - } - return haveHost; - } - }; - - IQuery<IInstallableUnit> iuQuery = PipedQuery.createPipe(new FragmentQuery(), hostLocalizationQuery); + IExpressionFactory factory = ExpressionUtil.getFactory(); + IQuery<IInstallableUnit> iuQuery = new ExpressionQuery<IInstallableUnit>(IInstallableUnitFragment.class, factory.matchExpression(haveHostMatch, theUnit)); IQueryResult<IInstallableUnit> collected = iuQuery.perform(localizationFragments.iterator()); if (!collected.isEmpty()) { String translation = null; 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 c02133f2e..46bc7f55d 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 @@ -80,6 +80,10 @@ public class ExpressionFactory implements IExpressionFactory, IExpressionConstan return new LambdaExpression((Variable) variable, (Expression) body); } + public IExpression latest(IExpression collection) { + throw failNoQL(); + } + public IExpression less(IExpression lhs, IExpression rhs) { return new Compare((Expression) lhs, (Expression) rhs, true, false); } @@ -105,6 +109,10 @@ public class ExpressionFactory implements IExpressionFactory, IExpressionConstan } public IExpression member(IExpression target, String name) { + if ("empty".equals(name)) //$NON-NLS-1$ + return new Member.EmptyMember((Expression) target); + if ("length".equals(name)) //$NON-NLS-1$ + return new Member.LengthMember((Expression) target); return new Member.DynamicMember((Expression) target, name); } diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Member.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Member.java index ab08fffed..5af889ac7 100644 --- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Member.java +++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Member.java @@ -11,6 +11,7 @@ package org.eclipse.equinox.internal.p2.metadata.expression; import java.lang.reflect.*; +import java.util.*; import org.eclipse.equinox.p2.metadata.expression.*; /** @@ -103,6 +104,50 @@ public abstract class Member extends Unary { } } + public static class LengthMember extends Member { + private static final Integer ZERO = new Integer(0); + + LengthMember(Expression operand) { + super(operand, "length", Expression.emptyArray); //$NON-NLS-1$ + } + + public Object evaluate(IEvaluationContext context) { + int len = getLength(operand.evaluate(context)); + return len == 0 ? ZERO : new Integer(len); + } + + int getLength(Object val) { + if (val == null) + return 0; + + if (val.getClass().isArray()) + return Array.getLength(val); + + if (val instanceof Collection<?>) + return ((Collection<?>) val).size(); + + if (val instanceof String) + return ((String) val).length(); + + if (val instanceof Map<?, ?>) + return ((Map<?, ?>) val).size(); + + return 0; + } + } + + public static class EmptyMember extends LengthMember { + EmptyMember(Expression operand) { + super(operand); + } + + public Object evaluate(IEvaluationContext context) { + Object val = operand.evaluate(context); + boolean empty = (val instanceof Iterator<?>) ? !((Iterator<?>) val).hasNext() : getLength(val) == 0; + return Boolean.valueOf(empty); + } + } + static final Object[] NO_ARGS = new Object[0]; static Member createDynamicMember(Expression operand, String name) { 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 1013e91aa..c8bc55d7e 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.internal.p2.metadata.query; 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 fc269117f..2e9b4b0c2 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 @@ -6,73 +6,40 @@ * * Contributors: * EclipseSource - initial API and implementation + * Cloudsmith Inc. - converted into expression based query ******************************************************************************/ package org.eclipse.equinox.internal.p2.metadata.query; -import java.util.*; +import org.eclipse.equinox.internal.p2.metadata.expression.ContextExpression; +import org.eclipse.equinox.internal.p2.metadata.expression.ExpressionFactory; import org.eclipse.equinox.p2.metadata.IVersionedId; -import org.eclipse.equinox.p2.metadata.index.IIndexProvider; -import org.eclipse.equinox.p2.metadata.index.IQueryWithIndex; -import org.eclipse.equinox.p2.query.*; +import org.eclipse.equinox.p2.metadata.expression.*; +import org.eclipse.equinox.p2.metadata.query.ExpressionContextQuery; +import org.eclipse.equinox.p2.query.IQuery; /** * This query returns the latest version for each unique VersionedID. * All other elements are discarded. */ -public class LatestIUVersionQuery<T extends IVersionedId> extends ContextQuery<T> implements IQueryWithIndex<T> { +public class LatestIUVersionQuery<T extends IVersionedId> extends ExpressionContextQuery<T> { - private final IQuery<T> query; - - public LatestIUVersionQuery() { - this.query = null; - } - - public LatestIUVersionQuery(IQuery<T> query) { - this.query = query; + private static <T> IContextExpression<T> createLatestExpression(IQuery<T> query) { + ContextExpression<T> ctxExpr = (ContextExpression<T>) createExpression(query); + IExpressionFactory factory = ExpressionUtil.getFactory(); + return factory.contextExpression(factory.latest(ctxExpr.operand), ctxExpr.getParameters()); } - /** - * Performs the LatestIUVersionQuery - */ - public IQueryResult<T> perform(Iterator<T> iterator) { - if (query != null) - iterator = query.perform(iterator).iterator(); - return latest(iterator); + private static IContextExpression<?> createLatestExpression() { + IExpressionFactory factory = ExpressionUtil.getFactory(); + return factory.contextExpression(factory.latest(ExpressionFactory.EVERYTHING)); } - public IQueryResult<T> perform(IIndexProvider<T> indexProvider) { - Iterator<T> iterator; - if (query != null) { - if (query instanceof IQueryWithIndex<?>) - iterator = ((IQueryWithIndex<T>) query).perform(indexProvider).iterator(); - else - iterator = query.perform(indexProvider.everything()).iterator(); - } else - iterator = indexProvider.everything(); - return latest(iterator); + @SuppressWarnings("unchecked") + public LatestIUVersionQuery() { + super((Class<? extends T>) IVersionedId.class, createLatestExpression()); } - private IQueryResult<T> latest(Iterator<T> iterator) { - HashMap<String, T> greatestIUVersion = new HashMap<String, T>(); - while (iterator.hasNext()) { - T versionedID = iterator.next(); - if (greatestIUVersion.containsKey(versionedID.getId())) { - T currentIU = greatestIUVersion.get(versionedID.getId()); - if (currentIU.getVersion().compareTo(versionedID.getVersion()) < 0) - greatestIUVersion.put(versionedID.getId(), versionedID); - } else - greatestIUVersion.put(versionedID.getId(), versionedID); - } - - Collection<T> values = greatestIUVersion.values(); - Iterator<T> valuesIterator = values.iterator(); - boolean continueGather = true; - - Collector<T> result = new Collector<T>(); - while (valuesIterator.hasNext() && continueGather) { - T nextIU = valuesIterator.next(); - continueGather = result.accept(nextIU); - } - return result; + public LatestIUVersionQuery(IQuery<T> query) { + super(getElementClass(query), createLatestExpression(query)); } } 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 61f97c47f..d27b230ad 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 @@ -6,38 +6,40 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Corporation - initial API and implementation + * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.internal.p2.metadata.query; -import org.eclipse.equinox.p2.metadata.*; -import org.eclipse.equinox.p2.query.MatchQuery; +import org.eclipse.equinox.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.p2.metadata.IInstallableUnitPatch; +import org.eclipse.equinox.p2.metadata.expression.*; +import org.eclipse.equinox.p2.metadata.query.ExpressionQuery; /** * A query that finds all IUs that are considered an "Update" of the * specified IU. */ -public final class UpdateQuery extends MatchQuery<IInstallableUnit> { - private IInstallableUnit updateFrom; +public final class UpdateQuery extends ExpressionQuery<IInstallableUnit> { + private static final IExpression expr1; + private static final IExpression expr2; - public UpdateQuery(IInstallableUnit updateFrom) { - this.updateFrom = updateFrom; + static { + IExpressionParser parser = ExpressionUtil.getParser(); + + // This expression is used in case the updateFrom is an IInstallableUnitPatch + // + expr1 = parser.parse("$0 ~= updateDescriptor && ($0.id != id || $0.version < version)"); //$NON-NLS-1$ + + // When updateFrom is not an IInstallableUnitPatch, we need to do one of two things depending + // on if the current item is an InstallableUnitPatch or not. + // + expr2 = parser.parse("this ~= class('org.eclipse.equinox.p2.metadata.IInstallableUnitPatch')" + // //$NON-NLS-1$ + "? $0 ~= lifeCycle" + // //$NON-NLS-1$ + ": $0 ~= updateDescriptor && ($0.id != id || $0.version < version)"); //$NON-NLS-1$ } - public boolean isMatch(IInstallableUnit candidate) { - if (candidate instanceof IInstallableUnitPatch && !(updateFrom instanceof IInstallableUnitPatch)) { - IInstallableUnitPatch potentialPatch = (IInstallableUnitPatch) candidate; - IRequirement lifeCycle = potentialPatch.getLifeCycle(); - if (lifeCycle == null) - return false; - return updateFrom.satisfies(lifeCycle); - } - IUpdateDescriptor descriptor = candidate.getUpdateDescriptor(); - if (descriptor != null && descriptor.isUpdateOf(updateFrom)) { - if (!updateFrom.getId().equals(candidate.getId())) - return true; - return updateFrom.getVersion().compareTo(candidate.getVersion()) < 0; - } - return false; + public UpdateQuery(IInstallableUnit updateFrom) { + super(IInstallableUnit.class, ExpressionUtil.getFactory().matchExpression(updateFrom instanceof IInstallableUnitPatch ? expr1 : expr2, updateFrom, IInstallableUnitPatch.class)); } } 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 1206e79ec..a86891b94 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 @@ -11,6 +11,7 @@ package org.eclipse.equinox.p2.metadata.expression; import java.util.List; +import org.eclipse.equinox.p2.metadata.IVersionedId; import org.eclipse.equinox.p2.query.IQuery; /** @@ -139,6 +140,15 @@ public interface IExpressionFactory { IExpression lambda(IExpression variable, IExpression body); /** + * Create an expression that yields a new collection consisting of the latest version of + * the elements of the <code>collection</code>. Each element in <code>collection</code> + * must implement the {@link IVersionedId} interface. + * @param collection The collection providing the versioned elements + * @return A collection expression + */ + IExpression latest(IExpression collection); + + /** * Create an expression that tests if <code>lhs</code> is less than <code>rhs</code>. * @param lhs The left hand side value. * @param rhs The right hand side value. 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 bb11a3ef0..d2d6b09c2 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.p2.metadata.query; 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 f93fbb4ab..65f6f5f1e 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.p2.metadata.query; diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/ExpressionContextQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/ExpressionContextQuery.java index 11271b470..d02ac366f 100644 --- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/ExpressionContextQuery.java +++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/metadata/query/ExpressionContextQuery.java @@ -11,13 +11,12 @@ package org.eclipse.equinox.p2.metadata.query; import java.util.Iterator; -import org.eclipse.equinox.internal.p2.metadata.expression.QueryResult; +import org.eclipse.equinox.internal.p2.metadata.expression.*; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.metadata.expression.*; import org.eclipse.equinox.p2.metadata.index.IIndexProvider; import org.eclipse.equinox.p2.metadata.index.IQueryWithIndex; -import org.eclipse.equinox.p2.query.ContextQuery; -import org.eclipse.equinox.p2.query.IQueryResult; +import org.eclipse.equinox.p2.query.*; /** * A query that evaluates using an iterator as input and produces a new iterator. @@ -58,4 +57,39 @@ public class ExpressionContextQuery<T> extends ContextQuery<T> implements IQuery public IContextExpression<T> getExpression() { return expression; } + + protected static <T> Class<? extends T> getElementClass(IQuery<T> query) { + @SuppressWarnings("unchecked") + Class<? extends T> elementClass = (Class<T>) Object.class; + if (query instanceof ExpressionQuery<?>) + elementClass = ((ExpressionQuery<T>) query).getMatchingClass(); + else if (query instanceof ExpressionContextQuery<?>) + elementClass = ((ExpressionContextQuery<T>) query).getElementClass(); + return elementClass; + } + + protected static <T> IContextExpression<T> createExpression(IQuery<T> query) { + IExpressionFactory factory = ExpressionUtil.getFactory(); + IExpression expr = query.getExpression(); + Object[] parameters; + if (expr == null) { + expr = factory.toExpression(query); + if (query instanceof IMatchQuery<?>) + expr = factory.select(ExpressionFactory.EVERYTHING, factory.lambda(ExpressionFactory.THIS, expr)); + parameters = new Object[0]; + } else { + if (expr instanceof MatchExpression<?>) { + MatchExpression<?> matchExpr = (MatchExpression<?>) expr; + parameters = matchExpr.getParameters(); + expr = factory.select(ExpressionFactory.EVERYTHING, factory.lambda(ExpressionFactory.THIS, matchExpr.operand)); + } else if (expr instanceof ContextExpression<?>) { + ContextExpression<?> contextExpr = (ContextExpression<?>) expr; + parameters = contextExpr.getParameters(); + expr = contextExpr.operand; + } else + parameters = new Object[0]; + } + return factory.contextExpression(expr, parameters); + } + } 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 de04066a3..22dfc2ef4 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.p2.metadata.query; 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 729920902..d1035cf20 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.p2.metadata.query; 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 42f5c9915..33b8e0bb5 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.p2.metadata.query; 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 e341d8efc..3217a755d 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.p2.metadata.query; diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/CompoundQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/CompoundQuery.java index 12c873329..69e2170ff 100644 --- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/CompoundQuery.java +++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/CompoundQuery.java @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * EclipseSource - ongoing development + * Cloudsmith Inc. - added index capabilities *******************************************************************************/ package org.eclipse.equinox.p2.query; diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/LimitQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/LimitQuery.java index d4b0d01a1..21e429841 100644 --- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/LimitQuery.java +++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/LimitQuery.java @@ -6,13 +6,13 @@ * * Contributors: * EclipseSource - initial API and implementation +* Cloudsmith Inc. - converted into expression based query ******************************************************************************/ package org.eclipse.equinox.p2.query; -import org.eclipse.equinox.internal.p2.metadata.expression.*; +import org.eclipse.equinox.internal.p2.metadata.expression.ContextExpression; import org.eclipse.equinox.p2.metadata.expression.*; import org.eclipse.equinox.p2.metadata.query.ExpressionContextQuery; -import org.eclipse.equinox.p2.metadata.query.ExpressionQuery; /** * A limit query can be used to limit the number of query results returned. Once @@ -21,41 +21,13 @@ import org.eclipse.equinox.p2.metadata.query.ExpressionQuery; */ public class LimitQuery<T> extends ExpressionContextQuery<T> { - private static <T> Class<? extends T> getElementClass(IQuery<T> query) { - @SuppressWarnings("unchecked") - Class<? extends T> elementClass = (Class<T>) Object.class; - if (query instanceof ExpressionQuery<?>) - elementClass = ((ExpressionQuery<T>) query).getMatchingClass(); - else if (query instanceof ExpressionContextQuery<?>) - elementClass = ((ExpressionContextQuery<T>) query).getElementClass(); - return elementClass; - } - - private static <T> IContextExpression<T> createExpression(IQuery<T> query, int limit) { + private static <T> IContextExpression<T> createLimitExpression(IQuery<T> query, int limit) { + ContextExpression<T> ctxExpr = (ContextExpression<T>) createExpression(query); IExpressionFactory factory = ExpressionUtil.getFactory(); - IExpression expr = query.getExpression(); - Object[] parameters; - if (expr == null) { - expr = factory.toExpression(query); - if (query instanceof IMatchQuery<?>) - expr = factory.select(ExpressionFactory.EVERYTHING, factory.lambda(ExpressionFactory.THIS, expr)); - parameters = new Object[0]; - } else { - if (expr instanceof MatchExpression<?>) { - MatchExpression<?> matchExpr = (MatchExpression<?>) expr; - parameters = matchExpr.getParameters(); - expr = factory.select(ExpressionFactory.EVERYTHING, factory.lambda(ExpressionFactory.THIS, matchExpr.operand)); - } else if (expr instanceof ContextExpression<?>) { - ContextExpression<?> contextExpr = (ContextExpression<?>) expr; - parameters = contextExpr.getParameters(); - expr = contextExpr.operand; - } else - parameters = new Object[0]; - } - return factory.contextExpression(factory.limit(expr, limit), parameters); + return factory.contextExpression(factory.limit(ctxExpr.operand, limit), ctxExpr.getParameters()); } public LimitQuery(IQuery<T> query, int limit) { - super(getElementClass(query), createExpression(query, limit)); + super(getElementClass(query), createLimitExpression(query, limit)); } } 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 5a1544ae7..8bb69d055 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 @@ -11,7 +11,6 @@ package org.eclipse.equinox.p2.ql; import java.util.Map; -import org.eclipse.equinox.p2.metadata.IVersionedId; import org.eclipse.equinox.p2.metadata.expression.IExpression; import org.eclipse.equinox.p2.metadata.expression.IExpressionFactory; @@ -107,15 +106,6 @@ public interface IQLFactory extends IExpressionFactory { IExpression lambda(IExpression variable, IExpression[] initialAssignments, IExpression body); /** - * Create an expression that yields a new collection consisting of the latest version of - * the elements of the <code>collection</code>. Each element in <code>collection</code> - * must implement the {@link IVersionedId} interface. - * @param collection The collection providing the versioned elements - * @return A collection expression - */ - IExpression latest(IExpression collection); - - /** * Creates a member call expression. * @param target The target for the member call * @param name The name of the member 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 deleted file mode 100644 index 9987cdc7b..000000000 --- a/bundles/org.eclipse.equinox.p2.ql/src/org/eclipse/equinox/p2/ql/QLQuery.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Cloudsmith Inc. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Cloudsmith Inc. - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.p2.ql; - -import java.util.Locale; -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> { - final Class<T> elementClass; - private Locale locale; - - protected QLQuery(Class<T> elementClass) { - this.elementClass = elementClass; - } - - public Locale getLocale() { - return locale == null ? Locale.getDefault() : locale; - } - - public void setLocale(Locale locale) { - this.locale = locale; - } - -} diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/ArtifactDescription.java b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/ArtifactDescription.java index 09d09b7e2..ed430728d 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/ArtifactDescription.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/ArtifactDescription.java @@ -1,6 +1,7 @@ package org.eclipse.equinox.p2.internal.repository.tools.tasks; -import java.util.Properties; +import java.util.HashMap; +import java.util.Map; import org.apache.tools.ant.types.DataType; import org.apache.tools.ant.types.Parameter; import org.eclipse.equinox.p2.metadata.*; @@ -13,7 +14,7 @@ public class ArtifactDescription extends DataType { private String id = null; private String version = null; private String range = null; - private Properties properties = null; + private Map<String, String> properties = null; public void setClassifier(String classifier) { this.classifier = classifier; @@ -33,7 +34,7 @@ public class ArtifactDescription extends DataType { public void addConfiguredProperty(Parameter property) { if (properties == null) - properties = new Properties(); + properties = new HashMap<String, String>(); properties.put(property.getName(), property.getValue()); } @@ -69,9 +70,6 @@ public class ArtifactDescription extends DataType { Version keyVersion = Version.parseVersion(version); keyRange = new VersionRange(keyVersion, true, keyVersion, true); } - - ArtifactDescriptorQuery query = new ArtifactDescriptorQuery(id, keyRange, null); - query.setProperties(properties); - return query; + return new ArtifactDescriptorQuery(id, keyRange, null, properties); } } diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactDescriptorQuery.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactDescriptorQuery.java index 9d660400e..0dee9e4bb 100644 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactDescriptorQuery.java +++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactDescriptorQuery.java @@ -7,15 +7,16 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.p2.repository.artifact; -import java.util.Iterator; -import java.util.Properties; +import java.util.*; +import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils; import org.eclipse.equinox.p2.metadata.VersionRange; -import org.eclipse.equinox.p2.query.MatchQuery; -import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor; +import org.eclipse.equinox.p2.metadata.expression.*; +import org.eclipse.equinox.p2.metadata.query.ExpressionQuery; /** * A general purpose query for matching {@link IArtifactDescriptor} instances @@ -23,112 +24,65 @@ import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor; * * @since 2.0 */ -public class ArtifactDescriptorQuery extends MatchQuery<IArtifactDescriptor> { +public class ArtifactDescriptorQuery extends ExpressionQuery<IArtifactDescriptor> { + + private static final IExpression descriptorMatch = ExpressionUtil.parse(// + "artifactKey.id == $0 && artifactKey.version ~= $1 && ($2.empty || $2.all(x | properties[x.key] == x.value))"); //$NON-NLS-1$ + + private static IMatchExpression<IArtifactDescriptor> createExpression(String id, VersionRange range, String format, Map<String, String> properties) { + if (range == null) + range = VersionRange.emptyRange; + if (format != null) { + if (properties == null || properties.isEmpty()) + properties = Collections.singletonMap(IArtifactDescriptor.FORMAT, format); + else { + properties = new HashMap<String, String>(properties); + properties.put(IArtifactDescriptor.FORMAT, format); + } + } else if (properties == null) + properties = CollectionUtils.emptyMap(); + + IExpressionFactory factory = ExpressionUtil.getFactory(); + return factory.<IArtifactDescriptor> matchExpression(descriptorMatch, id, range, properties); + } /** * A singleton query that will match all instances of {@link IArtifactDescriptor}. */ public static final ArtifactDescriptorQuery ALL_DESCRIPTORS = new ArtifactDescriptorQuery(); - private ArtifactDescriptor descriptor = null; - private String format = null; - private String id = null; - private Properties properties = null; - private VersionRange range = null; - private IArtifactRepository repository = null; - /** * Clients must use {@link #ALL_DESCRIPTORS}. */ private ArtifactDescriptorQuery() { //matches everything + super(IArtifactDescriptor.class, ExpressionUtil.TRUE_EXPRESSION); } /** - * The query will match candidate descriptors where: - * <pre> - * new ArtifactDescriptor(descriptor).equals(new ArtifactDescriptor(candidate)) - * </pre> - * @param descriptor The descriptor to match - */ - public ArtifactDescriptorQuery(IArtifactDescriptor descriptor) { - this.descriptor = (descriptor.getClass() == ArtifactDescriptor.class) ? (ArtifactDescriptor) descriptor : new ArtifactDescriptor(descriptor); - } - - /** - * The query will match descriptors with the given id, version and format - * If any parameter is null, that attribute will be ignored. - * - * @param id the descriptor id to match, or <code>null</code> to match any id + * The query will match descriptors with the given <code>id</code>, <code>versionRange</code> + * and <code>format</code> + * @param id the descriptor id to match. Can not be <code>null</code> * @param versionRange the descriptor version range to match or <code>null</code> to match * any version range * @param format the descriptor {@link IArtifactDescriptor#FORMAT} value to match, or <code>null</code> to * match any descriptor format */ public ArtifactDescriptorQuery(String id, VersionRange versionRange, String format) { - this(id, versionRange, format, null); + super(IArtifactDescriptor.class, createExpression(id, versionRange, format, null)); } /** - * The query will match descriptors with the given id, version range, format and repository - * if any parameter is null, that attribute will be ignored. - * - * @param id the descriptor id to match, or <code>null</code> to match any id + * The query will match descriptors with the given <code>id</code>, <code>versionRange</code>, + * <code>format</code>, and <code>properties</code>. + * @param id the descriptor id to match. Can not be <code>null</code> * @param versionRange the descriptor version range to match or <code>null</code> to match * any version range * @param format the descriptor {@link IArtifactDescriptor#FORMAT} value to match, or <code>null</code> to * match any descriptor format - * @param repository The repository of the descriptor to match, or <code>null</code> - * to match descriptors from any repository - */ - public ArtifactDescriptorQuery(String id, VersionRange versionRange, String format, IArtifactRepository repository) { - this.id = id; - this.range = versionRange; - this.format = format; - this.repository = repository; - } - - /*(non-Javadoc) - * @see org.eclipse.equinox.p2.query.MatchQuery#isMatch(java.lang.Object) - */ - public boolean isMatch(IArtifactDescriptor candidate) { - if (descriptor != null) - return matchDescriptor(candidate); - - if (id != null && !id.equals(candidate.getArtifactKey().getId())) - return false; - - if (range != null && !range.isIncluded(candidate.getArtifactKey().getVersion())) - return false; - - if (format != null && !format.equals(candidate.getProperty(IArtifactDescriptor.FORMAT))) - return false; - - if (repository != null && repository != candidate.getRepository()) - return false; - - if (properties != null) { - for (Iterator<Object> iterator = properties.keySet().iterator(); iterator.hasNext();) { - String key = (String) iterator.next(); - String value = properties.getProperty(key); - if (value != null && !value.equals(candidate.getProperty(key))) - return false; - } - } - return true; - } - - private boolean matchDescriptor(IArtifactDescriptor candidate) { - ArtifactDescriptor candidateDescriptor = (candidate.getClass() == ArtifactDescriptor.class) ? (ArtifactDescriptor) candidate : new ArtifactDescriptor(candidate); - return descriptor.equals(candidateDescriptor); - } - - /** - * Sets the properties that this query should match against. This query will only match - * descriptors that have property keys and values matching those provided here. * @param properties The properties to query for */ - public void setProperties(Properties properties) { - this.properties = properties; + public ArtifactDescriptorQuery(String id, VersionRange versionRange, String format, Map<String, String> properties) { + super(IArtifactDescriptor.class, createExpression(id, versionRange, format, properties)); } } 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 4b8bd8686..8758da2d7 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.p2.repository.artifact; diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ArtifactDescriptor.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ArtifactDescriptor.java index 68e51fb66..350e17b19 100644 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ArtifactDescriptor.java +++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ArtifactDescriptor.java @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - IMemberProvider access. *******************************************************************************/ package org.eclipse.equinox.p2.repository.artifact.spi; @@ -14,13 +15,19 @@ import java.util.Arrays; import java.util.Map; import org.eclipse.equinox.internal.p2.core.helpers.OrderedProperties; import org.eclipse.equinox.p2.metadata.IArtifactKey; +import org.eclipse.equinox.p2.metadata.expression.IMemberProvider; import org.eclipse.equinox.p2.repository.artifact.*; /** * This represents information about a given artifact stored on a particular byte server. * @since 2.0 */ -public class ArtifactDescriptor implements IArtifactDescriptor { +public class ArtifactDescriptor implements IArtifactDescriptor, IMemberProvider { + public static final String MEMBER_ARTIFACT_KEY = "artifactKey"; //$NON-NLS-1$ + public static final String MEMBER_PROCESSING_STEPS = "processingSteps"; //$NON-NLS-1$ + public static final String MEMBER_PROPERTIES = "properties"; //$NON-NLS-1$ + public static final String MEMBER_REPOSITORY = "repository"; //$NON-NLS-1$ + private static final IProcessingStepDescriptor[] EMPTY_STEPS = new ProcessingStepDescriptor[0]; protected IArtifactKey key; // The key associated with this artifact @@ -149,4 +156,20 @@ public class ArtifactDescriptor implements IArtifactDescriptor { return format + ": " + key.toString(); //$NON-NLS-1$ } + public Object getMember(String memberName) { + if (memberName == MEMBER_ARTIFACT_KEY) + return key; + + if (memberName == MEMBER_PROPERTIES) + return properties; + + if (memberName == MEMBER_PROCESSING_STEPS) + return processingSteps; + + if (memberName == MEMBER_REPOSITORY) + return repository; + + throw new IllegalArgumentException("No such member: " + memberName); //$NON-NLS-1$ + } + } diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/SimpleArtifactRepositoryTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/SimpleArtifactRepositoryTest.java index 75e0082ef..369665e57 100644 --- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/SimpleArtifactRepositoryTest.java +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/SimpleArtifactRepositoryTest.java @@ -367,11 +367,11 @@ public class SimpleArtifactRepositoryTest extends AbstractProvisioningTest { IQueryResult<IArtifactDescriptor> result = descQueryable.query(new ArtifactDescriptorQuery("a", null, null), null); assertEquals(3, queryResultSize(result)); - result = descQueryable.query(new ArtifactDescriptorQuery(null, new VersionRange("[2.0.0, 3.0.0)"), null), null); + result = descQueryable.query(new ArtifactDescriptorQuery("a", new VersionRange("[2.0.0, 3.0.0)"), null), null); assertEquals(2, queryResultSize(result)); assertNotContains(result, d1); - result = descQueryable.query(new ArtifactDescriptorQuery(null, null, IArtifactDescriptor.FORMAT_PACKED), null); + result = descQueryable.query(new ArtifactDescriptorQuery("a", null, IArtifactDescriptor.FORMAT_PACKED), null); assertEquals(1, queryResultSize(result)); IArtifactDescriptor resultDescriptor = result.iterator().next(); assertEquals(d3.getArtifactKey(), resultDescriptor.getArtifactKey()); diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.eclipse/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.touchpoint.eclipse/META-INF/MANIFEST.MF index 8f462754f..f95c89ad5 100644 --- a/bundles/org.eclipse.equinox.p2.touchpoint.eclipse/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.touchpoint.eclipse/META-INF/MANIFEST.MF @@ -20,6 +20,7 @@ Import-Package: javax.xml.parsers, org.eclipse.equinox.p2.engine, org.eclipse.equinox.p2.engine.spi, org.eclipse.equinox.p2.metadata, + org.eclipse.equinox.p2.metadata.expression, org.eclipse.equinox.p2.metadata.query, org.eclipse.equinox.p2.planner, org.eclipse.equinox.p2.publisher;resolution:=optional, diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.eclipse/src/org/eclipse/equinox/p2/touchpoint/eclipse/query/OSGiBundleQuery.java b/bundles/org.eclipse.equinox.p2.touchpoint.eclipse/src/org/eclipse/equinox/p2/touchpoint/eclipse/query/OSGiBundleQuery.java index cd143acde..ef4809413 100644 --- a/bundles/org.eclipse.equinox.p2.touchpoint.eclipse/src/org/eclipse/equinox/p2/touchpoint/eclipse/query/OSGiBundleQuery.java +++ b/bundles/org.eclipse.equinox.p2.touchpoint.eclipse/src/org/eclipse/equinox/p2/touchpoint/eclipse/query/OSGiBundleQuery.java @@ -6,26 +6,26 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Corporation - initial API and implementation + * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.p2.touchpoint.eclipse.query; -import java.util.Collection; import org.eclipse.equinox.p2.metadata.IInstallableUnit; -import org.eclipse.equinox.p2.metadata.IProvidedCapability; -import org.eclipse.equinox.p2.query.MatchQuery; +import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil; +import org.eclipse.equinox.p2.metadata.expression.IMatchExpression; +import org.eclipse.equinox.p2.metadata.query.ExpressionQuery; /** * A query matching every {@link IInstallableUnit} that describes an OSGi bundle. * @since 2.0 */ -public class OSGiBundleQuery extends MatchQuery<IInstallableUnit> { +public class OSGiBundleQuery extends ExpressionQuery<IInstallableUnit> { - /* (non-Javadoc) - * @see org.eclipse.equinox.p2.query.MatchQuery#isMatch(java.lang.Object) - */ - public boolean isMatch(IInstallableUnit candidate) { - return isOSGiBundle(candidate); + private static final IMatchExpression<IInstallableUnit> bundleTest = ExpressionUtil.getFactory().matchExpression(ExpressionUtil.parse("providedCapabilities.exists(p | p.namespace == 'osgi.bundle')")); //$NON-NLS-1$ + + public OSGiBundleQuery() { + super(IInstallableUnit.class, bundleTest); } /** @@ -34,12 +34,6 @@ public class OSGiBundleQuery extends MatchQuery<IInstallableUnit> { * @return <tt>true</tt> if the parameter describes an OSGi bundle. */ public static boolean isOSGiBundle(IInstallableUnit iu) { - Collection<IProvidedCapability> provided = iu.getProvidedCapabilities(); - for (IProvidedCapability capability : provided) { - if (capability.getNamespace().equals("osgi.bundle")) { //$NON-NLS-1$ - return true; - } - } - return false; + return bundleTest.isMatch(iu); } }
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/META-INF/MANIFEST.MF index 743825dcf..cbca47dcd 100644 --- a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/META-INF/MANIFEST.MF @@ -21,6 +21,7 @@ Import-Package: com.ibm.icu.util;version="4.0.1", org.eclipse.equinox.internal.provisional.p2.updatechecker, org.eclipse.equinox.p2.core, org.eclipse.equinox.p2.engine, + org.eclipse.equinox.p2.engine.query, org.eclipse.equinox.p2.metadata, org.eclipse.equinox.p2.metadata.query, org.eclipse.equinox.p2.operations, 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 b422333d7..cfb42f3cc 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 @@ -18,9 +18,9 @@ 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.engine.query.IUProfilePropertyQuery; 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; @@ -61,47 +61,6 @@ public class AutomaticUpdateScheduler implements IStartup { } /** - * A query that searches for {@link IInstallableUnit} instances that have - * a property associated with the specified profile, whose value matches the provided value. - * Uses the profile id instead of the profile to reference the profile. - * The profile instance is cached only during the duration of the query. - * This query is used instead of IUProfilePropertyQuery because we pass - * this query to the automatic update checker and it will be referenced during - * the life of the platform. - */ - 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) { - this.propertyName = propertyName; - } - - private IProfile getProfile() { - if (cachedProfile == null) { - IProvisioningAgent agent = (IProvisioningAgent) ServiceHelper.getService(AutomaticUpdatePlugin.getContext(), IProvisioningAgent.SERVICE_NAME); - IProfileRegistry profileRegistry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME); - if (profileRegistry != null) - cachedProfile = profileRegistry.getProfile(profileId); - } - return cachedProfile; - } - - // overridden to release profile cache - public void postPerform() { - cachedProfile = null; - } - - public boolean isMatch(IInstallableUnit candidate) { - IProfile profile = getProfile(); - return profile != null && Boolean.valueOf(profile.getInstallableUnitProperty(candidate, propertyName)).booleanValue(); - } - } - - /** * The constructor. */ public AutomaticUpdateScheduler() { @@ -170,7 +129,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); + return new IUProfilePropertyQuery(IProfile.PROP_PROFILE_ROOT_IU, Boolean.TRUE.toString()); } 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 46787ca15..4388af162 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 @@ -45,11 +45,7 @@ public class QueryProvider { public static final int INSTALLED_IUS = 6; public static final int AVAILABLE_ARTIFACTS = 7; - private IQuery<IInstallableUnit> allQuery = new MatchQuery<IInstallableUnit>() { - public boolean isMatch(IInstallableUnit candidate) { - return true; - } - }; + private IQuery<IInstallableUnit> allQuery = new ExpressionQuery<IInstallableUnit>(IInstallableUnit.class, ExpressionQuery.MATCH_ALL_UNITS); public QueryProvider(ProvisioningUI ui) { this.ui = ui; diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/query/RequiredIUsQuery.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/query/RequiredIUsQuery.java index c8590c489..3037d86b5 100644 --- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/query/RequiredIUsQuery.java +++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/query/RequiredIUsQuery.java @@ -7,13 +7,14 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Cloudsmith Inc. - converted into expression based query *******************************************************************************/ package org.eclipse.equinox.internal.p2.ui.query; -import java.util.Collection; 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.ExpressionUtil; +import org.eclipse.equinox.p2.metadata.expression.IExpression; +import org.eclipse.equinox.p2.metadata.query.ExpressionQuery; /** /** @@ -27,9 +28,9 @@ import org.eclipse.equinox.p2.query.MatchQuery; * * @since 2.0 */ -public class RequiredIUsQuery extends MatchQuery<IInstallableUnit> { +public class RequiredIUsQuery extends ExpressionQuery<IInstallableUnit> { - private final Collection<IRequirement> required; + private static final IExpression expression = ExpressionUtil.parse("$0.exists(rc | this ~= rc)"); //$NON-NLS-1$ /** * Creates a new query that will return any IU that meets any @@ -38,19 +39,6 @@ public class RequiredIUsQuery extends MatchQuery<IInstallableUnit> { * @param iu The IU whose requirements are to be checked */ public RequiredIUsQuery(IInstallableUnit iu) { - this.required = iu.getRequiredCapabilities(); - } - - /* - * (non-Javadoc) - * @see org.eclipse.equinox.internal.provisional.p2.metadata.query.MatchQuery#isMatch(java.lang.Object) - */ - public boolean isMatch(IInstallableUnit candidate) { - // meeting any requirement is sufficient to match the query. - for (IRequirement req : required) { - if (candidate.satisfies(req)) - return true; - } - return false; + super(IInstallableUnit.class, ExpressionUtil.getFactory().matchExpression(expression, iu.getRequiredCapabilities())); } } |