/**
 * Copyright 2010-2013 Ralph Schaer <ralphschaer@gmail.com>
 *
 * 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 ch.ralscha.extdirectspring.controller;

import java.lang.reflect.Method;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils.MethodFilter;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethodSelector;

import ch.ralscha.extdirectspring.annotation.ExtDirectMethod;
import ch.ralscha.extdirectspring.util.MethodInfoCache;

/**
 * Spring application listener that listens for ContextRefreshedEvent events. If
 * such an event is received the listener will scan for ExtDirectMethod
 * annotated methods in the current ApplicationContext. Found methods will be
 * cached in the {@link MethodInfoCache}. The class also reports warnings and
 * errors of misconfigured methods.
 */
@Service
public class MethodRegistrar implements ApplicationListener<ContextRefreshedEvent> {

	private static final Log log = LogFactory.getLog(RouterController.class);

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {

		ApplicationContext context = (ApplicationContext) event.getSource();

		String[] beanNames = context.getBeanNamesForType(Object.class);

		for (String beanName : beanNames) {

			Class<?> handlerType = context.getType(beanName);
			final Class<?> userType = ClassUtils.getUserClass(handlerType);

			Set<Method> methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() {
				@Override
				public boolean matches(Method method) {
					return AnnotationUtils.findAnnotation(method, ExtDirectMethod.class) != null;
				}
			});

			for (Method method : methods) {
				ExtDirectMethod directMethodAnnotation = AnnotationUtils.findAnnotation(method, ExtDirectMethod.class);
				final String beanMethodName = beanName + "." + method.getName();
				if (directMethodAnnotation.value().isValid(beanMethodName, userType, method)) {
					MethodInfoCache.INSTANCE.put(beanName, handlerType, method, event.getApplicationContext());

					// /CLOVER:OFF
					if (log.isDebugEnabled()) {
						String info = "Register " + beanMethodName + "(" + directMethodAnnotation.value();
						if (StringUtils.hasText(directMethodAnnotation.group())) {
							info += ", " + directMethodAnnotation.group();
						}
						info += ")";
						log.debug(info);
					}
					// /CLOVER:ON
				}
			}

		}
	}

}

@@ -981,16 +981,57 @@
 dEvent;%0A
+import org.springframework.core.Ordered;%0A
 import o
@@ -1905,16 +1905,25 @@
 edEvent%3E
+, Ordered
  %7B%0A%0A%09pri
@@ -3366,10 +3366,86 @@
 %09%09%7D%0A%09%7D%0A%0A
+%09@Override%0A%09public int getOrder() %7B%0A%09%09return Ordered.LOWEST_PRECEDENCE;%0A%09%7D%0A%0A
 %7D%0A

Implement Ordered interface and return LOWEST_PRECEDENCE. This way MethodRegistrar should be called last