| /** |
| * This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
| * You can obtain one at http://mozilla.org/MPL/2.0/. |
| */ |
| package org.mifosplatform.infrastructure.jobs.annotation; |
| |
| import java.io.IOException; |
| import java.lang.annotation.Annotation; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.mifosplatform.infrastructure.jobs.service.JobName; |
| import org.springframework.core.env.StandardEnvironment; |
| import org.springframework.core.io.Resource; |
| import org.springframework.core.io.support.PathMatchingResourcePatternResolver; |
| import org.springframework.core.io.support.ResourcePatternResolver; |
| import org.springframework.core.type.MethodMetadata; |
| import org.springframework.core.type.classreading.CachingMetadataReaderFactory; |
| import org.springframework.core.type.classreading.MetadataReader; |
| import org.springframework.core.type.classreading.MetadataReaderFactory; |
| import org.springframework.util.ClassUtils; |
| |
| /** |
| * Parser to find method which is marked with CronTargetMethod annotation |
| */ |
| public class CronMethodParser { |
| |
| public static class ClassMethodNamesPair { |
| |
| public String className; |
| public String methodName; |
| } |
| |
| private static final String SEARCH_PACKAGE = "org.mifosplatform."; |
| |
| private static final String CRON_ANNOTATION_ATTRIBUTE_NAME = "jobName"; |
| |
| private static final String RESOURCE_PATTERN = "**/*.class"; |
| |
| private static final Map<String, ClassMethodNamesPair> targetMethosMap = new HashMap<>(); |
| |
| private static final ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); |
| |
| private static final MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver); |
| |
| public static ClassMethodNamesPair findTargetMethodDetails(final String attributeValue) throws IOException { |
| if (!targetMethosMap.containsKey(attributeValue)) { |
| findAnnotationMethods(CronTarget.class, CRON_ANNOTATION_ATTRIBUTE_NAME); |
| } |
| return targetMethosMap.get(attributeValue); |
| } |
| |
| /** |
| * method adds all the method names to map with annotation attribute value |
| * as key |
| */ |
| private static void findAnnotationMethods(final Class<? extends Annotation> annotationClass, final String attributeName) |
| throws IOException { |
| final String basePackagePath = ClassUtils.convertClassNameToResourcePath(new StandardEnvironment() |
| .resolveRequiredPlaceholders(SEARCH_PACKAGE)); |
| String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + basePackagePath + "/" + RESOURCE_PATTERN; |
| packageSearchPath = packageSearchPath.replace("//", "/"); // else it doesn't work if *.class are in WAR!! |
| final Resource[] resources = resourcePatternResolver.getResources(packageSearchPath); |
| for (final Resource resource : resources) { |
| if (resource.isReadable()) { |
| final MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource); |
| final Set<MethodMetadata> metadataSet = metadataReader.getAnnotationMetadata().getAnnotatedMethods( |
| annotationClass.getName()); |
| if (metadataSet != null && metadataSet.size() > 0) { |
| for (final MethodMetadata metadata : metadataSet) { |
| final Map<String, Object> attributes = metadata.getAnnotationAttributes(annotationClass.getName()); |
| final JobName attributeValue = (JobName) attributes.get(attributeName); |
| final String className = metadata.getDeclaringClassName(); |
| final ClassMethodNamesPair pair = new ClassMethodNamesPair(); |
| pair.className = className; |
| pair.methodName = metadata.getMethodName(); |
| targetMethosMap.put(attributeValue.toString(), pair); |
| } |
| } |
| } |
| } |
| } |
| } |