<commit_before>/*
 * Copyright 2002-2007 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.springframework.core.typefilter;

import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.objectweb.asm.ClassReader;

/**
 * Type filter that is aware of traversing over hierarchy.
 * 
 * <p>This filter is useful when matching needs to be made based on potentially the
 * whole class/interface hierarchy. The algorithm employed uses succeed-fast
 * strategy i.e. if at anytime a match is declared, no further processing is
 * carried out.
 * 
 * @author <NAME>
 * @since 2.1
 */
public abstract class AbstractTypeHierarchyTraversingFilter implements TypeFilter {

	private final boolean considerInherited;

	private final boolean considerInterfaces;


	public AbstractTypeHierarchyTraversingFilter(boolean considerInherited, boolean considerInterfaces) {
		this.considerInherited = considerInherited;
		this.considerInterfaces = considerInterfaces;
	}

	public boolean match(ClassReader classReader) {
		// This method optimizes avoiding unnecessary creation of ClassReaders
		// as well as visting over those readers
		if (matchSelf(classReader)) {
			return true;
		}
		ClassNameAndTypesReadingVisitor typesReadingVisitor = new ClassNameAndTypesReadingVisitor();
		classReader.accept(typesReadingVisitor, true);

		if (matchClassName(typesReadingVisitor.getClassName())) {
			return true;
		}

		if (!this.considerInherited) {
			return false;
		}

		if (typesReadingVisitor.hasSuperClass()) {
			// Optimization to avoid creating ClassReader for super class
			if (matchSuperClassName(typesReadingVisitor.getSuperName())) {
				return true;
			}
			if (match(typesReadingVisitor.getSuperName())) {
				return true;
			}
		}

		if (!this.considerInterfaces) {
			return false;
		}

		for (String interfaze : typesReadingVisitor.getInterfaceNames()) {
			// Optimization to avoid creating ClassReader for super class
			if (matchInterfaceName(interfaze)) {
				return true;
			}
			if (match(interfaze)) {
				return true;
			}
		}
		return false;
	}

	private boolean match(String className) {
		try {
			return match(new ClassReader(className));
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Cannot load class with name '" + className + "'", ex);
		}
	}<commit_msg>Using Spring Resource to obtain InputStream instead of passing className to ClassReader.<commit_after>/*
 * Copyright 2002-2007 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.springframework.core.typefilter;

import java.io.IOException;
import java.io.InputStream;

import org.objectweb.asm.ClassReader;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.ClassUtils;

/**
 * Type filter that is aware of traversing over hierarchy.
 * 
 * <p>This filter is useful when matching needs to be made based on potentially the
 * whole class/interface hierarchy. The algorithm employed uses succeed-fast
 * strategy i.e. if at anytime a match is declared, no further processing is
 * carried out.
 * 
 * @author <NAME>
 * @author <NAME>
 * @since 2.1
 */
public abstract class AbstractTypeHierarchyTraversingFilter implements TypeFilter {

	private final boolean considerInherited;

	private final boolean considerInterfaces;


	public AbstractTypeHierarchyTraversingFilter(boolean considerInherited, boolean considerInterfaces) {
		this.considerInherited = considerInherited;
		this.considerInterfaces = considerInterfaces;
	}

	public boolean match(ClassReader classReader) {
		// This method optimizes avoiding unnecessary creation of ClassReaders
		// as well as visting over those readers
		if (matchSelf(classReader)) {
			return true;
		}
		ClassNameAndTypesReadingVisitor typesReadingVisitor = new ClassNameAndTypesReadingVisitor();
		classReader.accept(typesReadingVisitor, true);

		if (matchClassName(typesReadingVisitor.getClassName())) {
			return true;
		}

		if (!this.considerInherited) {
			return false;
		}

		if (typesReadingVisitor.hasSuperClass()) {
			// Optimization to avoid creating ClassReader for super class
			if (matchSuperClassName(typesReadingVisitor.getSuperName())) {
				return true;
			}
			if (match(typesReadingVisitor.getSuperName())) {
				return true;
			}
		}

		if (!this.considerInterfaces) {
			return false;
		}

		for (String interfaze : typesReadingVisitor.getInterfaceNames()) {
			// Optimization to avoid creating ClassReader for super class
			if (matchInterfaceName(interfaze)) {
				return true;
			}
			if (match(interfaze)) {
				return true;
			}
		}
		return false;
	}

	private boolean match(String className) {
		String resourcePath = ClassUtils.convertClassNameToResourcePath(className) + ".class";
		Resource resource = new ClassPathResource(resourcePath);
		InputStream stream = null;
		try {
			stream = resource.getInputStream();
			return match(new ClassReader(stream));
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Cannot load class with name '" + className + "'", ex);
		}
		finally {
			try {
				if (stream != null) {
					stream.close();
				}
			}
			catch (IOException ex) {
				// ignore, cleanup
			}
		}
	}
{'fraction_non_alphanumeric': 0.08359571788413098, 'fraction_numerical': 0.004408060453400504, 'mean_word_length': 4.139967637540453, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4049203', 'n_tokens_mistral': 1910, 'n_tokens_neox': 1676, 'n_words': 581}