View Javadoc

1   /*
2    * Copyright (C) 2017-2019 Centre National d'Etudes Spatiales (CNES).
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 3.0 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not, write to the Free Software
16   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17   * MA 02110-1301  USA
18   */
19  package fr.cnes.doi.plugin;
20  
21  import fr.cnes.doi.exception.DoiRuntimeException;
22  import fr.cnes.doi.settings.Consts;
23  import fr.cnes.doi.utils.spec.Requirement;
24  import java.lang.reflect.InvocationTargetException;
25  import java.lang.reflect.Method;
26  import java.util.Map;
27  import java.util.concurrent.ConcurrentHashMap;
28  
29  /**
30   *
31   * @author Jean-Christophe Malapert (jean-christophe.malapert@cnes.fr)
32   */
33  @Requirement(reqId = Requirement.DOI_ARCHI_030, reqName = Requirement.DOI_ARCHI_030_NAME)
34  public final class PluginFactory {
35  
36      /**
37       * Map the name of an interface to the name of a corresponding concrete
38       * implementation class.
39       */
40      private static final Map<String, String> PLUGINS_IMPL = new ConcurrentHashMap<>();
41  
42      /**
43       * Settings.
44       */
45      private static final Map<String, String> SETTINGS = new ConcurrentHashMap<>();
46  
47      /**
48       * Stores the instances of plugin.
49       */
50      private static final Map<String, Object> CONFIG = new ConcurrentHashMap<>();
51  
52      /**
53       * Loads the path of plugins from Settings.
54       *
55       * @param settings config settings
56       */
57      public static void init(final Map<String, String> settings) {
58          final String userRealPlugin = settings.getOrDefault(Consts.PLUGIN_USER_GROUP_MGT, "");
59          final String projectSuffixPlugin = settings.getOrDefault(Consts.PLUGIN_PROJECT_SUFFIX, "");
60          final String tokenPlugin = settings.getOrDefault(Consts.PLUGIN_TOKEN, "");
61          final String authPlugin = settings.getOrDefault(Consts.PLUGIN_AUTHENTICATION, "");
62          PLUGINS_IMPL.put(Consts.PLUGIN_USER_GROUP_MGT, userRealPlugin);
63          PLUGINS_IMPL.put(Consts.PLUGIN_PROJECT_SUFFIX, projectSuffixPlugin);
64          PLUGINS_IMPL.put(Consts.PLUGIN_TOKEN, tokenPlugin);
65          PLUGINS_IMPL.put(Consts.PLUGIN_AUTHENTICATION, authPlugin);
66          SETTINGS.putAll(settings);
67      }
68  
69      /**
70       * Returns the concrete implementation of the user management interface.
71       *
72       * @return the plugin
73       */
74      public static AbstractUserRolePluginHelper getUserManagement() {
75          final String implClassName = PLUGINS_IMPL.get(Consts.PLUGIN_USER_GROUP_MGT);
76          final AbstractUserRolePluginHelper plugin = getPlugin(implClassName);
77          if (!plugin.isConfigured()) {
78              plugin.setConfiguration(SETTINGS);
79              plugin.initConnection();
80          }
81          return plugin;
82      }
83  
84      /**
85       * Returns the concrete implementation of the suffix project db.
86       *
87       * @return the plugin
88       */
89      public static AbstractProjectSuffixPluginHelper getProjectSuffix() {
90          final String implClassName = PLUGINS_IMPL.get(Consts.PLUGIN_PROJECT_SUFFIX);
91          final AbstractProjectSuffixPluginHelper plugin = getPlugin(implClassName);
92          if (!plugin.isConfigured()) {
93              plugin.setConfiguration(SETTINGS);
94              plugin.initConnection();
95          }
96          return plugin;
97      }
98  
99      /**
100      * Returns the concrete implementation of the token db.
101      *
102      * @return the plugin
103      */
104     public static AbstractTokenDBPluginHelper getToken() {
105         final String implClassName = PLUGINS_IMPL.get(Consts.PLUGIN_TOKEN);
106         final AbstractTokenDBPluginHelper plugin = getPlugin(implClassName);
107         if (!plugin.isConfigured()) {
108             plugin.setConfiguration(SETTINGS);
109             plugin.initConnection();
110         }
111         return plugin;
112     }
113 
114     /**
115      * Returns the concrete implementation of the authentication system.
116      *
117      * @return the plugin
118      */
119     public static AbstractAuthenticationPluginHelper getAuthenticationSystem() {
120         final String implClassName = PLUGINS_IMPL.get(Consts.PLUGIN_AUTHENTICATION);
121         final AbstractAuthenticationPluginHelper plugin = getPlugin(implClassName);
122         if (!plugin.isConfigured()) {
123             plugin.setConfiguration(SETTINGS);
124             plugin.initConnection();
125         }
126         return plugin;
127     }
128 
129     /**
130      * Checks if the key is a password in the class keywordClassName related to
131      * the configuration file
132      *
133      * @param keywordClassName plugin related to the configuration file
134      * @param key keyword
135      * @return True when key is a password otherwise false
136      * @throws DoiRuntimeException When an error occurs
137      */
138     public static boolean isPassword(final String keywordClassName, final String key) throws
139             DoiRuntimeException {
140         try {
141             final String implClassName = PLUGINS_IMPL.get(keywordClassName);
142             final Class implClass = Class.forName(implClassName);
143             final Method method = implClass.getMethod("isPassword", String.class);
144             final Object obj = method.invoke(null, key);
145             return Boolean.getBoolean(String.valueOf(obj));
146         } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
147             throw new DoiRuntimeException(ex);
148         }
149     }
150 
151     /**
152      * Returns the plugin according to its implementation class.
153      *
154      * @param <T> the plugin
155      * @param implClassName implementation class
156      * @return the plugin
157      */
158     private static <T> T getPlugin(final String implClassName) {
159         final T plugin;
160         if (CONFIG.get(implClassName) == null) {
161             try {
162                 final Class impClass = Class.forName(implClassName);
163                 plugin = (T) impClass.cast(buildObject(implClassName));
164                 CONFIG.put(implClassName, plugin);
165             } catch (ClassNotFoundException ex) {
166                 throw new DoiRuntimeException(ex);
167             }
168         } else {
169             plugin = (T) CONFIG.get(implClassName);
170         }
171         return plugin;
172     }
173 
174     /**
175      * instantiates the plugin.
176      *
177      * @param aClassName the plugin name
178      * @return instance of aClassName
179      * @throws DoiRuntimeException - if aClassName cannot be instantiated
180      */
181     private static Object buildObject(final String aClassName) throws DoiRuntimeException {
182         final Object result;
183         try {
184             final Class implClass = Class.forName(aClassName);
185             result = implClass.newInstance();
186         } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
187             throw new DoiRuntimeException(ex);
188         }
189         return result;
190     }
191 
192     /**
193      * "Static" class cannot be instantiated
194      */
195     private PluginFactory() {
196     }
197 
198 }