View Javadoc

1   /**
2    * 2009, Digitalis Informatica. All rights reserved. Distribuicao e Gestao de Informatica, Lda. Estrada de Paco de Arcos
3    * num.9 - Piso -1 2780-666 Paco de Arcos Telefone: (351) 21 4408990 Fax: (351) 21 4408999 http://www.digitalis.pt
4    */
5   
6   package pt.digitalis.dif.ioc;
7   
8   import java.util.HashMap;
9   import java.util.List;
10  import java.util.Map;
11  import java.util.Map.Entry;
12  import java.util.Properties;
13  
14  import pt.digitalis.dif.controller.security.managers.IAuthenticationManager;
15  import pt.digitalis.dif.controller.security.managers.IAuthorizationManager;
16  import pt.digitalis.dif.controller.security.managers.IIdentityManager;
17  import pt.digitalis.dif.controller.security.managers.impl.AuthenticationManagerStaticImpl;
18  import pt.digitalis.dif.controller.security.managers.impl.AuthorizationManagerStaticImpl;
19  import pt.digitalis.dif.controller.security.managers.impl.IdentityManagerStaticImpl;
20  import pt.digitalis.dif.dem.managers.IMessageManager;
21  import pt.digitalis.dif.dem.managers.impl.MessageManagerImpl;
22  import pt.digitalis.utils.config.IConfigurations;
23  import pt.digitalis.utils.ioc.IIoCRegistry;
24  import pt.digitalis.utils.ioc.modules.IoCBinding;
25  import pt.digitalis.utils.ioc.modules.IoCBindingManager;
26  
27  /**
28   * Wraps a {@link IIoCRegistry} instance, adding the default/active module configuration funcionality for
29   * multi-implementations interfaces
30   * 
31   * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a><br/>
32   * @created 3 de Fev de 2011
33   */
34  public class DIFDefaultModulesConfiguration {
35  
36      /**  */
37      public static final String DEFAULT_MODULE_CONFIG_ID = "dif2";
38  
39      /**  */
40      public static final String DEFAULT_MODULE_CONFIG_SECTION_ID = "Modules";
41  
42      /** the singleton instance */
43      private static DIFDefaultModulesConfiguration instance = null;
44  
45      /**
46       * @return the singleton instance
47       */
48      public static DIFDefaultModulesConfiguration getInstance()
49      {
50          if (instance == null)
51              instance = new DIFDefaultModulesConfiguration();
52  
53          return instance;
54      }
55  
56      /**
57       * default DIF modules, when no configuration was specified.<br/>
58       * Map composed of k = interfaceClassCanonicalName; v = default implementation ID
59       */
60      private Map<String, String> defaultInnerDIFModuleDefaults = null;
61  
62      /** the default modules map cache object, after initialization. */
63      private Map<String, String> defaultModuleMap = null;
64  
65      /**
66       * the default constructor
67       */
68      public DIFDefaultModulesConfiguration()
69      {}
70  
71      /**
72       * Adds the default implementation from the implementation list. Used when no configurations exists
73       * 
74       * @param interfaceClass
75       * @param defaultImplClass
76       */
77      private void addDefaultIfAvailable(Class<?> interfaceClass, Class<?> defaultImplClass)
78      {
79          List<IoCBinding> bindings = IoCBindingManager.getInstance().getBindings(interfaceClass);
80          String implClassID = null;
81  
82          for (IoCBinding binding: bindings)
83              if (binding.getImplementationType() == defaultImplClass)
84              {
85                  implClassID = binding.getId();
86                  break;
87              }
88  
89          if (implClassID != null)
90              defaultInnerDIFModuleDefaults.put(interfaceClass.getCanonicalName(), implClassID);
91      }
92  
93      /**
94       * Adds to the default implementations list used when no configurations exists, the first implementation that is not
95       * the defaultImplClass, or defaultImplClass if it is the only one
96       * 
97       * @param interfaceClass
98       * @param defaultImplClass
99       */
100     private void addOtherThanDefaultIfAvailable(Class<?> interfaceClass, Class<?> defaultImplClass)
101     {
102         List<IoCBinding> bindings = IoCBindingManager.getInstance().getBindings(interfaceClass);
103         String implClassID = null;
104 
105         for (IoCBinding binding: bindings)
106             if (implClassID == null || binding.getImplementationType() != defaultImplClass)
107                 implClassID = binding.getId();
108 
109         defaultInnerDIFModuleDefaults.put(interfaceClass.getCanonicalName(), implClassID);
110     }
111 
112     /**
113      * @param serviceInterface
114      *            the serviceInterfase
115      * @return the Id of the default implementation as customized. Will use the hard-coded defaults if no custom
116      *         configuration exists
117      */
118     public IoCBinding getDefaultImplementationBindingFor(Class<?> serviceInterface)
119     {
120         return IoCBindingManager.getInstance().getBinding(serviceInterface,
121                 getDefaultImplementationIDFor(serviceInterface));
122     }
123 
124     /**
125      * @param serviceInterface
126      *            the serviceInterfase
127      * @return the Id of the default implementation as customized. Will use the hard-coded defaults if no custom
128      *         configuration exists
129      */
130     public String getDefaultImplementationIDFor(Class<?> serviceInterface)
131     {
132         if (defaultModuleMap == null)
133         {
134             defaultModuleMap = new HashMap<String, String>();
135 
136             // load customized configurations
137             IConfigurations config;
138             try
139             {
140                 config = (IConfigurations) IoCBindingManager.getInstance().getBinding(IConfigurations.class)
141                         .getImplementationType().newInstance();
142             }
143             catch (InstantiationException e)
144             {
145                 e.printStackTrace();
146                 return null;
147             }
148             catch (IllegalAccessException e)
149             {
150                 e.printStackTrace();
151                 return null;
152             }
153 
154             Properties customDefaultModules = config.readConfiguration(DEFAULT_MODULE_CONFIG_ID,
155                     DEFAULT_MODULE_CONFIG_SECTION_ID);
156 
157             for (Entry<Object, Object> entry: customDefaultModules.entrySet())
158                 defaultModuleMap.put(entry.getKey().toString(), entry.getValue().toString());
159 
160             // for DIF main modules, add missing configurations from defaults
161             for (Entry<String, String> entry: getDefaultInnerDIFModuleDefaults().entrySet())
162                 if (!defaultModuleMap.containsKey(entry.getKey()))
163                     defaultModuleMap.put(entry.getKey(), entry.getValue());
164         }
165 
166         return defaultModuleMap.get(serviceInterface.getCanonicalName());
167     }
168 
169     /**
170      * Inspector for the 'defaultInnerDIFModuleDefaults' attribute.
171      * 
172      * @return the defaultInnerDIFModuleDefaults value
173      */
174     protected Map<String, String> getDefaultInnerDIFModuleDefaults()
175     {
176         if (defaultInnerDIFModuleDefaults == null)
177         {
178             defaultInnerDIFModuleDefaults = new HashMap<String, String>();
179 
180             // Always add the static implementation AS THE DEFAULT.
181             // Customization will take priority if exists
182             // TODO: Luis: Add these contributions that do not have implementations in the Core module.
183             // TODO: Luis: Must add to the configurations persistence the selected module, for future backwards
184             // compatibility
185             // addDefaultIfAvailable(IContentManager.class, null);
186             // addDefaultIfAvailable(IDocumentRepositoryManager.class, null);
187             addDefaultIfAvailable(IMessageManager.class, MessageManagerImpl.class);
188             addDefaultIfAvailable(IMessageManager.class, MessageManagerImpl.class);
189             addDefaultIfAvailable(IAuthorizationManager.class, AuthorizationManagerStaticImpl.class);
190 
191             // Add "other" implementation than the static if present AS THE DEFAULT.
192             // Customization will take priority if exists
193             addOtherThanDefaultIfAvailable(IIdentityManager.class, IdentityManagerStaticImpl.class);
194             addOtherThanDefaultIfAvailable(IAuthenticationManager.class, AuthenticationManagerStaticImpl.class);
195         }
196 
197         return defaultInnerDIFModuleDefaults;
198     }
199 }