1 module hunt.shiro.util.LifecycleUtils;
2 
3 import hunt.shiro.util.Common;
4 
5 import hunt.collection.Collection;
6 import hunt.logging.Logger;
7 
8 import std.array;
9 
10 /**
11  * Utility class to help call {@link hunt.shiro.util.Initializable#init() Initializable.init()} and
12  * {@link hunt.shiro.util.Destroyable#destroy() Destroyable.destroy()} methods cleanly on any object.
13  *
14  * @since 0.2
15  */
16 abstract class LifecycleUtils {
17 
18     static void init(Object o) {
19         Initializable obj = cast(Initializable) o;
20         if (obj !is null) {
21             init(obj);
22         }
23     }
24 
25     static void init(Initializable initializable) {
26         initializable.init();
27     }
28 
29     /**
30      * Calls {@link #init(Object) init} for each object in the collection.  If the collection is {@code null} or empty,
31      * this method returns quietly.
32      *
33      * @param c the collection containing objects to {@link #init init}.
34      * @throws ShiroException if unable to initialize one or more instances.
35      * @since 0.9
36      */
37     static void init(Collection!Object c) {
38         if (c is null || c.isEmpty()) {
39             return;
40         }
41         foreach (Object o ; c) {
42             init(o);
43         }
44     }
45 
46     static void init(Object[] c) {
47         if (c.empty()) {
48             return;
49         }
50         foreach (Object o ; c) {
51             init(o);
52         }
53     }
54 
55     static void destroy(Object o) {
56         Destroyable d = cast(Destroyable)o;
57         if (d !is null) {
58             destroy(d);
59         } else {
60             Collection!Object c = cast(Collection!Object)o;
61             if (c !is null) {
62                 destroy(c);
63             }
64         }
65     }
66 
67     static void destroy(Destroyable d) {
68         if (d !is null) {
69             try {
70                 d.destroy();
71             } catch (Throwable t) {
72                 version(HUNT_DEBUG) {
73                     string msg = "Unable to cleanly destroy instance [" ~ 
74                         (cast(Object)d).toString() ~ "] of type [" ~ 
75                         typeid(cast(Object)d).name ~ "].";
76                     trace(msg, t);
77                 }
78             }
79         }
80     }
81 
82     /**
83      * Calls {@link #destroy(Object) destroy} for each object in the collection.
84      * If the collection is {@code null} or empty, this method returns quietly.
85      *
86      * @param c the collection of objects to destroy.
87      * @since 0.9
88      */
89     static void destroy(Collection!Object c) {
90         if (c is null || c.isEmpty()) {
91             return;
92         }
93 
94         foreach (Object o ; c) {
95             destroy(o);
96         }
97     }
98 
99     static void destroy(Object[] c) {
100         if (c is null) {
101             return;
102         }
103 
104         foreach (Object o ; c) {
105             destroy(o);
106         }
107     }
108 }