| /******************************************************************************* |
| * Copyright (c) 2001, 2006 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. |
| */ |
| protected TabbedPropertyRegistryClassSectionFilter(ITypeMapper typeMapper) { |
| super(); |
| this.typeMapper = typeMapper; |
| } |
| |
| /** |
| * Verifies if the property section extension represented by sectionElement |
| * applies to the given input. |
| */ |
| protected 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; |
| } |
| } |
| } |
| } |
| |
| 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); |
| } |
| } |
| } |