Skip to main content
summaryrefslogtreecommitdiffstats
blob: 011ad8d1eeb7309a148af5c1d653cac4a959781a (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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/*******************************************************************************
 * Copyright (c) 2008 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
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.ui;

import java.net.URI;
import java.net.URL;
import org.eclipse.equinox.internal.p2.ui.model.*;
import org.eclipse.equinox.internal.p2.ui.query.*;
import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
import org.eclipse.equinox.internal.provisional.p2.director.IUProfilePropertyQuery;
import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.IUPropertyQuery;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery;
import org.eclipse.equinox.internal.provisional.p2.query.*;
import org.eclipse.equinox.internal.provisional.p2.ui.*;
import org.eclipse.equinox.internal.provisional.p2.ui.model.MetadataRepositories;
import org.eclipse.equinox.internal.provisional.p2.ui.model.Updates;
import org.eclipse.equinox.internal.provisional.p2.ui.operations.ProvisioningUtil;
import org.eclipse.equinox.internal.provisional.p2.ui.policy.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.statushandlers.StatusManager;

/**
 * Provides a default set of queries to drive the provisioning UI.
 * 
 * @since 3.5
 */

public class DefaultQueryProvider extends QueryProvider {

	private Policy policy;

	private Query allQuery = new Query() {
		public boolean isMatch(Object candidate) {
			return true;
		}
	};

	public DefaultQueryProvider(Policy policy) {
		this.policy = policy;
	}

	public ElementQueryDescriptor getQueryDescriptor(final QueriedElement element) {
		// Initialize queryable, queryContext, and queryType from the element.
		// In some cases we override this.
		IQueryable queryable = element.getQueryable();
		int queryType = element.getQueryType();
		IUViewQueryContext context = element.getQueryContext();
		if (context == null) {
			context = policy.getQueryContext();
		}
		switch (queryType) {
			case QueryProvider.ARTIFACT_REPOS :
				queryable = new QueryableArtifactRepositoryManager(context.getArtifactRepositoryFlags());
				return new ElementQueryDescriptor(queryable, null, new Collector() {
					public boolean accept(Object object) {
						if (object instanceof URL)
							return super.accept(new ArtifactRepositoryElement(element, (URI) object));
						return true;
					}
				});
			case QueryProvider.AVAILABLE_IUS :
				// Things get more complicated if the user wants to filter out installed items. 
				// This involves setting up a secondary query for installed content that the various
				// collectors will use to reject content.  We can't use a compound query because the
				// queryables are different (profile for installed content, repo for available content)
				AvailableIUCollector availableIUCollector;
				ElementQueryDescriptor installedQueryDescriptor = null;
				boolean showLatest = context.getShowLatestVersionsOnly();
				boolean hideInstalled = context.getHideAlreadyInstalled();
				String profileId = context.getInstalledProfileId();
				if (hideInstalled && profileId != null) {
					try {
						IProfile profile = ProvisioningUtil.getProfile(profileId);
						installedQueryDescriptor = new ElementQueryDescriptor(profile, new IUProfilePropertyByIdQuery(profile.getProfileId(), context.getVisibleInstalledIUProperty(), Boolean.toString(true)), new Collector());
					} catch (ProvisionException e) {
						// just bail out, we won't try to query the installed
						installedQueryDescriptor = null;
					}
				}

				// Showing children of a rollback element
				if (element instanceof RollbackRepositoryElement) {
					Query profileIdQuery = new InstallableUnitQuery(((RollbackRepositoryElement) element).getProfileId());
					Query rollbackIUQuery = new IUPropertyQuery(IInstallableUnit.PROP_TYPE_PROFILE, Boolean.toString(true));
					availableIUCollector = new RollbackIUCollector(queryable, element.getParent(element));
					return new ElementQueryDescriptor(queryable, new CompoundQuery(new Query[] {profileIdQuery, rollbackIUQuery}, true), availableIUCollector);
				}

				Query topLevelQuery = new IUPropertyQuery(context.getVisibleAvailableIUProperty(), Boolean.TRUE.toString());
				Query categoryQuery = new IUPropertyQuery(IInstallableUnit.PROP_TYPE_CATEGORY, Boolean.toString(true));

				// Showing child IU's of a group of repositories, or of a single repository
				if (element instanceof MetadataRepositories || element instanceof MetadataRepositoryElement) {
					if (context.getViewType() == IUViewQueryContext.AVAILABLE_VIEW_FLAT) {
						AvailableIUCollector collector;
						if (showLatest)
							collector = new LatestIUVersionElementCollector(queryable, element, true);
						else
							collector = new AvailableIUCollector(queryable, element, true);
						if (hideInstalled && installedQueryDescriptor != null)
							collector.hideInstalledIUs(installedQueryDescriptor);
						return new ElementQueryDescriptor(queryable, topLevelQuery, collector);
					}

					// Assume category view if it wasn't flat.
					// Installed content not a concern for collecting categories
					return new ElementQueryDescriptor(queryable, categoryQuery, new CategoryElementCollector(queryable, element, true));
				}

				// Showing children of categories that we've already collected
				// Must do this one before CategoryElement since it's a subclass
				if (element instanceof UncategorizedCategoryElement) {
					// Will have to look at all categories and groups and from there, figure out what's left
					Query firstPassQuery = new CompoundQuery(new Query[] {topLevelQuery, categoryQuery}, false);
					availableIUCollector = showLatest ? new LatestIUVersionElementCollector(queryable, element, false) : new AvailableIUCollector(queryable, element, false);
					if (hideInstalled && installedQueryDescriptor != null)
						availableIUCollector.hideInstalledIUs(installedQueryDescriptor);
					return new ElementQueryDescriptor(queryable, firstPassQuery, new UncategorizedElementCollector(queryable, element, availableIUCollector));

				}
				// If it's a category, we get the requirements and show all requirements
				// that are also visible in the available list.  Note this same query could be used to drill
				// down into any IU's requirements, but we choose not to do this (yet) in the available view.
				// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=226577
				// if (element instanceof IUElement) {
				if (element instanceof CategoryElement) {
					Query meetsAnyRequirementQuery = new AnyRequiredCapabilityQuery(((IUElement) element).getRequirements());
					if (showLatest)
						availableIUCollector = new LatestIUVersionElementCollector(queryable, element, true);
					else
						availableIUCollector = new AvailableIUCollector(queryable, element, true);
					if (hideInstalled && installedQueryDescriptor != null)
						availableIUCollector.hideInstalledIUs(installedQueryDescriptor);
					return new ElementQueryDescriptor(queryable, new CompoundQuery(new Query[] {new CompoundQuery(new Query[] {topLevelQuery, categoryQuery}, false), meetsAnyRequirementQuery}, true), availableIUCollector);
				}
				return null;
			case QueryProvider.AVAILABLE_UPDATES :
				IProfile profile;
				IInstallableUnit[] toUpdate = null;
				if (element instanceof Updates) {
					try {
						profile = ProvisioningUtil.getProfile(((Updates) element).getProfileId());
					} catch (ProvisionException e) {
						ProvUI.handleException(e, NLS.bind(ProvUIMessages.DefaultQueryProvider_ErrorRetrievingProfile, ((Updates) element).getProfileId()), StatusManager.LOG);
						return null;
					}
					toUpdate = ((Updates) element).getIUs();
				} else {
					profile = (IProfile) ProvUI.getAdapter(element, IProfile.class);
				}
				if (profile == null)
					return null;
				Collector collector;
				if (toUpdate == null) {
					collector = profile.query(new IUProfilePropertyByIdQuery(profile.getProfileId(), context.getVisibleInstalledIUProperty(), Boolean.toString(true)), new Collector(), null);
					toUpdate = (IInstallableUnit[]) collector.toArray(IInstallableUnit.class);
				}
				QueryableUpdates updateQueryable = new QueryableUpdates(toUpdate);
				if (context.getShowLatestVersionsOnly())
					collector = new LatestIUVersionCollector(updateQueryable, element, true);
				else
					collector = new Collector();
				return new ElementQueryDescriptor(updateQueryable, allQuery, collector);
			case QueryProvider.INSTALLED_IUS :
				// Querying of IU's.  We are drilling down into the requirements.
				if (element instanceof IUElement) {
					Query meetsAnyRequirementQuery = new AnyRequiredCapabilityQuery(((IUElement) element).getRequirements());
					Query visibleAsAvailableQuery = new IUPropertyQuery(context.getVisibleAvailableIUProperty(), Boolean.TRUE.toString());
					availableIUCollector = new AvailableIUCollector(queryable, element, true);
					return new ElementQueryDescriptor(queryable, new CompoundQuery(new Query[] {visibleAsAvailableQuery, meetsAnyRequirementQuery}, true), new InstalledIUCollector(queryable, element));
				}
				profile = (IProfile) ProvUI.getAdapter(element, IProfile.class);
				if (profile == null)
					return null;
				// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=229352
				// Rollback profiles are specialized/temporary instances so we must use a query that uses the profile instance, not the id.
				if (element instanceof RollbackProfileElement)
					return new ElementQueryDescriptor(profile, new IUProfilePropertyQuery(profile, context.getVisibleInstalledIUProperty(), Boolean.toString(true)), new InstalledIUCollector(profile, element));

				// Just a normal query of the installed IU's, query the profile and look for the visible ones
				return new ElementQueryDescriptor(profile, new IUProfilePropertyByIdQuery(profile.getProfileId(), context.getVisibleInstalledIUProperty(), Boolean.toString(true)), new InstalledIUCollector(profile, element));
			case QueryProvider.METADATA_REPOS :
				if (element instanceof MetadataRepositories) {
					if (queryable == null) {
						queryable = new QueryableMetadataRepositoryManager(policy, ((MetadataRepositories) element).getIncludeDisabledRepositories());
						element.setQueryable(queryable);
					}
					return new ElementQueryDescriptor(element.getQueryable(), null, new MetadataRepositoryElementCollector(element.getQueryable(), element));
				}
				return null;
			case QueryProvider.PROFILES :
				queryable = new QueryableProfileRegistry();
				return new ElementQueryDescriptor(queryable, new Query() {
					public boolean isMatch(Object candidate) {
						return ProvUI.getAdapter(candidate, IProfile.class) != null;
					}
				}, new ProfileElementCollector(null, element));
			default :
				return null;
		}
	}
}

Back to the top