diff --git a/bundles/org.eclipse.equinox.p2.metadata/.settings/.api_filters b/bundles/org.eclipse.equinox.p2.metadata/.settings/.api_filters index d8f48e5c23..6b7f3a23f8 100644 --- a/bundles/org.eclipse.equinox.p2.metadata/.settings/.api_filters +++ b/bundles/org.eclipse.equinox.p2.metadata/.settings/.api_filters @@ -8,4 +8,12 @@ + + + + + + + + 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 3c7fb6ea53..ebd7ce45f9 100644 --- a/bundles/org.eclipse.equinox.p2.metadata/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.metadata/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.equinox.p2.metadata;singleton:=true -Bundle-Version: 2.7.100.qualifier +Bundle-Version: 2.8.0.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: org.eclipse.equinox.internal.p2.metadata; diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/QueryResult.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/QueryResult.java index 10adc0ef06..2e3a0d89ba 100644 --- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/QueryResult.java +++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/QueryResult.java @@ -14,15 +14,21 @@ package org.eclipse.equinox.internal.p2.metadata.expression; import java.lang.reflect.Array; -import java.util.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.equinox.p2.metadata.index.IIndexProvider; import org.eclipse.equinox.p2.query.IQuery; import org.eclipse.equinox.p2.query.IQueryResult; /** - * A result optimized for dealing with iterators returned from - * expression evaluation. + * A result optimized for dealing with iterators returned from expression + * evaluation. */ public class QueryResult implements IQueryResult { @@ -30,15 +36,18 @@ public class QueryResult implements IQueryResult { private boolean firstUse = true; /** - * Create an QueryResult based on the given iterator. The oneShot parameter - * can be set to true if the returned instance is expected to be perused - * only once. This will allow some optimizations since the result of the iteration doesn't - * need to be copied in preparation for a second iteration. + * Create an QueryResult based on the given iterator. The oneShot + * parameter can be set to true if the returned instance is + * expected to be perused only once. This will allow some optimizations since + * the result of the iteration doesn't need to be copied in preparation for a + * second iteration. * * @param iterator The iterator to use as the result iterator. */ public QueryResult(Iterator iterator) { - this.iterator = (iterator instanceof IRepeatableIterator) ? (IRepeatableIterator) iterator : RepeatableIterator.create(iterator); + this.iterator = (iterator instanceof IRepeatableIterator repeatable) // + ? repeatable + : RepeatableIterator.create(iterator); } public QueryResult(Collection collection) { @@ -63,31 +72,26 @@ public Iterator iterator() { @SuppressWarnings("unchecked") public T[] toArray(Class clazz) { Object provider = iterator.getIteratorProvider(); - if (provider.getClass().isArray()) + if (provider.getClass().isArray()) { return (T[]) provider; - - Collection c = toUnmodifiableSet(); - return c.toArray((T[]) Array.newInstance(clazz, c.size())); + } + return toArray(toUnmodifiableSet(), clazz); } @Override @SuppressWarnings("unchecked") public Set toSet() { Object provider = iterator.getIteratorProvider(); - if (provider instanceof Collection) - return new HashSet<>((Collection) provider); - if (provider instanceof IIndexProvider) - return iteratorToSet(((IIndexProvider) provider).everything()); - if (provider.getClass().isArray()) { + if (provider instanceof Collection collection) { + return new HashSet<>(collection); + } else if (provider instanceof IIndexProvider indexProvider) { + return iteratorToSet(indexProvider.everything()); + } else if (provider.getClass().isArray()) { T[] elems = (T[]) provider; - int idx = elems.length; - HashSet copy = new HashSet<>(idx); - while (--idx >= 0) - copy.add(elems[idx]); - return copy; + return new HashSet<>(Arrays.asList(elems)); + } else if (provider instanceof Map map) { + return new HashSet<>((Set) map.entrySet()); } - if (provider instanceof Map) - return new HashSet<>((Set) ((Map) provider).entrySet()); return iteratorToSet(iterator()); } @@ -100,17 +104,25 @@ public IQueryResult query(IQuery query, IProgressMonitor monitor) { @SuppressWarnings("unchecked") public Set toUnmodifiableSet() { Object provider = iterator.getIteratorProvider(); - if (provider instanceof Set) - return Collections.unmodifiableSet((Set) provider); - if (provider instanceof Map) - return Collections.unmodifiableSet((Set) ((Map) provider).entrySet()); + if (provider instanceof Set set) { + return Collections.unmodifiableSet(set); + } else if (provider instanceof Map map) { + return Collections.unmodifiableSet((Set) map.entrySet()); + } return toSet(); } private Set iteratorToSet(Iterator iter) { - HashSet set = new HashSet<>(); - while (iter.hasNext()) + Set set = new HashSet<>(); + while (iter.hasNext()) { set.add(iter.next()); + } return set; } + + public static T[] toArray(Collection collection, Class clazz) { + @SuppressWarnings("unchecked") + T[] arr = (T[]) Array.newInstance(clazz, collection == null ? 0 : collection.size()); + return collection != null ? collection.toArray(arr) : arr; + } } 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 index 23e5d94b63..73ca211d4c 100644 --- 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 @@ -13,16 +13,19 @@ *******************************************************************************/ package org.eclipse.equinox.p2.query; -import java.lang.reflect.Array; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; +import java.util.stream.Stream; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.equinox.internal.p2.metadata.expression.QueryResult; /** - * This class allows to adapt java collections to a p2 a query result and as such something queryable + * This class allows to adapt java collections to a p2 a query result and as + * such something queryable + * * @since 2.0 */ public class CollectionResult implements IQueryResult { @@ -49,12 +52,7 @@ public Iterator iterator() { @Override public T[] toArray(Class clazz) { - int size = collection.size(); - @SuppressWarnings("unchecked") - T[] result = (T[]) Array.newInstance(clazz, size); - if (size != 0) - collection.toArray(result); - return result; + return QueryResult.toArray(collection, clazz); } @Override @@ -71,4 +69,9 @@ public Set toUnmodifiableSet() { public String toString() { return collection.toString(); } + + @Override + public Stream stream() { + return collection.stream(); + } } diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/Collector.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/Collector.java index ffa0d6f475..6aa5f6658b 100644 --- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/Collector.java +++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/Collector.java @@ -14,15 +14,16 @@ *******************************************************************************/ package org.eclipse.equinox.p2.query; -import java.lang.reflect.Array; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; +import java.util.stream.Stream; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.equinox.internal.p2.metadata.Messages; +import org.eclipse.equinox.internal.p2.metadata.expression.QueryResult; /** * A collector is a generic visitor that collects objects passed to it, and can @@ -51,13 +52,6 @@ public static final Collector emptyCollector() { return (Collector) EMPTY_COLLECTOR; } - /** - * Creates a new collector. - */ - public Collector() { - super(); - } - /** * Accepts an object. *

@@ -96,8 +90,9 @@ public void addAll(IQueryResult queryResult) { * @return the collection being used to collect results. */ protected Collection getCollection() { - if (collected == null) + if (collected == null) { collected = new HashSet<>(); + } return collected; } @@ -119,7 +114,7 @@ public boolean isEmpty() { */ @Override public Iterator iterator() { - return collected == null ? Collections.emptyList().iterator() : collected.iterator(); + return collected == null ? Collections.emptyIterator() : collected.iterator(); } /** @@ -140,18 +135,13 @@ public int size() { */ @Override public T[] toArray(Class clazz) { - int size = collected == null ? 0 : collected.size(); - @SuppressWarnings("unchecked") - T[] result = (T[]) Array.newInstance(clazz, size); - if (size != 0) - collected.toArray(result); - return result; + return QueryResult.toArray(collected, clazz); } /** * Returns a copy of the collected objects. * - * @return An unmodifiable collection of the collected objects + * @return An modifiable collection of the collected objects */ @Override public Set toSet() { @@ -164,8 +154,9 @@ public Set toSet() { @Override public IQueryResult query(IQuery query, IProgressMonitor monitor) { IQueryResult result; - if (monitor == null) + if (monitor == null) { monitor = new NullProgressMonitor(); + } try { monitor.beginTask(Messages.performing_subquery, 1); result = query.perform(iterator()); @@ -188,4 +179,9 @@ public Set toUnmodifiableSet() { } return Collections.unmodifiableSet(collected); } + + @Override + public Stream stream() { + return collected == null ? Stream.empty() : collected.stream(); + } } diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/IQueryResult.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/IQueryResult.java index 7260a15841..1faf8a7d1f 100644 --- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/IQueryResult.java +++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/IQueryResult.java @@ -14,21 +14,25 @@ ******************************************************************************/ package org.eclipse.equinox.p2.query; +import java.util.Collection; import java.util.Iterator; import java.util.Set; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; /** - * An IQueryResult represents the results of a query. + * An IQueryResult represents the results of a query. * * @since 2.0 */ public interface IQueryResult extends IQueryable, Iterable { /** - * Returns whether this QueryResult is empty. - * @return true if this QueryResult has accepted any results, - * and false otherwise. + * Returns whether this QueryResult is empty. + * + * @return true if this QueryResult has accepted any results, and + * false otherwise. */ - public boolean isEmpty(); + boolean isEmpty(); /** * Returns an iterator on the collected objects. @@ -36,7 +40,7 @@ public interface IQueryResult extends IQueryable, Iterable { * @return an iterator of the collected objects. */ @Override - public Iterator iterator(); + Iterator iterator(); /** * Returns the collected objects as an array @@ -46,18 +50,34 @@ public interface IQueryResult extends IQueryable, Iterable { * @throws ArrayStoreException the runtime type of the specified array is * not a super-type of the runtime type of every collected object */ - public T[] toArray(Class clazz); + T[] toArray(Class clazz); /** - * Creates a new Set copy with the contents of this query result. The - * copy can be altered without any side effects on its origin. + * Creates a new Set copy with the contents of this query result. The copy can + * be altered without any side effects on its origin. + * * @return A detached copy of the result. */ - public Set toSet(); + Set toSet(); /** * Returns a Set backed by this query result. The set is immutable. + * * @return A Set backed by this query result. */ - public Set toUnmodifiableSet(); + Set toUnmodifiableSet(); + + /** + * Returns a sequential {@code Stream} of the collected objects. + * + * @implSpec The default implementation creates a sequential {@code Stream} from + * this query-results {@code Spliterator}. Implementations backed by a + * {@code Collection} should override this method and call + * {@link Collection#stream()}. + * @since 2.8 + */ + default Stream stream() { + return StreamSupport.stream(spliterator(), false); + } + }