1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.configuration2.event;
18
19 import java.io.Serializable;
20 import java.util.HashSet;
21 import java.util.Set;
22
23 /**
24 * <p>
25 * A class representing an event type.
26 * </p>
27 * <p>
28 * The events produced by <em>Commons Configuration</em> all have a specific type. The event type can be used to
29 * determine the meaning of a specific event. It also acts as filter criterion when event listeners are registered. The
30 * listener is then called only for events of this type or derived types. The events in this library form a natural
31 * hierarchy with base types and more specialized types. By specifying an appropriate event type at listener
32 * registration time, it can be determined on a fine-granular basis which events are propagated to the listener.
33 * </p>
34 * <p>
35 * Note: Users familiar with JavaFX probably recognize this approach to event handling. It allows for generic event
36 * listener interfaces and a natural selection of events to be processed.
37 * </p>
38 *
39 * @since 2.0
40 * @param <T> the event associated with this type
41 */
42 public class EventType<T extends Event> implements Serializable {
43 /** Serial version UID. */
44 private static final long serialVersionUID = 20150416L;
45
46 /** Constant for the format used by toString(). */
47 private static final String FMT_TO_STRING = "%s [ %s ]";
48
49 /** Stores the super type of this type. */
50 private final EventType<? super T> superType;
51
52 /** A name for this event type. */
53 private final String name;
54
55 /**
56 * Creates a new instance of {@code EventType} and initializes it with the super type and a type name. If no super type
57 * is specified, this is the root event type.
58 *
59 * @param superEventType the super event type
60 * @param typeName the name of this event type
61 */
62 public EventType(final EventType<? super T> superEventType, final String typeName) {
63 superType = superEventType;
64 name = typeName;
65 }
66
67 /**
68 * Gets the super event type. Result is <b>null</b> for the root event type.
69 *
70 * @return the super event type
71 */
72 public EventType<? super T> getSuperType() {
73 return superType;
74 }
75
76 /**
77 * Gets the name of this event type. The name has no specific semantic meaning. It is just used for debugging
78 * purposes and also part of the string representation of this event type.
79 *
80 * @return the event type name
81 */
82 public String getName() {
83 return name;
84 }
85
86 /**
87 * Returns a string representation for this object. This method is mainly overridden for debugging purposes. The
88 * returned string contains the name of this event type.
89 *
90 * @return a string for this object
91 */
92 @Override
93 public String toString() {
94 return String.format(FMT_TO_STRING, getClass().getSimpleName(), getName());
95 }
96
97 /**
98 * Returns a set with all event types that are super types of the specified type. This set contains the direct and
99 * indirect super types and also includes the given type itself. The passed in type may be <b>null</b>, then an empty
100 * set is returned.
101 *
102 * @param eventType the event type in question
103 * @return a set with all super event types
104 */
105 public static Set<EventType<?>> fetchSuperEventTypes(final EventType<?> eventType) {
106 final Set<EventType<?>> types = new HashSet<>();
107 EventType<?> currentType = eventType;
108 while (currentType != null) {
109 types.add(currentType);
110 currentType = currentType.getSuperType();
111 }
112 return types;
113 }
114
115 /**
116 * Checks whether an event type is derived from another type. This implementation tests whether {@code baseType} is a
117 * direct or indirect super type of {@code derivedType}. If one of the types is <b>null</b>, result is <b>false</b>.
118 *
119 * @param derivedType the derived event type
120 * @param baseType the base event type
121 * @return <b>true</b> if the derived type is an instance of the base type, <b>false</b> otherwise
122 */
123 public static boolean isInstanceOf(final EventType<?> derivedType, final EventType<?> baseType) {
124 EventType<?> currentType = derivedType;
125 while (currentType != null) {
126 if (currentType == baseType) {
127 return true;
128 }
129 currentType = currentType.getSuperType();
130 }
131 return false;
132 }
133 }