/******************************************************************************* * Copyright (c) 2009, 2010 Cloudsmith Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cloudsmith Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.equinox.internal.p2.metadata.expression; import java.util.*; import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext; /** * An expression that will collect items recursively based on a <code>rule</code>. * The <code>rule</code> is applied for each item in the <code>collection</code> and * is supposed to create a new collection. The <code>rule</code> is then applied for each item * in the new collection. All items are collected into a set and items that are already * in that set will not be perused again. The set becomes the result of the traversal. */ final class Traverse extends CollectionFilter { Traverse(Expression collection, LambdaExpression lambda) { super(collection, lambda); } public Object evaluate(IEvaluationContext context, Iterator<?> itor) { return evaluateAsIterator(context, itor); } public Iterator<?> evaluateAsIterator(IEvaluationContext context, Iterator<?> iterator) { HashSet<Object> collector = new HashSet<Object>(); while (iterator.hasNext()) traverse(collector, iterator.next(), context); return collector.iterator(); } public int getExpressionType() { return TYPE_TRAVERSE; } public String getOperator() { return KEYWORD_TRAVERSE; } void traverse(Set<Object> collector, Object parent, IEvaluationContext context) { if (collector.add(parent)) { Variable variable = lambda.getItemVariable(); context = EvaluationContext.create(context, variable); variable.setValue(context, parent); Iterator<?> subIterator = lambda.evaluateAsIterator(context); while (subIterator.hasNext()) traverse(collector, subIterator.next(), context); } } }