001: /*******************************************************************************
002: * Copyright (c) 2001, 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.views.properties.tabbed.view;
011:
012: import java.util.ArrayList;
013: import java.util.HashMap;
014: import java.util.HashSet;
015: import java.util.Iterator;
016: import java.util.List;
017: import java.util.Map;
018: import java.util.Set;
019:
020: import org.eclipse.jface.viewers.IFilter;
021: import org.eclipse.jface.viewers.ISelection;
022: import org.eclipse.jface.viewers.IStructuredSelection;
023: import org.eclipse.ui.views.properties.tabbed.ISectionDescriptor;
024: import org.eclipse.ui.views.properties.tabbed.ITypeMapper;
025:
026: /**
027: * Provides a section filtering mechanism where the selection is an
028: * IStructuredSelection and filtering is based on class.
029: *
030: * @author Anthony Hunter
031: */
032: public class TabbedPropertyRegistryClassSectionFilter {
033:
034: private ITypeMapper typeMapper = null;
035:
036: /**
037: * Constructor for TabbedPropertyRegistryClassSectionFilter
038: *
039: * @param typeMapper
040: * the type mapper.
041: */
042: public TabbedPropertyRegistryClassSectionFilter(
043: ITypeMapper typeMapper) {
044: super ();
045: this .typeMapper = typeMapper;
046: }
047:
048: /**
049: * Verifies if the property section extension represented by sectionElement
050: * applies to the given input.
051: * @param descriptor the section descriptor.
052: * @param selection the selection.
053: * @return <code>true</code> if this section applies to the current
054: * selection.
055: */
056: public boolean appliesToSelection(ISectionDescriptor descriptor,
057: ISelection selection) {
058:
059: if (selection instanceof IStructuredSelection
060: && selection.isEmpty() == false) {
061:
062: if (descriptor.getEnablesFor() != ISectionDescriptor.ENABLES_FOR_ANY
063: && ((IStructuredSelection) selection).size() != descriptor
064: .getEnablesFor()) {
065: /**
066: * enablesFor does not match the size of the selection, do not
067: * display section.
068: */
069: return false;
070: }
071:
072: IFilter filter = descriptor.getFilter();
073:
074: if (filter != null) {
075: for (Iterator i = ((IStructuredSelection) selection)
076: .iterator(); i.hasNext();) {
077: Object object = i.next();
078:
079: if (filter != null
080: && filter.select(object) == false) {
081: /**
082: * filter fails so section does not apply to the
083: * selection, do not display section.
084: */
085: return false;
086: }
087: }
088: /**
089: * filter passes for all objects in the selection.
090: */
091: return true;
092: }
093:
094: Set effectiveTypes = new HashSet();
095:
096: for (Iterator i = ((IStructuredSelection) selection)
097: .iterator(); i.hasNext();) {
098:
099: Object object = i.next();
100:
101: Class remapType = object.getClass();
102: if (typeMapper != null) {
103: remapType = typeMapper.mapType(object);
104: }
105:
106: if (effectiveTypes.add(remapType)) {
107:
108: // the effective types of the selection
109: if (appliesToEffectiveType(descriptor, remapType) == false) {
110: return false;
111: }
112: }
113: }
114: }
115:
116: return true;
117: }
118:
119: private boolean appliesToEffectiveType(
120: ISectionDescriptor descriptor, Class inputClass) {
121:
122: ArrayList classTypes = getClassTypes(inputClass);
123:
124: List sectionInputTypes = descriptor.getInputTypes();
125: for (Iterator j = sectionInputTypes.iterator(); j.hasNext();) {
126: String type = (String) j.next();
127: if (classTypes.contains(type)) {
128: // found a match
129: return true;
130: }
131: }
132:
133: return false;
134: }
135:
136: /**
137: * Returns the classes and interfaces the given target class
138: * extends/implements.
139: */
140: protected ArrayList getClassTypes(Class target) {
141: ArrayList result = new ArrayList();
142: // add classes
143: List classes = computeClassOrder(target);
144: for (Iterator i = classes.iterator(); i.hasNext();) {
145: result.add(((Class) i.next()).getName());
146: }
147: // add interfaces
148: result.addAll(computeInterfaceOrder(classes));
149: return result;
150: }
151:
152: private List computeClassOrder(Class target) {
153: List result = new ArrayList(4);
154: Class clazz = target;
155: while (clazz != null) {
156: result.add(clazz);
157: clazz = clazz.getSuperclass();
158: }
159: return result;
160: }
161:
162: private List computeInterfaceOrder(List classes) {
163: List result = new ArrayList(4);
164: Map seen = new HashMap(4);
165: for (Iterator iter = classes.iterator(); iter.hasNext();) {
166: Class[] interfaces = ((Class) iter.next()).getInterfaces();
167: internalComputeInterfaceOrder(interfaces, result, seen);
168: }
169: return result;
170: }
171:
172: private void internalComputeInterfaceOrder(Class[] interfaces,
173: List result, Map seen) {
174: List newInterfaces = new ArrayList(seen.size());
175: for (int i = 0; i < interfaces.length; i++) {
176: Class interfac = interfaces[i];
177: if (seen.get(interfac) == null) {
178: result.add(interfac.getName());
179: seen.put(interfac, interfac);
180: newInterfaces.add(interfac);
181: }
182: }
183: for (Iterator iter = newInterfaces.iterator(); iter.hasNext();) {
184: internalComputeInterfaceOrder(((Class) iter.next())
185: .getInterfaces(), result, seen);
186: }
187: }
188: }
|