1 /* 2 * Entreri, an entity-component framework in Java 3 * 4 * Copyright (c) 2013, Michael Ludwig 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without modification, 8 * are permitted provided that the following conditions are met: 9 * 10 * Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 23 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 package com.lhkbob.entreri.impl; 28 29 import com.lhkbob.entreri.Component; 30 31 import javax.annotation.processing.ProcessingEnvironment; 32 import javax.lang.model.element.TypeElement; 33 import java.util.List; 34 35 /** 36 * ComponentSpecification provides an interface to access the information encoded in a 37 * Component sub-interface in order to generate a proxy implementation. The specification 38 * can be extracted at runtime using reflection, or at compile time using the annotation 39 * processor mirror API. The two factory methods, {@link Factory#fromClass(Class)} and 40 * {@link Factory#fromTypeElement(javax.lang.model.element.TypeElement, 41 * javax.annotation.processing.ProcessingEnvironment)} correspond to these two scenarios. 42 * 43 * @author Michael Ludwig 44 */ 45 public interface ComponentSpecification { 46 /** 47 * Get the qualified name of the component type, with the package prefix removed. 48 * Thus, the returned string should be valid to insert into source code within the 49 * same package of the component and refer to that exact type. 50 * 51 * @return The component type 52 */ 53 public String getType(); 54 55 /** 56 * @return The package the component type resides in 57 */ 58 public String getPackage(); 59 60 /** 61 * Get all properties that must be implemented for this component type. This will 62 * include all properties defined in a parent component type if the type does not 63 * directly extend Component. 64 * <p/> 65 * The returned list will be immutable and sorted by logical property name. 66 * 67 * @return The list of all properties for the component 68 */ 69 public List<? extends PropertyDeclaration> getProperties(); 70 71 public static final class Factory { 72 private Factory() { 73 } 74 75 /** 76 * Produce a ComponentSpecification for the given Component class type. 77 * 78 * @param type The component type 79 * 80 * @return The extracted ComponentSpecification 81 * 82 * @throws com.lhkbob.entreri.IllegalComponentDefinitionException 83 * if the class does not follow the specification defined in Component, 84 * or if referenced Property classes do not meet their requirements 85 */ 86 public static ComponentSpecification fromClass(Class<? extends Component> type) { 87 return new ReflectionComponentSpecification(type); 88 } 89 90 /** 91 * Produce a ComponentSpecification for the given Component type element, within 92 * the context of the ProcessingEnvironment used by the active annotation 93 * processor. The returned specification maintains no dependencies to the 94 * processing environment but no guarantee is made on its validity after the 95 * processing round completes. 96 * 97 * @param type The component type 98 * @param env The ProcessingEnvironment for the current round 99 * 100 * @return The extracted ComponentSpecification 101 * 102 * @throws com.lhkbob.entreri.IllegalComponentDefinitionException 103 * if the class does not follow the specification defined in Component, 104 * or if referenced Property classes do not meet ther requirements 105 */ 106 public static ComponentSpecification fromTypeElement(TypeElement type, 107 ProcessingEnvironment env) { 108 return new MirrorComponentSpecification(type, env.getTypeUtils(), 109 env.getElementUtils(), 110 env.getFiler()); 111 } 112 } 113 }