1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 module hunt.shiro.event.support.EventClassComparator;
20 
21 import hunt.shiro.event.support.SingleArgumentMethodEventListener;
22 import hunt.util.Comparator;
23 
24 import hunt.Exceptions;
25 import hunt.logging.Logger;
26 
27 /**
28  * Compares two event classes based on their position in a class hierarchy.  Classes higher up in a hierarchy are
29  * 'greater than' (ordered later) than classes lower in a hierarchy (ordered earlier).  Classes in unrelated
30  * hierarchies have the same order priority.
31  * <p/>
32  * Event bus implementations use this comparator to determine which event listener method to invoke when polymorphic
33  * listener methods are defined:
34  * <p/>
35  * If two event classes exist A and B, where A is the parent class of B (and B is a subclass of A) and an event
36  * subscriber listens to both events:
37  * <pre>
38  * &#64;Subscribe
39  * void onEvent(A a) { ... }
40  *
41  * &#64;Subscribe
42  * void onEvent(B b) { ... }
43  * </pre>
44  *
45  * The {@code onEvent(B b)} method will be invoked on the subscriber and the
46  * {@code onEvent(A a)} method will <em>not</em> be invoked.  This is to prevent multiple dispatching of a single event
47  * to the same consumer.
48  * <p/>
49  * The EventClassComparator is used to order listener method priority based on their event argument class - methods
50  * handling event subclasses have higher precedence than superclasses.
51  *
52  * @since 1.3
53  */
54 class EventClassComparator : Comparator!TypeInfo_Class {
55 
56     int compare(TypeInfo_Class a, TypeInfo_Class b) {
57         try {
58             if (a is null) {
59                 if (b is null) {
60                     return 0;
61                 } else {
62                     return -1;
63                 }
64             } else if (b is null) {
65                 return 1;
66             } else if (a is b || a.opEquals(b)) {
67                 return 0;
68             } else {
69                 implementationMissing(false);
70                 return 0;
71                 // if (a.isAssignableFrom(b)) {
72                 //     return 1;
73                 // } else if (b.isAssignableFrom(a)) {
74                 //     return -1;
75                 // } else {
76                 //     return 0;
77                 // }
78             }
79         }
80       catch(Exception ex)   {
81           warning(ex.msg);
82           return 0;
83       }
84     } 
85 }