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 }