/** * Copyright (C) 2006-2017 INRIA and contributors * Spoon - http://spoon.gforge.inria.fr/ * * This software is governed by the CeCILL-C License under French law and * abiding by the rules of distribution of free software. You can use, modify * and/or redistribute the software under the terms of the CeCILL-C license as * circulated by CEA, CNRS and INRIA at http://www.cecill.info. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ package spoon.reflect.visitor.filter; import spoon.reflect.declaration.CtElement; import spoon.reflect.visitor.Filter; /** * This class defines a composite filter, which can compose several filters * together by using {@link spoon.reflect.visitor.filter.FilteringOperator}. * * @author Renaud Pawlak */ public class CompositeFilter<T extends CtElement> implements Filter<T> { /** * Defines the matching using * {@link spoon.reflect.visitor.filter.FilteringOperator}. */ public boolean matches(T element) { switch (operator) { case INTERSECTION: for (Filter<T> f : filters) { if (!hasMatch(f, element)) { return false; } } return true; case UNION: for (Filter<T> f : filters) { if (hasMatch(f, element)) { return true; } } return false; case SUBSTRACTION: if (filters.length == 0) { return false; } if (!filters[0].matches(element)) { return false; } for (int i = 1; i < filters.length; i++) { if (filters[i].matches(element)) { return false; } } return true; default: return false; } } Filter<T>[] filters; FilteringOperator operator; /** * Creates a new composite filter. * * @param operator * the operator used to compose the filters together * @param filters * the filters to be composed */ public CompositeFilter(FilteringOperator operator, Filter<T>... filters) { this.filters = filters; this.operator = operator; } private boolean hasMatch(Filter<T> filter, T element) { try { return filter.matches(element); } catch (ClassCastException e) { return false; } } @SuppressWarnings("unchecked") public Class<T> getType() { return (Class<T>) CtElement.class; } }