Skip to main content
summaryrefslogtreecommitdiffstats
blob: ef622876e6c02866e054782e34554b2a5203d9e9 (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*******************************************************************************
 * Copyright (c) 2007, 2009 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *     EclipseSource - ongoing development
 *******************************************************************************/
package org.eclipse.equinox.internal.provisional.p2.metadata.query;

import java.lang.reflect.Array;
import java.util.*;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.equinox.internal.p2.metadata.Messages;
import org.eclipse.equinox.p2.metadata.query.*;

/**
 * A collector is a generic visitor that collects objects passed to it,
 * and can then express the result of the visit in various forms. The collector
 * can also short-circuit a traversal by returning <code>false</code> from
 * its {@link #accept(Object)} method.
 * <p>
 * This default collector just accepts all objects passed to it.  Clients may subclass
 * to perform different processing on the objects passed to it.
 */
public class Collector implements IQueryResult, IAcceptor {
	private Set collected = null;

	/**
	 * Creates a new collector.
	 */
	public Collector() {
		super();
	}

	/**
	 * Accepts an object.
	 * <p>
	 * This default implementation adds the objects to a list. Clients may
	 * override this method to perform additional filtering, add different objects 
	 * to the list, short-circuit the traversal, or process the objects directly without 
	 * collecting them.
	 * 
	 * @param object the object to collect or visit
	 * @return <code>true</code> if the traversal should continue,
	 * or <code>false</code> to indicate the traversal should stop.
	 */
	public boolean accept(Object object) {
		getCollection().add(object);
		return true;
	}

	/**
	 * Adds the elements from one collector to this collector
	 * @param queryResult The collector from which the elements should be retrieved
	 */
	public void addAll(IQueryResult queryResult) {
		boolean keepGoing = true;
		for (Iterator iter = queryResult.iterator(); iter.hasNext() && keepGoing;) {
			keepGoing = accept(iter.next());
		}
	}

	/**
	 * Returns the collection that is being used to collect results. Unlike {@linkplain #toCollection()},
	 * this returns the actual modifiable collection that is being used to store results. The
	 * return value is only intended to be used within subclasses and should not be exposed
	 * outside of a collection class.
	 * 
	 * @return the collection being used to collect results.
	 */
	protected Collection getCollection() {
		if (collected == null)
			collected = new HashSet();
		return collected;
	}

	/**
	 * Returns whether this collector is empty.
	 * @return <code>true</code> if this collector has accepted any results,
	 * and <code>false</code> otherwise.
	 */
	public boolean isEmpty() {
		return collected == null || collected.isEmpty();
	}

	/**
	 * Returns an iterator on the collected objects.
	 * 
	 * @return an iterator of the collected objects.
	 */
	public Iterator iterator() {
		return collected == null ? Collections.EMPTY_LIST.iterator() : collected.iterator();
	}

	/**
	 * Returns the number of collected objects.
	 */
	public int size() {
		return collected == null ? 0 : collected.size();
	}

	/**
	 * Returns the collected objects as an array
	 * 
	 * @param clazz The type of array to return
	 * @return The array of results
	 * @throws ArrayStoreException the runtime type of the specified array is
	 *         not a supertype of the runtime type of every collected object
	 */
	public Object[] toArray(Class clazz) {
		int size = collected == null ? 0 : collected.size();
		Object[] result = (Object[]) Array.newInstance(clazz, size);
		if (size != 0)
			collected.toArray(result);
		return result;
	}

	/**
	 * Returns the collected objects as an immutable collection.
	 * 
	 * @return An unmodifiable collection of the collected objects
	 */
	public Collection toCollection() {
		return collected == null ? Collections.EMPTY_SET : Collections.unmodifiableSet(collected);
	}

	/**
	 * Performs a query on this results of this collector.  
	 */
	public IQueryResult query(IQuery query, IProgressMonitor monitor) {
		Collector collector = new Collector();
		Iterator iter = toCollection().iterator();
		if (monitor == null)
			monitor = new NullProgressMonitor();
		try {
			monitor.beginTask(Messages.performing_subquery, 1);
			collector = query.perform(iter, collector);
			monitor.worked(1);
		} finally {
			monitor.done();
		}
		return collector;
	}
}

Back to the top