blob: 30683207e7a8e0293587b368a3d88653ccfc1239 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.views.markers.internal;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.ui.IContainmentAdapter;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PlatformUI;
class MarkerFilter implements IFilter {
private static final String TAG_DIALOG_SECTION = "filter"; //$NON-NLS-1$
private static final String TAG_ENABLED = "enabled"; //$NON-NLS-1$
private static final String TAG_FILTER_ON_MARKER_LIMIT = "filterOnMarkerLimit"; //$NON-NLS-1$
private static final String TAG_MARKER_LIMIT = "markerLimit"; //$NON-NLS-1$
private static final String TAG_ON_RESOURCE = "onResource"; //$NON-NLS-1$
private static final String TAG_SELECTED_TYPES = "selectedType"; //$NON-NLS-1$
private static final String TAG_WORKING_SET = "workingSet"; //$NON-NLS-1$
private static final String TAG_TYPES_DELIMITER = ":"; //$NON-NLS-1$
static final int ON_ANY_RESOURCE = 0;
static final int ON_SELECTED_RESOURCE_ONLY = 1;
static final int ON_SELECTED_RESOURCE_AND_CHILDREN = 2;
static final int ON_ANY_RESOURCE_OF_SAME_PROJECT = 3;
static final int ON_WORKING_SET = 4;
static final int DEFAULT_MARKER_LIMIT = 2000;
static final boolean DEFAULT_FILTER_ON_MARKER_LIMIT = true;
static final int DEFAULT_ON_RESOURCE = ON_ANY_RESOURCE;
static final boolean DEFAULT_ACTIVATION_STATUS = true;
protected List rootTypes = new ArrayList();
protected List selectedTypes = new ArrayList();
protected IWorkingSet workingSet;
protected int onResource;
protected boolean filterOnMarkerLimit;
protected boolean enabled;
protected int markerLimit;
private MarkerTypesModel typesModel;
private IResource[] focusResource;
MarkerFilter(String[] rootTypes) {
typesModel = new MarkerTypesModel();
for (int i = 0; i < rootTypes.length; i++) {
MarkerType type = typesModel.getType(rootTypes[i]);
if (!this.rootTypes.contains(type))
this.rootTypes.add(type);
}
}
private void addAllSubTypes() {
for (int i = 0; i < rootTypes.size(); i++) {
MarkerType rootType = (MarkerType) rootTypes.get(i);
addAllSubTypes(rootType);
}
}
private void addAllSubTypes(MarkerType type) {
if (type == null)
return;
if (!selectedTypes.contains(type))
selectedTypes.add(type);
MarkerType[] subTypes = type.getSubtypes();
for (int i = 0; i < subTypes.length; i++)
addAllSubTypes(subTypes[i]);
}
public Object[] filter(Object[] elements) {
if (elements == null)
return new Object[0];
List filteredElements = new ArrayList();
for (int i = 0; i < elements.length; i++) {
Object element = elements[i];
if (select(element))
filteredElements.add(element);
}
return filteredElements.toArray();
}
public boolean select(Object item) {
if (!isEnabled()) {
return true;
}
if (!(item instanceof IMarker))
return false;
IMarker marker = (IMarker) item;
return selectByType(marker) && selectBySelection(marker);
}
private boolean selectByType(IMarker marker) {
String type;
try {
type = marker.getType();
}
catch (CoreException e) {
return false;
}
return selectedTypes.contains(typesModel.getType(type));
}
/**
* Returns whether the specified marker should be filter out or not.
*
* @param marker the marker to test
* @return
* true=the marker should not be filtered out
* false=the marker should be filtered out
*/
private boolean selectBySelection(IMarker marker) {
if (onResource == ON_ANY_RESOURCE || marker == null)
return true;
if (focusResource == null)
return true;
IResource resource = marker.getResource();
if (onResource == ON_WORKING_SET) {
if (workingSet == null)
return true;
if (resource != null)
return isEnclosed(resource);
} else if (onResource == ON_ANY_RESOURCE_OF_SAME_PROJECT) {
IProject project = resource.getProject();
for (int i = 0; i < focusResource.length; i++) {
IProject selectedProject = focusResource[i].getProject();
if (project.equals(selectedProject))
return true;
}
} else if (onResource == ON_SELECTED_RESOURCE_ONLY) {
for (int i = 0; i < focusResource.length; i++) {
if (resource.equals(focusResource[i]))
return true;
}
} else if (onResource == ON_SELECTED_RESOURCE_AND_CHILDREN) {
for (int i = 0; i < focusResource.length; i++) {
IResource parentResource = resource;
while (parentResource != null) {
if (parentResource.equals(focusResource[i]))
return true;
parentResource = parentResource.getParent();
}
}
}
return false;
}
/**
* Returns if the given resource is enclosed by a working set element.
* The IContainmentAdapter of each working set element is used for the
* containment test. If there is no IContainmentAdapter for a working
* set element, a simple resource based test is used.
*
* @param element resource to test for enclosure by a working set
* element
* @return true if element is enclosed by a working set element and
* false otherwise.
*/
private boolean isEnclosed(IResource element) {
IPath elementPath = element.getFullPath();
IAdaptable[] workingSetElements = workingSet.getElements();
if (elementPath.isEmpty() || elementPath.isRoot())
return false;
for (int i = 0; i < workingSetElements.length; i++) {
IAdaptable workingSetElement = workingSetElements[i];
IContainmentAdapter containmentAdapter = (IContainmentAdapter) workingSetElement.getAdapter(IContainmentAdapter.class);
// if there is no IContainmentAdapter defined for the working
// set element type fall back to using resource based
// containment check
if (containmentAdapter != null) {
if (containmentAdapter.contains(workingSetElement, element, IContainmentAdapter.CHECK_CONTEXT | IContainmentAdapter.CHECK_IF_CHILD | IContainmentAdapter.CHECK_IF_DESCENDANT))
return true;
} else if (isEnclosedResource(element, elementPath, workingSetElement)) {
return true;
}
}
return false;
}
/**
* Returns if the given resource is enclosed by a working set element.
* A resource is enclosed if it is either a parent of a working set
* element, a child of a working set element or a working set element
* itself.
* Simple path comparison is used. This is only guaranteed to return
* correct results for resource working set elements.
*
* @param element resource to test for enclosure by a working set
* element
* @param elementPath full, absolute path of the element to test
* @return true if element is enclosed by a working set element and
* false otherwise.
*/
private boolean isEnclosedResource(IResource element, IPath elementPath, IAdaptable workingSetElement) {
IResource workingSetResource = null;
if (workingSetElement.equals(element))
return true;
if (workingSetElement instanceof IResource)
workingSetResource = (IResource) workingSetElement;
else
workingSetResource = (IResource) workingSetElement.getAdapter(IResource.class);
if (workingSetResource != null) {
IPath resourcePath = workingSetResource.getFullPath();
if (resourcePath.isPrefixOf(elementPath))
return true;
}
return false;
}
/**
* @return the defined limit on the number of markers to be displayed.
*/
int getMarkerLimit() {
return markerLimit;
}
/**
* Sets the limit on the number of markers to be displayed.
*
* @param the new limit
*/
void setMarkerLimit(int markerLimit) {
this.markerLimit = markerLimit;
}
/**
* @return <ul>
* <li><code>MarkerFilter.ON_ANY_RESOURCE</code> if showing items associated with any resource.</li>
* <li><code>MarkerFilter.ON_SELECTED_RESOURCE_ONLY</code> if showing items associated with
* the selected resource within the workbench.</li>
* <li><code>MarkerFilter.ON_SELECTED_RESOURCE_AND_CHILDREN</code> if showing items associated with
* the selected resource within the workbench and its children.</li>
* <li><code>MarkerFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT</code> if showing items in the same project
* as the selected resource within the workbench.</li>
* <li><code>MarkerFilter.ON_WORKING_SET</code> if showing items in some working set.</li>
* </ul>
*/
int getOnResource() {
return onResource;
}
/**
* Sets the type of filtering by selection.
*
* @param onResource must be one of:
* <ul>
* <li><code>MarkerFilter.ON_ANY_RESOURCE</code></li>
* <li><code>MarkerFilter.ON_SELECTED_RESOURCE_ONLY</code></li>
* <li><code>MarkerFilter.ON_SELECTED_RESOURCE_AND_CHILDREN</code></li>
* <li><code>MarkerFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT</code></li>
* <li><code>MarkerFilter.ON_WORKING_SET</code></li>
* </ul>
*/
void setOnResource(int onResource) {
if (onResource >= ON_ANY_RESOURCE && onResource <= ON_WORKING_SET)
this.onResource = onResource;
}
/**
* @return the selected resource(s) withing the workbench.
*/
IResource[] getFocusResource() {
return focusResource;
}
/**
* Sets the focused resources.
*/
void setFocusResource(IResource[] resources) {
focusResource = resources;
}
/**
* @return
* <ul>
* <li><code>true</code> if the filter is enabled.</li>
* <li><code>false</code> if the filter is not enabled.</li>
* </ul>
*/
boolean isEnabled() {
return enabled;
}
/**
* @return
* <ul>
* <li><code>true</code> if filtering by marker limit is enabled.</li>
* <li><code>false</code> if filtering by marker limit is not enabled.</li>
* </ul>
*/
boolean getFilterOnMarkerLimit() {
return filterOnMarkerLimit;
}
/**
* @return the root marker types.
*/
List getRootTypes() {
return rootTypes;
}
/**
* @return the selected marker types to be displayed.
*/
List getSelectedTypes() {
return selectedTypes;
}
/**
* @return the current working set or <code>null</code> if no working set is defined.
*/
IWorkingSet getWorkingSet() {
return workingSet;
}
/**
* Sets the enablement state of the filter.
*/
void setEnabled(boolean enabled) {
this.enabled = enabled;
}
/**
* Sets the enablement state of filtering by marker limit.
*/
void setFilterOnMarkerLimit(boolean filterOnMarkerLimit) {
this.filterOnMarkerLimit = filterOnMarkerLimit;
}
/**
* Sets the selected marker types to be displayed. The List <b>MUST ONLY</b> contain
* <code>MarkerType</code> objects.
*/
void setSelectedTypes(List selectedTypes) {
this.selectedTypes = selectedTypes;
}
/**
* Sets the current working set.
*/
void setWorkingSet(IWorkingSet workingSet) {
this.workingSet = workingSet;
}
void resetState() {
enabled = DEFAULT_ACTIVATION_STATUS;
filterOnMarkerLimit = DEFAULT_FILTER_ON_MARKER_LIMIT;
markerLimit = DEFAULT_MARKER_LIMIT;
onResource = DEFAULT_ON_RESOURCE;
selectedTypes.clear();
addAllSubTypes();
workingSet = null;
}
public void restoreState(IDialogSettings dialogSettings) {
resetState();
IDialogSettings settings = dialogSettings.getSection(TAG_DIALOG_SECTION);
if (settings != null) {
String setting = settings.get(TAG_ENABLED);
if (setting != null)
enabled = Boolean.valueOf(setting).booleanValue();
setting = settings.get(TAG_FILTER_ON_MARKER_LIMIT);
if (setting != null)
filterOnMarkerLimit = Boolean.valueOf(setting).booleanValue();
setting = settings.get(TAG_MARKER_LIMIT);
if (setting != null)
try {
markerLimit = Integer.parseInt(setting);
}
catch (NumberFormatException eNumberFormat) {
}
setting = settings.get(TAG_ON_RESOURCE);
if (setting != null)
try {
onResource = Integer.parseInt(setting);
}
catch (NumberFormatException eNumberFormat) {
}
setting = settings.get(TAG_SELECTED_TYPES);
if (setting != null) {
selectedTypes.clear();
StringTokenizer stringTokenizer = new StringTokenizer(setting);
while (stringTokenizer.hasMoreTokens()) {
MarkerType markerType = typesModel.getType(stringTokenizer.nextToken(TAG_TYPES_DELIMITER));
if (markerType != null && !selectedTypes.contains(markerType))
selectedTypes.add(markerType);
}
}
setting = settings.get(TAG_WORKING_SET);
if (setting != null)
workingSet = PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(setting);
}
}
public void saveState(IDialogSettings dialogSettings) {
if (dialogSettings != null) {
IDialogSettings settings = dialogSettings.getSection(TAG_DIALOG_SECTION);
if (settings == null)
settings = dialogSettings.addNewSection(TAG_DIALOG_SECTION);
settings.put(TAG_ENABLED, enabled);
settings.put(TAG_FILTER_ON_MARKER_LIMIT, filterOnMarkerLimit);
settings.put(TAG_MARKER_LIMIT, markerLimit);
settings.put(TAG_ON_RESOURCE, onResource);
String markerTypeIds = ""; //$NON-NLS-1$
for (int i = 0; i < selectedTypes.size(); i++) {
MarkerType markerType = (MarkerType) selectedTypes.get(i);
markerTypeIds += markerType.getId() + TAG_TYPES_DELIMITER;
}
settings.put(TAG_SELECTED_TYPES, markerTypeIds);
if (workingSet != null)
settings.put(TAG_WORKING_SET, workingSet.getName());
}
}
}