/* * Copyright 2016 Kejun Xia * * 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.shipdream.lib.poke; import com.shipdream.lib.poke.exception.ProvideException; import com.shipdream.lib.poke.util.ReflectUtils; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import javax.inject.Qualifier; /** * This provider uses default/empty constructor by provided class type to get dependencies. So * make sure the implementation has default public constructor */ public class ProviderByClassType<T> extends Provider<T> { private final Class<? extends T> clazz; private final String implClassName; /** * Construct a provider binding the type and the implementation class type. The found * implementation class may be annotated by {@link Qualifier} * @param type The contract of the implementation * @param implementationClass The class type of the implementation. It must have a default * public constructor */ public ProviderByClassType(Class<T> type, Class<? extends T> implementationClass) { super(type, ReflectUtils.findFirstQualifierInAnnotations(implementationClass)); this.implClassName = implementationClass.getName(); this.clazz = implementationClass; } @Override public T createInstance() throws ProvideException { try { Constructor constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); return (T)constructor.newInstance(); } catch (InstantiationException e) { throwProvideException(e); } catch (IllegalAccessException e) { throwProvideException(e); } catch (NoSuchMethodException e) { throwProvideException(e); } catch (InvocationTargetException e) { throwProvideException(e); } throw new ProvideException(String.format("Failed to provide class - %s as newInstance " + "of it returns null", type())); } private void throwProvideException(Exception e) throws ProvideException { throw new ProvideException(String.format("Failed to provide class - %s. Make sure %s exist " + "and with a default empty constructor.", clazz.getName(), implClassName), e); } }