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.EventListenerComparator;
20 
21 import hunt.shiro.event.support.EventListener;
22 import hunt.shiro.event.support.EventClassComparator;
23 import hunt.shiro.event.support.TypedEventListener;
24 
25 import hunt.logging.Logger;
26 import hunt.util.Comparator;
27 
28 import std.concurrency : initOnce;
29 
30 /**
31  * Compares two event listeners to determine the order in which they should be invoked when an event is dispatched.
32  * The lower the order, the sooner it will be invoked (the higher its precedence).  The higher the order, the later
33  * it will be invoked (the lower its precedence).
34  * <p/>
35  * TypedEventListeners have a higher precedence (i.e. a lower order) than standard EventListener instances.  Standard
36  * EventListener instances have the same order priority.
37  * <p/>
38  * When both objects being compared are TypedEventListeners, they are ordered according to the rules of the
39  * {@link EventClassComparator}, using the TypedEventListeners'
40  * {@link TypedEventListener#getEventType() eventType}.
41  *
42  * @since 1.3
43  */
44 class EventListenerComparator : Comparator!EventListener {
45 
46     //event class comparator is stateless, so we can retain an instance:
47     private static EventClassComparator EVENT_CLASS_COMPARATOR() {
48         __gshared EventClassComparator inst;
49         return initOnce!inst(new EventClassComparator);
50     } 
51 
52     int compare(EventListener a, EventListener b) {
53         try {
54         if (a is null) {
55             if (b is null) {
56                 return 0;
57             } else {
58                 return -1;
59             }
60         } else if (b is null) {
61             return 1;
62         } else if (a is b || a == b) {
63             return 0;
64         } else {
65             TypedEventListener ta = cast(TypedEventListener)a;
66             TypedEventListener tb = cast(TypedEventListener)b;
67             if (ta !is null) {
68                 if (tb !is null) {
69                     return EVENT_CLASS_COMPARATOR.compare(ta.getEventType(), tb.getEventType());
70                 } else {
71                     return -1; //TypedEventListeners are 'less than' (higher priority) than non typed
72                 }
73             } else {
74                 if (tb !is null) {
75                     return 1;
76                 } else {
77                     return 0;
78                 }
79             }
80         }
81 
82             
83         } catch(Exception ex) {
84             warning(ex.msg);
85             return 0;
86         }
87     }
88 }