org.springframework.data.gemfire.function.config.AnnotationFunctionExecutionConfigurationSource Maven / Gradle / Ivy
/*
* Copyright 2002-2013 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.data.gemfire.function.config;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* Annotation based configuration source for function executions
*
* @author David Turanski
*
*/
class AnnotationFunctionExecutionConfigurationSource extends AbstractFunctionExecutionConfigurationSource {
private static final String BASE_PACKAGES = "basePackages";
private static final String BASE_PACKAGE_CLASSES = "basePackageClasses";
private final AnnotationMetadata metadata;
private final AnnotationAttributes attributes;
/**
* Creates a new {@link AnnotationFunctionExecutionConfigurationSource} from the given {@link AnnotationMetadata} and
* annotation.
*
* @param metadata must not be {@literal null}.
*/
AnnotationFunctionExecutionConfigurationSource(AnnotationMetadata metadata) {
Assert.notNull(metadata);
this.attributes = new AnnotationAttributes(metadata.getAnnotationAttributes(EnableGemfireFunctionExecutions.class.getName()));
this.metadata = metadata;
}
/* (non-Javadoc)
* @see org.springframework.data.gemfire.function.config.FunctionExecutionConfigurationSource#getSource()
*/
@Override
public Object getSource() {
// TODO Auto-generated method stub
return this.metadata;
}
/* (non-Javadoc)
* @see org.springframework.data.gemfire.function.config.FunctionExecutionConfigurationSource#getBasePackages()
*/
@Override
public Iterable getBasePackages() {
String[] value = attributes.getStringArray("value");
String[] basePackages = attributes.getStringArray(BASE_PACKAGES);
Class[] basePackageClasses = attributes.getClassArray(BASE_PACKAGE_CLASSES);
// Default configuration - return package of annotated class
if (value.length == 0 && basePackages.length == 0 && basePackageClasses.length == 0) {
String className = metadata.getClassName();
return Collections.singleton(className.substring(0, className.lastIndexOf('.')));
}
Set packages = new HashSet();
packages.addAll(Arrays.asList(value));
packages.addAll(Arrays.asList(basePackages));
for (Class typeName : basePackageClasses) {
packages.add(ClassUtils.getPackageName(typeName));
}
return packages;
}
@Override
public Iterable getIncludeFilters() {
return parseFilters("includeFilters");
}
@Override
public Iterable getExcludeFilters() {
return parseFilters("excludeFilters");
}
private Set parseFilters(String attributeName) {
Set result = new HashSet();
AnnotationAttributes[] filters = attributes.getAnnotationArray(attributeName);
for (AnnotationAttributes filter : filters) {
result.addAll(typeFiltersFor(filter));
}
return result;
}
/**
* Copy of {@code ComponentScanAnnotationParser#typeFiltersFor}.
*
* @param filterAttributes
* @return
*/
private List typeFiltersFor(AnnotationAttributes filterAttributes) {
List typeFilters = new ArrayList();
FilterType filterType = filterAttributes.getEnum("type");
for (Class filterClass : filterAttributes.getClassArray("value")) {
switch (filterType) {
case ANNOTATION:
Assert.isAssignable(Annotation.class, filterClass, "An error occured when processing a @ComponentScan "
+ "ANNOTATION type filter: ");
@SuppressWarnings("unchecked")
Class annoClass = (Class) filterClass;
typeFilters.add(new AnnotationTypeFilter(annoClass));
break;
case ASSIGNABLE_TYPE:
typeFilters.add(new AssignableTypeFilter(filterClass));
break;
case CUSTOM:
Assert.isAssignable(TypeFilter.class, filterClass, "An error occured when processing a @ComponentScan "
+ "CUSTOM type filter: ");
typeFilters.add(BeanUtils.instantiateClass(filterClass, TypeFilter.class));
break;
default:
throw new IllegalArgumentException("unknown filter type " + filterType);
}
}
return typeFilters;
}
}