All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.equinox.p2.query.CompoundQueryable Maven / Gradle / Ivy

The newest version!
/******************************************************************************* 
* Copyright (c) 2009, 2010 EclipseSource 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:
*   EclipseSource - initial API and implementation
******************************************************************************/
package org.eclipse.equinox.p2.query;

import java.util.*;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
import org.eclipse.equinox.internal.p2.metadata.expression.CompoundIterator;
import org.eclipse.equinox.internal.p2.metadata.index.CompoundIndex;
import org.eclipse.equinox.internal.p2.metadata.index.IndexProvider;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.KeyWithLocale;
import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
import org.eclipse.equinox.p2.metadata.expression.IExpression;
import org.eclipse.equinox.p2.metadata.index.IIndex;
import org.eclipse.equinox.p2.metadata.index.IIndexProvider;

/**
 * A queryable that holds a number of other IQueryables and provides
 * a mechanism for querying the entire set.
 * @since 2.0
 */
public final class CompoundQueryable extends IndexProvider {

	static class PassThroughIndex implements IIndex {
		private final Iterator iterator;

		public PassThroughIndex(Iterator iterator) {
			this.iterator = iterator;
		}

		public Iterator getCandidates(IEvaluationContext ctx, IExpression variable, IExpression booleanExpr) {
			return iterator;
		}
	}

	private IQueryable[] queryables;

	public CompoundQueryable(IQueryable[] queryables) {
		this.queryables = queryables;
	}

	/**
	 * Creates a queryable that combines the given collection of input queryables
	 * 
	 * @param queryables The collection of queryables to be combined
	 */
	CompoundQueryable(Collection> queryables) {
		// don't suppress the warning as it will cause warnings in the official build
		// see bug 423628. Write this without unchecked conversion.
		this(queryables.toArray(new IQueryable[queryables.size()]));
	}

	/**
	 * Creates a queryable that combines the two provided input queryables
	 * 
	 * @param query1 The first queryable
	 * @param query2 The second queryable
	 */
	@SuppressWarnings("unchecked")
	CompoundQueryable(IQueryable query1, IQueryable query2) {
		this(new IQueryable[] {query1, query2});
	}

	public IIndex getIndex(String memberName) {
		// Check that at least one of the queryable can present an index
		// for the given member.
		boolean found = false;
		for (IQueryable queryable : queryables) {
			if (queryable instanceof IIndexProvider) {
				@SuppressWarnings("unchecked")
				IIndexProvider ip = (IIndexProvider) queryable;
				if (ip.getIndex(memberName) != null) {
					found = true;
					break;
				}
			}
		}

		if (!found)
			// Nobody had an index for this member
			return null;

		ArrayList> indexes = new ArrayList>(queryables.length);
		for (IQueryable queryable : queryables) {
			if (queryable instanceof IIndexProvider) {
				@SuppressWarnings("unchecked")
				IIndexProvider ip = (IIndexProvider) queryable;
				IIndex index = ip.getIndex(memberName);
				if (index != null)
					indexes.add(index);
				else
					indexes.add(new PassThroughIndex(ip.everything()));
			} else {
				indexes.add(new PassThroughIndex(getIteratorFromQueryable(queryable)));
			}
		}
		return indexes.size() == 1 ? indexes.get(0) : new CompoundIndex(indexes);
	}

	public Iterator everything() {
		if (queryables.length == 0)
			return Collections. emptySet().iterator();

		if (queryables.length == 1)
			return getIteratorFromQueryable(queryables[0]);

		ArrayList> iterators = new ArrayList>(queryables.length);
		for (IQueryable queryable : queryables)
			iterators.add(getIteratorFromQueryable(queryable));
		return new CompoundIterator(iterators.iterator());
	}

	public Object getManagedProperty(Object client, String memberName, Object key) {
		for (IQueryable queryable : queryables) {
			if (queryable instanceof IIndexProvider) {
				@SuppressWarnings("unchecked")
				IIndexProvider ip = (IIndexProvider) queryable;
				Object value = ip.getManagedProperty(client, memberName, key);
				if (value != null)
					return value;
			}
		}

		// When asked for translatedProperties we should return from the IU when the property is not found.
		if (client instanceof IInstallableUnit && memberName.equals(InstallableUnit.MEMBER_TRANSLATED_PROPERTIES)) {
			IInstallableUnit iu = (IInstallableUnit) client;
			return key instanceof KeyWithLocale ? iu.getProperty(((KeyWithLocale) key).getKey()) : iu.getProperty(key.toString());
		}
		return null;
	}

	static class IteratorCapture implements IQuery {
		private Iterator capturedIterator;

		public IQueryResult perform(Iterator iterator) {
			capturedIterator = iterator;
			return Collector.emptyCollector();
		}

		public IExpression getExpression() {
			return null;
		}

		Iterator getCapturedIterator() {
			return capturedIterator == null ? Collections. emptySet().iterator() : capturedIterator;
		}
	}

	private static  Iterator getIteratorFromQueryable(IQueryable queryable) {
		if (queryable instanceof IIndexProvider) {
			@SuppressWarnings("unchecked")
			IIndexProvider ip = (IIndexProvider) queryable;
			return ip.everything();
		}
		IteratorCapture capture = new IteratorCapture();
		queryable.query(capture, new NullProgressMonitor());
		return capture.getCapturedIterator();
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy