1package org.apache.archiva.event;
23/*4 * Licensed to the Apache Software Foundation (ASF) under one5 * or more contributor license agreements. See the NOTICE file6 * distributed with this work for additional information7 * regarding copyright ownership. The ASF licenses this file8 * to you under the Apache License, Version 2.0 (the9 * "License"); you may not use this file except in compliance10 * with the License. You may obtain a copy of the License at11 *12 * http://www.apache.org/licenses/LICENSE-2.013 *14 * Unless required by applicable law or agreed to in writing,15 * software distributed under the License is distributed on an16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY17 * KIND, either express or implied. See the License for the18 * specific language governing permissions and limitations19 * under the License.20 */2122import java.io.InvalidObjectException;
23import java.io.ObjectStreamException;
24import java.io.Serializable;
25import java.util.*;
2627/**28 * Event types define a hierarchical structure of events. Each event is bound to a certain event type.29 * All event types have a super type, only the root event type {@link EventType#ROOT} has no super type.30 *31 * Event types should be stored as static fields on the events itself.32 *33 * @param <T> The type class parameter allows to define the types in a type safe way and represents a event class,34 * where the type is associated to.35 */36publicclass EventType<T extends Event> implements Serializable {
373839publicstaticfinal EventType<Event> ROOT = new EventType<>();
4041privatefinal String name;
42privatefinal EventType<? super T> superType;
43private WeakHashMap<EventType<? extends T>, Void> subTypes;
4445/**46 * Creates a type with the given name and the root type as parent.47 * @param name the name of the new type48 */49publicEventType(String name) {
50this.superType = ROOT;
51this.name = name;
52 }
5354/**55 * Creates a event type instance with the given super type and name.56 *57 * @param superType The super type or <code>null</code>, if this is the root type.58 * @param name59 */60publicEventType(EventType<? super T> superType, String name) {
61if (superType==null) {
62thrownew NullPointerException("Super Type may not be null");
63 }
64this.name = name;
65this.superType = superType;
66 superType.register(this);
67 }
6869/**70 * Creates the root type71 */72privateEventType() {
73this.name="ROOT";
74this.superType=null;
75 }
7677public String name() {
78return name;
79 }
8081public EventType<? super T> getSuperType() {
82return superType;
83 }
8485privatevoid register(EventType<? extends T> subType) {
86if (subTypes == null) {
87 subTypes = new WeakHashMap<>();
88 }
89for (EventType<? extends T> t : subTypes.keySet()) {
90if (((t.name == null && subType.name == null) || (t.name != null && t.name.equals(subType.name)))) {
91thrownew IllegalArgumentException("EventType \"" + subType + "\""92 + "with parent \"" + subType.getSuperType()+"\" already exists");
93 }
94 }
95 subTypes.put(subType, null);
96 }
979899publicstatic List<EventType<?>> fetchSuperTypes(EventType<?> type) {
100 List<EventType<?>> typeList = new ArrayList<>();
101 EventType<?> cType = type;
102while (cType!=null) {
103 typeList.add(cType);
104 cType = cType.getSuperType();
105 }
106return typeList;
107 }
108109publicstaticboolean isInstanceOf(EventType<?> type, EventType<?> baseType) {
110 EventType<?> cType = type;
111while(cType!=null) {
112if (cType == baseType) {
113returntrue;
114 }
115 cType = cType.getSuperType();
116 }
117return false;
118 }
119120121private Object writeReplace() throws ObjectStreamException {
122 Deque<String> path = new LinkedList<String>();
123 EventType<?> t = this;
124while (t != ROOT) {
125 path.addFirst(t.name);
126 t = t.superType;
127 }
128returnnew EventTypeSerialization(new ArrayList<>(path));
129 }
130131staticclass EventTypeSerialization implements Serializable {
132privatestaticfinallong serialVersionUID = 1841649460281865547L;
133private List<String> path;
134135public EventTypeSerialization(List<String> path) {
136this.path = path;
137 }
138139private Object readResolve() throws ObjectStreamException {
140EventType t = ROOT;
141for (int i = 0; i < path.size(); ++i) {
142 String p = path.get(i);
143if (t.subTypes != null) {
144 EventType<?> s = findSubType(t.subTypes.keySet(), p);
145if (s == null) {
146thrownew InvalidObjectException("Cannot find event type \"" + p + "\" (of " + t + ")");
147 }
148 t = s;
149 } else {
150thrownew InvalidObjectException("Cannot find event type \"" + p + "\" (of " + t + ")");
151 }
152 }
153return t;
154 }
155156private EventType<?> findSubType(Set<EventType> subTypes, String name) {
157for (EventType t : subTypes) {
158if (((t.name == null && name == null) || (t.name != null && t.name.equals(name)))) {
159return t;
160 }
161 }
162returnnull;
163 }
164165 }
166 }