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.config.IniFactorySupport;
20 
21 import hunt.shiro.config.Ini;
22 // import hunt.shiro.io.ResourceUtils;
23 import hunt.shiro.util.AbstractFactory;
24 // import hunt.shiro.util.CollectionUtils;
25 // import hunt.shiro.util.Factory;
26 
27 import hunt.collection.HashMap;
28 import hunt.collection.Map;
29 import hunt.Exceptions;
30 import hunt.logging.Logger;
31 
32 /**
33  * Base support class for {@link Factory} implementations that generate their instance(s) based on
34  * {@link Ini} configuration.
35  *
36  * @since 1.0
37  * deprecated("") use Shiro's {@code Environment} mechanisms instead.
38  */
39 // deprecated("")
40 abstract class IniFactorySupport(T) : AbstractFactory!(T) {
41 
42     enum string DEFAULT_INI_RESOURCE_PATH = "shiro.ini";
43 
44     private Ini ini;
45 
46     private Map!(string, T) defaultBeans;
47 
48     protected this() {
49     }
50 
51     protected this(Ini ini) {
52         this.ini = ini;
53     }
54 
55     Ini getIni() {
56         return ini;
57     }
58 
59      void setIni(Ini ini) {
60         this.ini = ini;
61     }
62 
63     /**
64      * Returns a mapping of string to bean representing the default set of object used by the factory.
65      * These beans can be used by this factory in conjunction with objects parsed from the INI configuration.
66      * @return A Map of default objects, or <code>null</code>.
67      * @since 1.4
68      */
69     protected Map!(string, T) getDefaults() {
70         return defaultBeans;
71     }
72 
73     /**
74      * Sets the default objects used by this factory. These defaults may be used in conjunction with the INI
75      * configuration.
76      * @param defaultBeans string to object mapping used for default configuration in this factory.
77      * @since 1.4
78      */
79      void setDefaults(Map!(string, T) defaultBeans) {
80         this.defaultBeans = defaultBeans;
81     }
82 
83     /**
84      * Returns a new Ini instance created from the default {@code classpath:shiro.ini} file, or {@code null} if
85      * the file does not exist.
86      *
87      * @return a new Ini instance created from the default {@code classpath:shiro.ini} file, or {@code null} if
88      *         the file does not exist.
89      */
90      static Ini loadDefaultClassPathIni() {
91         Ini ini = Ini.fromResourcePath(DEFAULT_INI_RESOURCE_PATH);
92         if (ini is null || ini.isEmpty()) {
93             warning("shiro.ini found at the root of the classpath, but it did not contain any data.");
94         }
95         return ini;
96     }
97 
98     /**
99      * Tries to resolve the Ini instance to use for configuration.  This implementation functions as follows:
100      * <ol>
101      * <li>The {@code Ini} instance returned from {@link #getIni()} will be returned if it is not null or empty.</li>
102      * <li>If {@link #getIni()} is {@code null} or empty, this implementation will attempt to find and load the
103      * {@link #loadDefaultClassPathIni() default class path Ini}.</li>
104      * <li>If neither of the two attempts above returns an instance, {@code null} is returned</li>
105      * </ol>
106      *
107      * @return the Ini instance to use for configuration.
108      */
109     protected Ini resolveIni() {
110         Ini ini = getIni();
111         if (ini is null || ini.isEmpty()) {
112             tracef("Null or empty Ini instance.  Falling back to the default %s file.", DEFAULT_INI_RESOURCE_PATH);
113             ini = loadDefaultClassPathIni();
114         }
115         return ini;
116     }
117 
118     /**
119      * Creates a new object instance by using a configured INI source.  This implementation functions as follows:
120      * <ol>
121      * <li>{@link #resolveIni() Resolve} the {@code Ini} source to use for configuration.</li>
122      * <li>If there was no resolved Ini source, create and return a simple default instance via the
123      * {@link #createDefaultInstance()} method.</li>
124      * </ol>
125      *
126      * @return a new {@code SecurityManager} instance by using a configured INI source.
127      */
128     override T createInstance() {
129         Ini ini = resolveIni();
130 
131         T instance;
132 
133         if (ini is null || ini.isEmpty()) {
134             info("No populated Ini available.  Creating a default instance.");
135             instance = createDefaultInstance();
136             if (instance is null) {
137                 string msg = typeid(this).name ~ " implementation did not return a default instance in " ~
138                         "the event of a null/empty Ini configuration.  This is required to support the " ~
139                         "Factory interface.  Please check your implementation.";
140                 warning(msg);
141                 throw new IllegalStateException(msg);
142             }
143         } else {
144             info("Creating instance from Ini [" ~ ini.toString() ~ "]");
145             instance = createInstance(ini);
146             if (instance  is null) {
147                 string msg = typeid(this).name ~ " implementation did not return a constructed instance from " ~
148                         "the createInstance(Ini) method implementation.";
149                 throw new IllegalStateException(msg);
150             }
151         }
152 
153         return instance;
154     }
155 
156     protected abstract T createInstance(Ini ini);
157 
158     protected abstract T createDefaultInstance();
159 }