/****************************************************************************** * Copyright (C) 2015 Yevgeny Krasik * * * * 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 com.github.ykrasik.jaci.reflection.param.factory; import com.github.ykrasik.jaci.param.ParamDef; import com.github.ykrasik.jaci.reflection.ReflectionParameter; import com.github.ykrasik.jaci.util.opt.Opt; import java.lang.annotation.Annotation; /** * A {@link MethodParamFactory} that can create {@link ParamDef}s out of {@link ReflectionParameter}s * that are of specific types (classes), and have a specific annotation. * * @author Yevgeny Krasik */ public abstract class AnnotationMethodParamFactory<T extends ParamDef<?>, A extends Annotation> extends AbstractMethodParamFactory<T> { private final Class<A> annotationClass; /** * @param annotationClass Type of annotation this factory supports. * @param acceptedParameterType First type of parameters this factory can accept. * @param moreAcceptedParameterTypes Additional types of parameter this factory can accept. */ protected AnnotationMethodParamFactory(Class<A> annotationClass, Class<?> acceptedParameterType, Class<?>... moreAcceptedParameterTypes) { super(acceptedParameterType, moreAcceptedParameterTypes); this.annotationClass = annotationClass; } @Override protected T doCreate(Object instance, ReflectionParameter param) throws Exception { final Opt<A> annotation = param.getAnnotation(annotationClass); final String defaultParamName = param.getDefaultName(); final Class<?> type = param.getParameterType(); if (annotation.isPresent()) { return createFromAnnotation(instance, defaultParamName, annotation.get(), type); } else { return createDefault(defaultParamName, type); } } /** * Create a {@link ParamDef} out of the annotation. * * @param instance Instance of a class which contains the method for which this parameter is being created. * @param defaultParamName Default-generated parameter name. * @param annotation Annotation the parameter is annotated with. * @param type Parameter type. * @return A {@link ParamDef} created out of the annotation. * @throws Exception If any error occurs. */ protected abstract T createFromAnnotation(Object instance, String defaultParamName, A annotation, Class<?> type) throws Exception; /** * Create a default {@link ParamDef} of the supported type. * * @param defaultParamName Default-generated parameter name. * @param type Parameter type. * @return A default {@link ParamDef}. * @throws Exception If any error occurs. */ protected abstract T createDefault(String defaultParamName, Class<?> type) throws Exception; }