001/* 002 * Copyright © 2018. Sir Wellington. 003 * Licensed under the Apache License, Version 2.0 (the "License"); 004 * you may not use this file except in compliance with the License. 005 * 006 * You may obtain a copy of the License at 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software 010 * distributed under the License is distributed on an "AS IS" BASIS, 011 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 * See the License for the specific language governing permissions and 013 * limitations under the License. 014 */ 015 016package tech.sirwellington.alchemy.test.junit.runners; 017 018 019import java.lang.annotation.Retention; 020import java.lang.annotation.Target; 021 022import tech.sirwellington.alchemy.annotations.access.Internal; 023import tech.sirwellington.alchemy.annotations.access.NonInstantiable; 024import tech.sirwellington.alchemy.generator.AlchemyGenerator; 025 026import static java.lang.annotation.ElementType.FIELD; 027import static java.lang.annotation.RetentionPolicy.RUNTIME; 028import static tech.sirwellington.alchemy.test.Checks.Internal.checkNotNull; 029 030/** 031 * Used in with the {@link AlchemyTestRunner}, this Annotations allows the 032 * Runtime Injection of Custom Objects using the {@link AlchemyGenerator} library. 033 * <p> 034 * Example: 035 * <pre> 036 * {@code 037 * `@RunWith(AlchemyTestRunner.class) 038 * public class ExampleTest 039 * { 040 * `@GenerateCustom(type=Book.class, generator=BookGenerator.class) 041 * private Book book; 042 * 043 * } 044 * } 045 * </pre> 046 * <p> 047 * Note, '`' (ticks) used to escape Javadocs. 048 * 049 * @author SirWellington 050 * @author SirWellington 051 */ 052@Target(FIELD) 053@Retention(RUNTIME) 054public @interface GenerateCustom 055{ 056 057 /** 058 * Specify the Java Class to use to generate values. This class must 059 * be an {@link AlchemyGenerator}. 060 */ 061 Class<? extends AlchemyGenerator<?>> value(); 062 063 @Internal 064 @NonInstantiable 065 static class Values 066 { 067 068 private Values() throws IllegalAccessException 069 { 070 throw new IllegalAccessException("cannot instantiate"); 071 } 072 073 static AlchemyGenerator<?> createGeneratorFor(GenerateCustom annotation) throws IllegalArgumentException 074 { 075 checkNotNull(annotation, "missing annotation"); 076 077 Class<? extends AlchemyGenerator<?>> generatorClass = annotation.value(); 078 079 final AlchemyGenerator<?> generator = tryToInstantiate(generatorClass); 080 081 return generator; 082 } 083 084 private static AlchemyGenerator<?> tryToInstantiate(Class<? extends AlchemyGenerator<?>> generatorClass) 085 { 086 try 087 { 088 return generatorClass.newInstance(); 089 } 090 catch (Throwable ex) 091 { 092 throw new IllegalArgumentException("Cannot instantiate Alchemy Generator | " + generatorClass, ex); 093 } 094 } 095 096 } 097}