/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.powermock.tests.utils.impl; import org.powermock.tests.utils.TestClassesExtractor; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Base class for all test class extractors. */ public abstract class AbstractTestClassExtractor implements TestClassesExtractor { protected final boolean includeMethods; protected AbstractTestClassExtractor(){ this(false); } protected AbstractTestClassExtractor(boolean includeMethods) {this.includeMethods = includeMethods;} /** * If <code>element</code> is a class this method traverses the hierarchy * and extracts classes that should be prepared for test in all super * classes. */ @Override public final String[] getTestClasses(AnnotatedElement element) { final Set<String> classesToPrepareForTest = new HashSet<String>(); if (element instanceof Class<?>) { extractClassesFromTestClass((Class<?>) element, classesToPrepareForTest); } else { extractClassesAndAddThemToList(element, classesToPrepareForTest); } return classesToPrepareForTest.toArray(new String[classesToPrepareForTest.size()]); } private void extractClassesFromTestClass(final Class<?> element, Set<String> classesToPrepareForTest) { Class<?> classToInvestigate = element; while (classToInvestigate != null && !classToInvestigate.equals(Object.class)) { extractClassesAndAddThemToList(classToInvestigate, classesToPrepareForTest); if (includeMethods) { classesToPrepareForTest.addAll(lookOverMethods(classToInvestigate)); } classToInvestigate = classToInvestigate.getSuperclass(); } } private Collection<String> lookOverMethods(Class<?> classToInvestigate) { Set<String> classesToPrepareForTest = new HashSet<String>(); for (Method method : classToInvestigate.getMethods()) { extractClassesAndAddThemToList(method, classesToPrepareForTest); } return classesToPrepareForTest; } private void extractClassesAndAddThemToList(AnnotatedElement elementToExtractClassFrom, final Set<String> classesToPrepareForTest) { final String[] classesToModify = getClassesToModify(elementToExtractClassFrom); if (classesToModify != null) { Collections.addAll(classesToPrepareForTest, classesToModify); } } /** * Get the fully qualified names for classes that must should be modified * for this <code>element</code>. * * @param element The element that may contain info regarding which classes that * must be modified by PowerMock. * @return An array of fully-qualified names to classes that must be * modified by PowerMock for the specific <code>element</code>. */ protected abstract String[] getClassesToModify(AnnotatedElement element); @Override public boolean isPrepared(AnnotatedElement element, String fullyQualifiedClassName) { if (fullyQualifiedClassName == null) { throw new IllegalArgumentException("fullyQualifiedClassName cannot be null."); } final String[] testClasses = getTestClasses(element); for (String className : testClasses) { if (className.equals(fullyQualifiedClassName)) { return true; } } return false; } }