blob: 60119c24bea813ac76276c83b3edaa79239d8cbc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 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.ui.internal.views.properties.tabbed.view;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jface.viewers.IFilter;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.views.properties.tabbed.ISectionDescriptor;
import org.eclipse.ui.views.properties.tabbed.ITypeMapper;
/**
* Provides a section filtering mechanism where the selection is an
* IStructuredSelection and filtering is based on class.
*
* @author Anthony Hunter
*/
public class TabbedPropertyRegistryClassSectionFilter {
private ITypeMapper typeMapper = null;
/**
* Constructor for TabbedPropertyRegistryClassSectionFilter
*
* @param typeMapper
* the type mapper.
*/
public TabbedPropertyRegistryClassSectionFilter(ITypeMapper typeMapper) {
super();
this.typeMapper = typeMapper;
}
/**
* Verifies if the property section extension represented by sectionElement
* applies to the given input.
*
* @param descriptor
* the section descriptor.
* @param selection
* the selection.
* @return <code>true</code> if this section applies to the current
* selection.
*/
public boolean appliesToSelection(ISectionDescriptor descriptor,
ISelection selection) {
if (selection instanceof IStructuredSelection &&
selection.isEmpty() == false) {
if (descriptor.getEnablesFor() != ISectionDescriptor.ENABLES_FOR_ANY &&
((IStructuredSelection) selection).size() != descriptor
.getEnablesFor()) {
/**
* enablesFor does not match the size of the selection, do not
* display section.
*/
return false;
}
IFilter filter = descriptor.getFilter();
if (filter != null) {
for (Iterator i = ((IStructuredSelection) selection).iterator(); i
.hasNext();) {
Object object = i.next();
if (filter != null && filter.select(object) == false) {
/**
* filter fails so section does not apply to the
* selection, do not display section.
*/
return false;
}
}
/**
* filter passes for all objects in the selection.
*/
return true;
}
Set effectiveTypes = new HashSet();
for (Iterator i = ((IStructuredSelection) selection).iterator(); i
.hasNext();) {
Object object = i.next();
Class remapType = object.getClass();
if (typeMapper != null) {
remapType = typeMapper.mapType(object);
}
if (effectiveTypes.add(remapType)) {
// the effective types of the selection
if (appliesToEffectiveType(descriptor, remapType) == false) {
return false;
}
}
}
} else {
/* Bug 245690 selection is not a IStructuredSelection */
if (descriptor.getFilter() != null) {
return descriptor.getFilter().select(selection);
}
}
return true;
}
private boolean appliesToEffectiveType(ISectionDescriptor descriptor,
Class inputClass) {
ArrayList classTypes = getClassTypes(inputClass);
List sectionInputTypes = descriptor.getInputTypes();
for (Iterator j = sectionInputTypes.iterator(); j.hasNext();) {
String type = (String) j.next();
if (classTypes.contains(type)) {
// found a match
return true;
}
}
return false;
}
/**
* Returns the classes and interfaces the given target class
* extends/implements.
*/
protected ArrayList getClassTypes(Class target) {
ArrayList result = new ArrayList();
// add classes
List classes = computeClassOrder(target);
for (Iterator i = classes.iterator(); i.hasNext();) {
result.add(((Class) i.next()).getName());
}
// add interfaces
result.addAll(computeInterfaceOrder(classes));
return result;
}
private List computeClassOrder(Class target) {
List result = new ArrayList(4);
Class clazz = target;
while (clazz != null) {
result.add(clazz);
clazz = clazz.getSuperclass();
}
return result;
}
private List computeInterfaceOrder(List classes) {
List result = new ArrayList(4);
Map seen = new HashMap(4);
for (Iterator iter = classes.iterator(); iter.hasNext();) {
Class[] interfaces = ((Class) iter.next()).getInterfaces();
internalComputeInterfaceOrder(interfaces, result, seen);
}
return result;
}
private void internalComputeInterfaceOrder(Class[] interfaces, List result,
Map seen) {
List newInterfaces = new ArrayList(seen.size());
for (int i = 0; i < interfaces.length; i++) {
Class interfac = interfaces[i];
if (seen.get(interfac) == null) {
result.add(interfac.getName());
seen.put(interfac, interfac);
newInterfaces.add(interfac);
}
}
for (Iterator iter = newInterfaces.iterator(); iter.hasNext();) {
internalComputeInterfaceOrder(
((Class) iter.next()).getInterfaces(), result, seen);
}
}
}