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