/****************************************************************************** * 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.reflection.ReflectionUtils; import com.github.ykrasik.jaci.util.opt.Opt; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * A {@link MethodParamFactory} that can create {@link ParamDef}s out of {@link ReflectionParameter}s * that are of a specific type (class). * * @author Yevgeny Krasik */ public abstract class AbstractMethodParamFactory<T extends ParamDef<?>> implements MethodParamFactory<T> { private final List<Class<?>> acceptedParameterTypes; /** * @param acceptedParameterType First type of parameters this factory can accept. * @param moreAcceptedParameterTypes Additional types of parameter this factory can accept. */ protected AbstractMethodParamFactory(Class<?> acceptedParameterType, Class<?>... moreAcceptedParameterTypes) { this.acceptedParameterTypes = new ArrayList<>(moreAcceptedParameterTypes.length + 1); this.acceptedParameterTypes.add(acceptedParameterType); this.acceptedParameterTypes.addAll(Arrays.asList(moreAcceptedParameterTypes)); } @Override public Opt<T> create(Object instance, ReflectionParameter param) throws Exception { final Class<?> parameterType = param.getParameterType(); if (!isClassAccepted(parameterType)) { // This factory doesn't accept parameter this type. return Opt.absent(); } return Opt.of(doCreate(instance, param)); } private boolean isClassAccepted(Class<?> type) { for (Class<?> parameterType : acceptedParameterTypes) { if (ReflectionUtils.isAssignableFrom(parameterType, type)) { return true; } } return false; } /** * Create a {@link ParamDef} out of the {@link ReflectionParameter}, which is guaranteed to be of the accepted type. * * @param instance Instance of a class which contains the method for which this parameter is being created. * @param param Parameter to be processed. Guaranteed to be of the accepted type. * @return A {@link ParamDef} created out of this {@link ReflectionParameter}. * @throws Exception If any error occurs. */ protected abstract T doCreate(Object instance, ReflectionParameter param) throws Exception; }