/******************************************************************************* * Copyright (c) 2011 SAP AG 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: * SAP AG - initial API and implementation ******************************************************************************/ package com.sap.furcas.ide.editor.dialogs; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; /** * Provider that only yields the children which either match the filer or which * have (transitive) children matching the filter. * * @author Stephan Erb * */ public class FilteredContentProvider extends AdapterFactoryContentProvider { private final HashMap<Object, Boolean> childStateCache = new HashMap<Object, Boolean>(); private final Collection<Class<?>> filterList; public FilteredContentProvider(AdapterFactory adapterFactory, Collection<Class<?>> filterList) { super(adapterFactory); this.filterList = filterList; } @Override public Object[] getChildren(Object object) { Object[] unfilteredResult = super.getChildren(object); ArrayList<Object> filteredResult = new ArrayList<Object>(); for (Object childObj : unfilteredResult) { if (childObj == null) { continue; } if (isOfDesiredType(childObj) || hasChildOfDesiredTypeRecursive(childObj)) { filteredResult.add(childObj); } } return filteredResult.toArray(new Object[filteredResult.size()]); } private boolean isOfDesiredType(Object obj) { for (Class<?> c : filterList) { if (c.isAssignableFrom(obj.getClass())) { return true; } } return false; } private boolean hasChildOfDesiredTypeRecursive(Object childObj) { // Cache prevents that a hierarchy is walked downwards over // and over again. The cache is populated when the root element // is inspected. if (childStateCache.containsKey(childObj)) { return childStateCache.get(childObj); } boolean childHasChildrenOfDesiredType = getChildren(childObj).length > 0; childStateCache.put(childObj, childHasChildrenOfDesiredType); return childHasChildrenOfDesiredType; } }