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.property; 28 29 import java.lang.annotation.Annotation; 30 import java.util.Collection; 31 import java.util.HashMap; 32 import java.util.Map; 33 34 /** 35 * Attributes represents the collection of attributes that have been provided on a 36 * property declaration within a ComponentData definition. To use attributes, {@link 37 * PropertyFactory} implementations should have a constructor that takes a single 38 * Attributes instance. 39 * 40 * @author Michael Ludwig 41 * @see PropertyFactory 42 */ 43 public class Attributes { 44 private final Map<Class<? extends Annotation>, Annotation> attrs; 45 46 /** 47 * Construct a new set of attributes from the given annotations. Only annotations that 48 * have the Attribute annotation are kept. 49 * 50 * @param attrs The annotations from the method, or field, etc. 51 * 52 * @throws NullPointerException if attrs is null or contains null elements 53 */ 54 public Attributes(Annotation... attrs) { 55 if (attrs == null) { 56 throw new NullPointerException("Attributes cannot be null"); 57 } 58 this.attrs = new HashMap<>(); 59 60 for (Annotation a : attrs) { 61 if (a.annotationType().getAnnotation(Attribute.class) != null) { 62 // the attribute is an annotation 63 this.attrs.put(a.annotationType(), a); 64 } 65 } 66 } 67 68 /** 69 * Get the attribute annotation of type T. If there is no attribute for the given 70 * type, then null is returned. 71 * 72 * @param cls The attribute annotation class type 73 * 74 * @return The associated attribute instance 75 */ 76 @SuppressWarnings("unchecked") 77 public <T extends Annotation> T getAttribute(Class<T> cls) { 78 if (cls == null) { 79 throw new NullPointerException("Annotation class cannot be null"); 80 } 81 return (T) attrs.get(cls); 82 } 83 84 /** 85 * Get whether or not this set of attributes has an attribute of the given type. If an 86 * attribute does not have any variables, this is sufficient instead of getting the 87 * actual instance. 88 * 89 * @param cls The annotation class type 90 * 91 * @return True if the associated attribute exists 92 */ 93 public boolean hasAttribute(Class<? extends Annotation> cls) { 94 if (cls == null) { 95 throw new NullPointerException("Annotation class cannot be null"); 96 } 97 return attrs.containsKey(cls); 98 } 99 100 /** 101 * @return All annotation attributes in this set 102 */ 103 public Collection<Annotation> getAttributes() { 104 return attrs.values(); 105 } 106 }