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 }