/*
 * Copyright (c) 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 id.scanpath.support;

import java.lang.annotation.Annotation;
import java.util.logging.Level;
import java.util.logging.Logger;

import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.NotFoundException;

/**
 *
 * @author indroneel
 *
 */

public class MethodAnnotationVisitor extends ClassVisitor {

	private static final Logger LOGGER = Logger.getLogger(MethodAnnotationVisitor.class.getName());

	////////////////////////////////////////////////////////////////////////////
	// Methods of base class ClassVisitor

	@Override
	public void visit(String className) {
		try {
			CtClass cls = clsPool.get(className);
			visitImpl(cls);
		}
		catch (ClassNotFoundException | NotFoundException exep) {
			LOGGER.log(Level.WARNING, String.format("unable to visit class %s", className), exep);
		}
	}

	////////////////////////////////////////////////////////////////////////////
	// Helper methods

	private void visitImpl(CtClass cls)
								throws ClassNotFoundException, NotFoundException {
		CtMethod[] methods = cls.getMethods();
		for(CtMethod method : methods) {
			int mod = method.getModifiers();
			if(Modifier.isStatic(mod) || Modifier.isAbstract(mod)) {
				continue;
			}
			Object[] annotations = method.getAnnotations();
			if(annotations != null) {
				for(Object obj : annotations) {
					Annotation ann = (Annotation) obj;
					metaStore.addClassWithMethodAnnotation(ann.annotationType().getName(), cls.getName());
				}
			}
		}
	}
}
