001package com.identityworksllc.iiq.common.plugin;
002
003import sailpoint.api.SailPointContext;
004import sailpoint.api.SailPointFactory;
005import sailpoint.object.Configuration;
006import sailpoint.object.Plugin;
007import sailpoint.plugin.PluginContext;
008import sailpoint.plugin.Setting;
009import sailpoint.tools.GeneralException;
010import sailpoint.tools.Util;
011
012import java.util.function.Supplier;
013
014/**
015 * A helper class intended to be used by anybody implementing CommonExtendedPluginConfig.
016 * It will retrieve values first from the configured {@link Configuration} object, then
017 * from the plugin settings.
018 *
019 * You should construct a new instance of this class for each retrieval. Do not cache them
020 * or your SailPointContext will go stale.
021 */
022public class ExtendedPluginContextHelper implements CommonExtendedPluginContext {
023
024        @FunctionalInterface
025        public interface ConfigurationNameProvider extends Supplier<String> {
026
027        }
028
029        /**
030         * The current sailpoint context
031         */
032        private SailPointContext context;
033
034        /**
035         * Provides the name of the configuration class
036         */
037        private ConfigurationNameProvider nameProvider;
038        
039        /**
040         * The plugin context (provides plugin config)
041         */
042        private PluginContext pluginContext;
043        
044        /**
045         * The plugin name
046         */
047        private String pluginName;      
048
049        /**
050         * Constructor
051         * @param pluginName The plugin name
052         * @param context The Sailpoint context
053         * @param pluginContext The plugin context class
054         */
055        public ExtendedPluginContextHelper(String pluginName, SailPointContext context, PluginContext pluginContext, ConfigurationNameProvider nameProvider) {
056                this.pluginName = pluginName;
057                this.context = context;
058                this.pluginContext = pluginContext;
059                this.nameProvider = nameProvider;
060        }
061
062        
063        /**
064         * Bootstraps the Configuration object from the plugin settings. This will be used from now on.
065         * @throws GeneralException if any failures occur
066         */
067        private void bootstrapConfig() throws GeneralException {
068                SailPointContext existing = context;
069                SailPointContext privateContext = SailPointFactory.createPrivateContext();
070                SailPointFactory.setContext(privateContext);
071                try {
072                        Configuration config = new Configuration();
073                        config.setName(getSettingsConfigName());
074                        Plugin pluginObject = privateContext.getObjectByName(Plugin.class, pluginName);
075                        if (pluginObject != null) {
076                                if (pluginObject.getSettings() != null) {
077                                        for(Setting setting : pluginObject.getSettings()) {
078                                                String settingValue = Util.isNullOrEmpty(setting.getValue()) ? setting.getDefaultValue() : setting.getValue();
079                                                config.put(setting.getName(), settingValue);
080                                        }
081                                }
082                        }
083                        privateContext.saveObject(config);
084                        privateContext.commitTransaction();
085                        privateContext.decache();
086                } finally {
087                        SailPointFactory.releasePrivateContext(privateContext);
088                        SailPointFactory.setContext(existing);
089                }
090        }
091        
092
093        @Override
094        public boolean getConfigurationBool(String settingName) {
095                try {
096                        Configuration config = context.getObjectByName(Configuration.class, getSettingsConfigName());
097                        if (config == null) {
098                                bootstrapConfig();
099                                context.decache();
100                                config = context.getObjectByName(Configuration.class, getSettingsConfigName());
101                        } 
102                        if (config != null && config.containsAttribute(settingName)) {
103                                return config.getBoolean(settingName);
104                        }
105                } catch(GeneralException e) {
106                        // Ignore this, default to the plugin settings
107                }
108                return pluginContext.getSettingBool(settingName);
109        }
110
111        @Override
112        public int getConfigurationInt(String settingName) {
113                try {
114                        Configuration config = context.getObjectByName(Configuration.class, getSettingsConfigName());
115                        if (config == null) {
116                                bootstrapConfig();
117                                context.decache();
118                                config = context.getObjectByName(Configuration.class, getSettingsConfigName());
119                        } 
120                        if (config != null && config.containsAttribute(settingName)) {
121                                return config.getInt(settingName);
122                        }
123                } catch(GeneralException e) {
124                        // Ignore this, default to the plugin settings
125                }
126                return pluginContext.getSettingInt(settingName);
127        }
128
129        @Override
130        @SuppressWarnings("unchecked")
131        public <T> T getConfigurationObject(String settingName) {
132                try {
133                        Configuration config = context.getObjectByName(Configuration.class, getSettingsConfigName());
134                        if (config == null) {
135                                bootstrapConfig();
136                                context.decache();
137                                config = context.getObjectByName(Configuration.class, getSettingsConfigName());
138                        } 
139                        if (config != null && config.containsAttribute(settingName)) {
140                                return (T)config.get(settingName);
141                        }
142                } catch(GeneralException e) {
143                        // Ignore this, default to the plugin settings
144                }
145                return null;
146        }
147
148        @Override
149        public String getConfigurationString(String settingName) {
150                try {
151                        Configuration config = context.getObjectByName(Configuration.class, getSettingsConfigName());
152                        if (config == null) {
153                                bootstrapConfig();
154                                context.decache();
155                                config = context.getObjectByName(Configuration.class, getSettingsConfigName());
156                        } 
157                        if (config != null && config.containsAttribute(settingName)) {
158                                return config.getString(settingName);
159                        }
160                } catch(GeneralException e) {
161                        // Ignore this, default to the plugin settings
162                }
163                return pluginContext.getSettingString(settingName);
164        }
165        
166        /**
167         * The settings configuration object name. If a name provider exists, it will be used to
168         * get the Configuration name. Otherwise, it will default to `Plugin Configuration [plugin name]`.
169         *
170         * @return The name of the Configuration object
171         */
172        private String getSettingsConfigName() {
173                if (nameProvider != null) {
174                        return nameProvider.get();
175                } else {
176                        return "Plugin Configuration " + pluginName;
177                }
178        }
179        
180        
181
182}