001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: ******************************************************************************/package org.eclipse.ui.internal.provisional.views.markers;
011:
012: import java.util.ArrayList;
013: import java.util.Collection;
014: import java.util.HashMap;
015: import java.util.HashSet;
016: import java.util.Map;
017:
018: import org.eclipse.core.resources.IMarker;
019: import org.eclipse.core.resources.IProject;
020: import org.eclipse.core.resources.IResource;
021: import org.eclipse.core.resources.mapping.ResourceMapping;
022: import org.eclipse.core.runtime.CoreException;
023: import org.eclipse.core.runtime.IConfigurationElement;
024: import org.eclipse.core.runtime.IStatus;
025: import org.eclipse.ui.IMemento;
026: import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
027: import org.eclipse.ui.internal.ide.StatusUtil;
028: import org.eclipse.ui.internal.provisional.views.markers.api.FilterConfigurationArea;
029: import org.eclipse.ui.internal.provisional.views.markers.api.FiltersContributionParameters;
030: import org.eclipse.ui.internal.provisional.views.markers.api.MarkerField;
031: import org.eclipse.ui.internal.provisional.views.markers.api.MarkerFieldFilter;
032: import org.eclipse.ui.internal.provisional.views.markers.api.MarkerSupportConstants;
033: import org.eclipse.ui.statushandlers.StatusManager;
034:
035: /**
036: * MarkerFieldFilterGroup is the representation of a grouping of marker filters.
037: *
038: * @since 3.4
039: *
040: */
041: class MarkerFieldFilterGroup {
042:
043: private static final String ATTRIBUTE_ON_ANY_IN_SAME_CONTAINER = "ON_ANY_IN_SAME_CONTAINER";//$NON-NLS-1$
044: private static final String ATTRIBUTE_ON_SELECTED_AND_CHILDREN = "ON_SELECTED_AND_CHILDREN";//$NON-NLS-1$
045: private static final String ATTRIBUTE_ON_SELECTED_ONLY = "ON_SELECTED_ONLY"; //$NON-NLS-1$
046:
047: /**
048: * The attribute values for the scope
049: *
050: */
051:
052: private static final String ATTRIBUTE_SCOPE = "scope"; //$NON-NLS-1$
053:
054: private static final String ATTRIBUTE_VALUES = "values"; //$NON-NLS-1$
055:
056: private static final IProject[] EMPTY_PROJECT_ARRAY = new IProject[0];
057:
058: /**
059: * Constant for any element.
060: */
061: static final int ON_ANY = 0;
062:
063: /**
064: * Constant for any element in same container.
065: */
066: static final int ON_ANY_IN_SAME_CONTAINER = 3;
067:
068: /**
069: * Constant for selected element and children.
070: */
071: static final int ON_SELECTED_AND_CHILDREN = 2;
072: /**
073: * Constant for any selected element only.
074: */
075: static final int ON_SELECTED_ONLY = 1;
076: /**
077: * Constant for on working set.
078: */
079: static final int ON_WORKING_SET = 4;
080: static final String TAG_ENABLED = "enabled"; //$NON-NLS-1$
081: private static final String TAG_SCOPE = "scope"; //$NON-NLS-1$
082: private static final String TAG_FIELD_FILTER_ENTRY = "fieldFilter"; //$NON-NLS-1$
083:
084: /**
085: * Returns the set of projects that contain the given set of resources.
086: *
087: * @param resources
088: * @return IProject[]
089: */
090: static IProject[] getProjects(IResource[] resources) {
091: if (resources == null)
092: return EMPTY_PROJECT_ARRAY;
093:
094: Collection projects = getProjectsAsCollection(resources);
095:
096: return (IProject[]) projects.toArray(new IProject[projects
097: .size()]);
098: }
099:
100: /**
101: * Return the projects for the elements.
102: *
103: * @param elements
104: * collection of IResource or IResourceMapping
105: * @return Collection of IProject
106: */
107: static Collection getProjectsAsCollection(Object[] elements) {
108: HashSet projects = new HashSet();
109:
110: for (int idx = 0; idx < elements.length; idx++) {
111: if (elements[idx] instanceof IResource) {
112: projects.add(((IResource) elements[idx]).getProject());
113: } else {
114: IProject[] mappingProjects = (((ResourceMapping) elements[idx])
115: .getProjects());
116: for (int i = 0; i < mappingProjects.length; i++) {
117: projects.add(mappingProjects[i]);
118: }
119: }
120:
121: }
122:
123: return projects;
124: }
125:
126: private MarkerContentGenerator contentGenerator;
127:
128: private IConfigurationElement element;
129:
130: private Map EMPTY_MAP = new HashMap();
131: private boolean enabled = true;
132: private MarkerFieldFilter[] fieldFilters;
133: private int scope;
134:
135: /**
136: * Create a new instance of the receiver.
137: *
138: * @param configurationElement
139: * @param generator
140: */
141: public MarkerFieldFilterGroup(
142: IConfigurationElement configurationElement,
143: MarkerContentGenerator generator) {
144: element = configurationElement;
145: scope = processScope(element);
146: contentGenerator = generator;
147: }
148:
149: /**
150: * Get all of the filter configuration areas defined on the receiver.
151: *
152: * @return Collection of FilterConfigurationArea
153: */
154: Collection getFieldFilterAreas() {
155:
156: Collection areas = new ArrayList();
157: MarkerField[] fields = contentGenerator.getVisibleFields();
158: for (int i = 0; i < fields.length; i++) {
159: FilterConfigurationArea area = fields[i]
160: .generateFilterArea();
161: if (area != null) {
162: areas.add(area);
163: }
164: }
165: return areas;
166: }
167:
168: /**
169: * Get the filters registered on the receiver.
170: *
171: * @return MarkerFieldFilter[]
172: */
173: private MarkerFieldFilter[] getFieldFilters() {
174: if (fieldFilters == null) {
175: Map values = getValues();
176: Collection filters = new ArrayList();
177: MarkerField[] fields = contentGenerator.getVisibleFields();
178: for (int i = 0; i < fields.length; i++) {
179: MarkerFieldFilter fieldFilter = fields[i]
180: .generateFilter();
181: if (fieldFilter != null) {
182: filters.add(fieldFilter);
183:
184: // The type filter needs information from the generator
185: if (fieldFilter instanceof MarkerTypeFieldFilter)
186: // Show everything by default
187: ((MarkerTypeFieldFilter) fieldFilter)
188: .setAndSelectAllTypes(contentGenerator
189: .getMarkerTypes());
190: if (values != null)
191: fieldFilter.initialize(values);
192: }
193: }
194: fieldFilters = new MarkerFieldFilter[filters.size()];
195: filters.toArray(fieldFilters);
196: }
197: return fieldFilters;
198: }
199:
200: /**
201: * Return the MarkerFieldFilter for field or <code>null</code> if there
202: * isn't one.
203: *
204: * @param field
205: * @return MarkerFieldFilter
206: */
207: public MarkerFieldFilter getFilter(MarkerField field) {
208: MarkerFieldFilter[] filters = getFieldFilters();
209: for (int i = 0; i < filters.length; i++) {
210: if (filters[i].getField().equals(field))
211: return filters[i];
212: }
213: return null;
214: }
215:
216: /**
217: * Return the name of the receiver.
218: *
219: * @return
220: */
221: public String getName() {
222: return element
223: .getAttribute(MarkerSupportConstants.ATTRIBUTE_NAME);
224: }
225:
226: /**
227: * Return the id of the receiver.
228: *
229: * @return
230: */
231: public String getID() {
232: return element
233: .getAttribute(MarkerSupportConstants.ATTRIBUTE_ID);
234: }
235:
236: /**
237: * Get the root types for the receiver
238: *
239: * @return
240: */
241: public Collection getAllTypes() {
242: return contentGenerator.getMarkerTypes();
243: }
244:
245: /**
246: * Return the value of the scope.
247: *
248: * @return int
249: * @see #ON_ANY
250: * @see #ON_ANY_IN_SAME_CONTAINER
251: * @see #ON_SELECTED_AND_CHILDREN
252: * @see #ON_SELECTED_ONLY
253: * @see #ON_WORKING_SET
254: */
255: public int getScope() {
256: return scope;
257: }
258:
259: /**
260: * Get the values defined for the receiver.
261: *
262: * @return Map of values to apply to a {@link MarkerFieldFilter}
263: */
264: private Map getValues() {
265:
266: try {
267: String className = element.getAttribute(ATTRIBUTE_VALUES);
268: if (className != null) {
269: FiltersContributionParameters parameters = (FiltersContributionParameters) IDEWorkbenchPlugin
270: .createExtension(element, ATTRIBUTE_VALUES);
271: return parameters.getParameterValues();
272: }
273: } catch (CoreException e) {
274: StatusManager.getManager().handle(e.getStatus());
275: return null;
276: }
277: return EMPTY_MAP;
278:
279: }
280:
281: /**
282: * Return whether or not the receiver is enabled.
283: *
284: * @return boolean
285: */
286: public boolean isEnabled() {
287: return enabled;
288: }
289:
290: /**
291: * Make a working copy of the receiver.
292: *
293: * @return MarkerFieldFilterGroup or <code> null</code> if it failed.
294: */
295: MarkerFieldFilterGroup makeWorkingCopy() {
296: MarkerFieldFilterGroup clone = new MarkerFieldFilterGroup(
297: this .element, this .contentGenerator);
298: clone.scope = this .scope;
299: clone.enabled = this .enabled;
300: clone.fieldFilters = new MarkerFieldFilter[getFieldFilters().length];
301: for (int i = 0; i < fieldFilters.length; i++) {
302: try {
303: clone.fieldFilters[i] = (MarkerFieldFilter) fieldFilters[i]
304: .getClass().newInstance();
305: fieldFilters[i]
306: .populateWorkingCopy(clone.fieldFilters[i]);
307: } catch (InstantiationException e) {
308: StatusManager.getManager().handle(
309: StatusUtil.newStatus(IStatus.ERROR, e
310: .getLocalizedMessage(), e),
311: StatusManager.SHOW);
312: return null;
313: } catch (IllegalAccessException e) {
314: StatusManager.getManager().handle(
315: StatusUtil.newStatus(IStatus.ERROR, e
316: .getLocalizedMessage(), e),
317: StatusManager.SHOW);
318: return null;
319: }
320:
321: }
322: return clone;
323:
324: }
325:
326: /**
327: * Process the scope attribute.
328: *
329: * @param configurationElement
330: * @return int
331: */
332: private int processScope(IConfigurationElement configurationElement) {
333: String scopeValue = element.getAttribute(ATTRIBUTE_SCOPE);
334:
335: if (scopeValue.equals(ATTRIBUTE_ON_SELECTED_ONLY))
336: return ON_SELECTED_ONLY;
337:
338: if (scopeValue.equals(ATTRIBUTE_ON_SELECTED_AND_CHILDREN))
339: return ON_SELECTED_AND_CHILDREN;
340:
341: if (scopeValue.equals(ATTRIBUTE_ON_ANY_IN_SAME_CONTAINER))
342: return ON_ANY_IN_SAME_CONTAINER;
343:
344: return ON_ANY;
345: }
346:
347: /**
348: * Return whether or not this IMarker is being shown.
349: *
350: * @param marker
351: * @return <code>true</code> if it is being shown
352: */
353: public boolean select(IMarker marker) {
354: MarkerFieldFilter[] filters = getFieldFilters();
355: for (int i = 0; i < filters.length; i++) {
356: if (filters[i].select(marker))
357: continue;
358: return false;
359: }
360: return true;
361: }
362:
363: /**
364: * Set the scope of the receiver.
365: *
366: * @param newScope
367: */
368: public void setScope(int newScope) {
369: scope = newScope;
370: }
371:
372: /**
373: * Save the settings for the receiver in the memento.
374: *
375: * @param memento
376: */
377: void saveFilterSettings(IMemento memento) {
378: memento.putString(TAG_ENABLED, String.valueOf(enabled));
379: memento.putString(TAG_SCOPE, String.valueOf(scope));
380: MarkerFieldFilter[] filters = getFieldFilters();
381:
382: for (int i = 0; i < filters.length; i++) {
383: IMemento child = memento.createChild(
384: TAG_FIELD_FILTER_ENTRY, filters[i].getID());
385: filters[i].saveSettings(child);
386:
387: }
388:
389: }
390:
391: /**
392: * Load the current settings from the child.
393: *
394: * @param memento -
395: * the memento to load from
396: */
397: void loadSettings(IMemento memento) {
398:
399: String enabledString = memento.getString(TAG_ENABLED);
400: if (enabledString != null && enabledString.length() > 0)
401: enabled = Boolean.valueOf(enabledString).booleanValue();
402: scope = memento.getInteger(TAG_SCOPE).intValue();
403:
404: Map filterMap = new HashMap();
405: MarkerFieldFilter[] filters = getFieldFilters();
406: for (int i = 0; i < filters.length; i++) {
407: filterMap.put(filters[i].getID(), filters[i]);
408:
409: }
410:
411: IMemento[] children = memento
412: .getChildren(TAG_FIELD_FILTER_ENTRY);
413: for (int i = 0; i < children.length; i++) {
414: IMemento childMemento = children[i];
415: String id = childMemento.getID();
416: if (filterMap.containsKey(id)) {
417: ((MarkerFieldFilter) filterMap.get(id))
418: .loadSettings(childMemento);
419: }
420: }
421:
422: }
423:
424: /**
425: * Set whether or not the receiver is enabled.
426: *
427: * @param enabled
428: * The enabled to set.
429: */
430: void setEnabled(boolean enabled) {
431: this.enabled = enabled;
432: }
433: }
|