This project has retired. For details please refer to its Attic page.
EventType xref
View Javadoc
1   package org.apache.archiva.event;
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 }