Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 241dd649d272a7e761e5f81d5a942464d3be8795 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*******************************************************************************
 * 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.ql;

import java.util.*;

/**
 * An expression that ensures that the elements of its collection is only returned
 * once throughout the whole query.
 */
public final class Unique extends Binary {
	public static class UniqueIterator extends MatchIteratorFilter {
		private final Set uniqueSet;

		public UniqueIterator(Class instanceClass, Iterator iterator, Set uniqueSet) {
			super(instanceClass, iterator);
			this.uniqueSet = uniqueSet;
		}

		protected boolean isMatch(Object val) {
			synchronized (uniqueSet) {
				return uniqueSet.add(val);
			}
		}
	}

	static final String OPERATOR = "unique"; //$NON-NLS-1$

	public Unique(Expression collection, Expression cacheId) {
		super(collection, cacheId);
	}

	public Object evaluate(ExpressionContext context, VariableScope scope) {
		Object explicitCache = rhs.evaluate(context, scope);
		Set uniqueSet;
		if (explicitCache == null)
			// No cache, we just ensure that the iteration is unique
			uniqueSet = new HashSet();
		else {
			if (!(explicitCache instanceof Set))
				throw new IllegalArgumentException("Unique cache must be a java.util.Set"); //$NON-NLS-1$
			uniqueSet = (Set) explicitCache;
		}
		return new UniqueIterator(Object.class, lhs.evaluateAsIterator(context, scope), uniqueSet);
	}

	public void toString(StringBuffer bld) {
		CollectionFilter.appendProlog(bld, lhs, getOperator());
		if (rhs != Constant.NULL_CONSTANT)
			appendOperand(bld, rhs, ExpressionParser.PRIORITY_COMMA);
		bld.append(')');
	}

	String getOperator() {
		return OPERATOR;
	}

	int getPriority() {
		return ExpressionParser.PRIORITY_COLLECTION;
	}

}

Back to the top