]> source.dussan.org Git - archiva.git/blob
ab9678ab2e66b32d9d1f8f42356c80fbc81cd4d6
[archiva.git] /
1 package org.apache.archiva.repository.events;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import java.io.InvalidObjectException;
23 import java.io.ObjectStreamException;
24 import java.io.Serializable;
25 import java.util.*;
26
27 /**
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  */
36 public class EventType<T extends Event> implements Serializable  {
37
38
39     public static final EventType<Event> ROOT = new EventType<>();
40
41     private final String name;
42     private final EventType<? super T> superType;
43     private WeakHashMap<EventType<? extends T>, Void> subTypes;
44
45     /**
46      * Creates a type with the given name and the root type as parent.
47      * @param name the name of the new type
48      */
49     public EventType(String name) {
50         this.superType = ROOT;
51         this.name = name;
52     }
53
54     /**
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 name
59      */
60     public EventType(EventType<? super T> superType, String name) {
61         if (superType==null) {
62             throw new NullPointerException("Super Type may not be null");
63         }
64         this.name = name;
65         this.superType = superType;
66         superType.register(this);
67     }
68
69     /**
70      * Creates the root type
71      */
72     private EventType() {
73         this.name="ROOT";
74         this.superType=null;
75     }
76
77     public String name() {
78         return name;
79     }
80
81     public EventType<? super T> getSuperType() {
82         return superType;
83     }
84
85     private void register(EventType<? extends T> subType) {
86         if (subTypes == null) {
87             subTypes = new WeakHashMap<>();
88         }
89         for (EventType<? extends T> t : subTypes.keySet()) {
90             if (((t.name == null && subType.name == null) || (t.name != null && t.name.equals(subType.name)))) {
91                 throw new IllegalArgumentException("EventType \"" + subType + "\""
92                         + "with parent \"" + subType.getSuperType()+"\" already exists");
93             }
94         }
95         subTypes.put(subType, null);
96     }
97
98
99     public static List<EventType<?>> fetchSuperTypes(EventType<?> type) {
100         List<EventType<?>> typeList = new ArrayList<>();
101         EventType<?> cType = type;
102         while (cType!=null) {
103             typeList.add(cType);
104             cType = cType.getSuperType();
105         }
106         return typeList;
107     }
108
109     public static boolean isInstanceOf(EventType<?> type, EventType<?> baseType) {
110         EventType<?> cType = type;
111         while(cType!=null) {
112             if (cType == baseType) {
113                 return true;
114             }
115             cType = cType.getSuperType();
116         }
117         return false;
118     }
119
120
121     private Object writeReplace() throws ObjectStreamException {
122         Deque<String> path = new LinkedList<String>();
123         EventType<?> t = this;
124         while (t != ROOT) {
125             path.addFirst(t.name);
126             t = t.superType;
127         }
128         return new EventTypeSerialization(new ArrayList<>(path));
129     }
130
131     static class EventTypeSerialization implements Serializable {
132         private static final long serialVersionUID = 1841649460281865547L;
133         private List<String> path;
134
135         public EventTypeSerialization(List<String> path) {
136             this.path = path;
137         }
138
139         private Object readResolve() throws ObjectStreamException {
140             EventType t = ROOT;
141             for (int i = 0; i < path.size(); ++i) {
142                 String p = path.get(i);
143                 if (t.subTypes != null) {
144                     EventType<?> s = findSubType(t.subTypes.keySet(), p);
145                     if (s == null) {
146                         throw new InvalidObjectException("Cannot find event type \"" + p + "\" (of " + t + ")");
147                     }
148                     t = s;
149                 } else {
150                     throw new InvalidObjectException("Cannot find event type \"" + p + "\" (of " + t + ")");
151                 }
152             }
153             return t;
154         }
155
156         private EventType<?> findSubType(Set<EventType> subTypes, String name) {
157             for (EventType t : subTypes) {
158                 if (((t.name == null && name == null) || (t.name != null && t.name.equals(name)))) {
159                     return t;
160                 }
161             }
162             return null;
163         }
164
165     }
166 }