From 806cabb2c016647875edc8aab4c5ede5d55276f5 Mon Sep 17 00:00:00 2001 From: Lyncode Date: Mon, 13 Aug 2012 15:43:09 +0100 Subject: [PATCH 1/4] Dynamic Configuration Service A Dynamic alternative. New API provided. File based implementation. Addon configuration must be created in order to be modifyable. --- .gitignore | 23 ++ api/pom.xml | 5 + .../services/DynamicConfigurationService.java | 39 +++ impl/pom.xml | 5 + .../DSpaceDynamicConfigurationService.java | 287 ++++++++++++++++++ .../config/DSpacePropertiesConfiguration.java | 125 ++++++++ 6 files changed, 484 insertions(+) create mode 100644 .gitignore create mode 100644 api/src/main/java/org/dspace/services/DynamicConfigurationService.java create mode 100644 impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java create mode 100644 impl/src/main/java/org/dspace/servicemanager/config/DSpacePropertiesConfiguration.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..34e4cb9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +## Ignore the MVN compiled output directories from version tracking +target/ + +## Ignore project files created by Eclipse +.settings/ +.project +.classpath + +## Ignore project files created by IntelliJ IDEA +*.iml +*.ipr +*.iws +.idea/ + +## Ignore project files created by NetBeans +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +nbactions.xml +nb-configuration.xml +META-INF/ \ No newline at end of file diff --git a/api/pom.xml b/api/pom.xml index 660db33..af48d33 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -50,6 +50,11 @@ commons-lang 2.4 + + commons-configuration + commons-configuration + 1.8 + diff --git a/api/src/main/java/org/dspace/services/DynamicConfigurationService.java b/api/src/main/java/org/dspace/services/DynamicConfigurationService.java new file mode 100644 index 0000000..a33eb9c --- /dev/null +++ b/api/src/main/java/org/dspace/services/DynamicConfigurationService.java @@ -0,0 +1,39 @@ +package org.dspace.services; + +import java.util.List; + +import org.apache.commons.configuration.event.ConfigurationListener; + +public interface DynamicConfigurationService { + // Main Configuration File API + public Object getProperty (String key); + public boolean setProperty (String key, Object value); + public String getString (String key, String defaultValue); + public int getInt (String key, int defaultValue); + public long getLong (String key, long defaultValue); + public boolean getBoolean (String key, boolean defaultValue); + public List getList (String key); + public void addConfigurationListener (ConfigurationListener listener); + + // Modules Configuration API + public Object getModuleProperty (String module, String key); + public boolean setModuleProperty (String module, String key, Object value); + public String getModuleString (String module, String key, String defaultValue); + public int getModuleInt (String module, String key, int defaultValue); + public long getModuleLong (String module, String key, long defaultValue); + public boolean getModuleBoolean (String module, String key, boolean defaultValue); + public List getModuleList (String module, String key); + public void addModuleConfigurationListener (String module, ConfigurationListener listener); + + // Addon Configuration API + public Object getAddonProperty (String addon, String key); + public boolean setAddonProperty (String addon, String key, Object value); + public String getAddonString (String addon, String key, String defaultValue); + public long getAddonLong (String addon, String key, long defaultValue); + public int getAddonInt (String addon, String key, int defaultValue); + public boolean getAddonBoolean (String addon, String key, boolean defaultValue); + public List getAddonList (String addon, String key); + public void addAddonConfigurationListener (String addon, ConfigurationListener listener); + public boolean createAddonConfiguration (String addon); + public boolean addProperty (String addon, String key, Object value, String description); +} diff --git a/impl/pom.xml b/impl/pom.xml index 267eef8..f4ff4bd 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -144,6 +144,11 @@ commons-collections 3.2 + + commons-configuration + commons-configuration + 1.8 + diff --git a/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java b/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java new file mode 100644 index 0000000..b356cad --- /dev/null +++ b/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java @@ -0,0 +1,287 @@ +package org.dspace.servicemanager.config; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.event.ConfigurationListener; +import org.dspace.services.DynamicConfigurationService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +public class DSpaceDynamicConfigurationService implements + DynamicConfigurationService { + private static final Logger log = LoggerFactory.getLogger(DSpaceDynamicConfigurationService.class); + + private static final String DSPACE = "dspace"; + private static final String DSPACE_HOME = "dspace.dir"; + private static final String DOT_CONFIG = ".cfg"; + private static final String DSPACE_MODULES_CONFIG_PATH = "config" + File.separator + "modules"; + private static final String DSPACE_ADDONS_CONFIG_PATH = "config" + File.separator + "addons"; + private static final String DSPACE_CONFIG_PATH = "config/" + DSPACE + DOT_CONFIG; + + private String home; + private DSpacePropertiesConfiguration config = null; + private Map modulesConfig = null; + private Map addonsConfig = null; + + public DSpaceDynamicConfigurationService () { + home = null; + loadConfiguration(); + } + public DSpaceDynamicConfigurationService (String home) { + this.home = home; + loadConfiguration(); + } + + private void loadConfiguration () { + // now we load the settings from properties files + String homePath = System.getProperty(DSPACE_HOME); + + // now we load from the provided parameter if its not null + if (this.home != null && homePath == null) { + homePath = this.home; + } + + if (homePath == null) { + String catalina = System.getProperty("catalina.base"); + if (catalina == null) + catalina = System.getProperty("catalina.home"); + if (catalina != null) { + homePath = catalina + File.separatorChar + DSPACE + File.separatorChar; + } + } + if (homePath == null) { + homePath = System.getProperty("user.home"); + } + if (homePath == null) { + homePath = "/"; + } + + try{ + config = new DSpacePropertiesConfiguration(homePath + File.separatorChar + DSPACE_CONFIG_PATH); + File modulesDirectory = new File(homePath + File.separator + DSPACE_MODULES_CONFIG_PATH + File.separator); + modulesConfig = new TreeMap(); + if(modulesDirectory.exists()){ + try{ + Resource[] resources = new PathMatchingResourcePatternResolver().getResources(modulesDirectory.toURI().toURL().toString() + "*" + DOT_CONFIG); + if(resources != null){ + for(Resource resource : resources){ + String prefix = resource.getFilename().substring(0, resource.getFilename().lastIndexOf(".")); + modulesConfig.put(prefix, new DSpacePropertiesConfiguration(resource.getFile())); + } + } + }catch (Exception e){ + log.error("Error while loading the modules properties from:" + modulesDirectory.getAbsolutePath()); + } + }else{ + log.info("Failed to load the modules properties since (" + homePath + File.separator + DSPACE_MODULES_CONFIG_PATH + "): Does not exist"); + } + + } catch (IllegalArgumentException e){ + //This happens if we don't have a modules directory + log.error("Error while loading the module properties since (" + homePath + File.separator + DSPACE_MODULES_CONFIG_PATH + "): is not a valid directory", e); + } catch (ConfigurationException e) { + // This happens if an error occurs on parsing files + log.error("Error while loading properties from " + homePath + File.separator + DSPACE_MODULES_CONFIG_PATH , e); + } + + + try{ + File addonsDirectory = new File(homePath + File.separator + DSPACE_ADDONS_CONFIG_PATH + File.separator); + addonsConfig = new TreeMap(); + if(addonsDirectory.exists()){ + try{ + Resource[] resources = new PathMatchingResourcePatternResolver().getResources(addonsDirectory.toURI().toURL().toString() + "*" + DOT_CONFIG); + if(resources != null){ + for(Resource resource : resources){ + String prefix = resource.getFilename().substring(0, resource.getFilename().lastIndexOf(".")); + addonsConfig.put(prefix, new DSpacePropertiesConfiguration(resource.getFile())); + } + } + }catch (Exception e){ + log.error("Error while loading the addons properties from:" + addonsDirectory.getAbsolutePath()); + } + }else{ + log.info("Failed to load the addons properties since (" + homePath + File.separator + DSPACE_ADDONS_CONFIG_PATH + "): Does not exist"); + } + + } catch (IllegalArgumentException e){ + //This happens if we don't have a modules directory + log.error("Error while loading the module properties since (" + homePath + File.separator + DSPACE_ADDONS_CONFIG_PATH + "): is not a valid directory", e); + } + } + @Override + public Object getProperty(String key) { + return config.getProperty(key); + } + @Override + public boolean setProperty(String key, Object value) { + config.setProperty(key, value); + return true; + } + @Override + public String getString(String key, String defaultValue) { + return config.getString(key, defaultValue); + } + @Override + public int getInt(String key, int defaultValue) { + return config.getInt(key, defaultValue); + } + @Override + public long getLong(String key, long defaultValue) { + return config.getLong(key, defaultValue); + } + @Override + public boolean getBoolean(String key, boolean defaultValue) { + return config.getBoolean(key, defaultValue); + } + @Override + public List getList(String key) { + return config.getList(key); + } + @Override + public void addConfigurationListener(ConfigurationListener listener) { + config.addConfigurationEventListener(listener); + } + + + @Override + public Object getModuleProperty(String module, String key) { + if (modulesConfig.containsKey(module)) + return modulesConfig.get(module).getProperty(key); + return null; + } + @Override + public boolean setModuleProperty(String module, String key, Object value) { + if (modulesConfig.containsKey(module)) { + modulesConfig.get(module).setProperty(key, value); + return true; + } + return false; + } + @Override + public String getModuleString(String module, String key, String defaultValue) { + if (modulesConfig.containsKey(module)) + return modulesConfig.get(module).getString(key, defaultValue); + return defaultValue; + } + @Override + public int getModuleInt(String module, String key, int defaultValue) { + if (modulesConfig.containsKey(module)) + return modulesConfig.get(module).getInt(key, defaultValue); + return defaultValue; + } + @Override + public long getModuleLong(String module, String key, long defaultValue) { + if (modulesConfig.containsKey(module)) + return modulesConfig.get(module).getLong(key, defaultValue); + return defaultValue; + } + @Override + public boolean getModuleBoolean(String module, String key, + boolean defaultValue) { + if (modulesConfig.containsKey(module)) + return modulesConfig.get(module).getBoolean(key, defaultValue); + return defaultValue; + } + @Override + public List getModuleList(String module, String key) { + if (modulesConfig.containsKey(module)) + return modulesConfig.get(module).getList(key); + return new ArrayList(); + } + @Override + public void addModuleConfigurationListener(String module, + ConfigurationListener listener) { + if (modulesConfig.containsKey(module)) + modulesConfig.get(module).addConfigurationEventListener(listener); + } + + + @Override + public Object getAddonProperty(String addon, String key) { + if (addonsConfig.containsKey(addon)) + return addonsConfig.get(addon).getProperty(key); + return null; + } + @Override + public boolean setAddonProperty(String addon, String key, Object value) { + if (addonsConfig.containsKey(addon)) { + addonsConfig.get(addon).setProperty(key, value); + return true; + } + return false; + } + @Override + public String getAddonString(String addon, String key, String defaultValue) { + if (addonsConfig.containsKey(addon)) + return addonsConfig.get(addon).getString(key, defaultValue); + return defaultValue; + } + @Override + public long getAddonLong(String addon, String key, long defaultValue) { + if (addonsConfig.containsKey(addon)) + return addonsConfig.get(addon).getLong(key, defaultValue); + return defaultValue; + } + @Override + public int getAddonInt(String addon, String key, int defaultValue) { + if (addonsConfig.containsKey(addon)) + return addonsConfig.get(addon).getInt(key, defaultValue); + return defaultValue; + } + @Override + public boolean getAddonBoolean(String addon, String key, + boolean defaultValue) { + if (addonsConfig.containsKey(addon)) + return addonsConfig.get(addon).getBoolean(key, defaultValue); + return defaultValue; + } + @Override + public List getAddonList(String addon, String key) { + if (addonsConfig.containsKey(addon)) + return addonsConfig.get(addon).getList(key); + return new ArrayList(); + } + @Override + public void addAddonConfigurationListener(String addon, + ConfigurationListener listener) { + if (addonsConfig.containsKey(addon)) + addonsConfig.get(addon).addConfigurationEventListener(listener); + } + @Override + public boolean createAddonConfiguration(String addon) { + String path = this.home + File.separator + DSPACE_ADDONS_CONFIG_PATH + File.separator + addon + DOT_CONFIG; + try { + File f = new File(path); + f.createNewFile(); + DSpacePropertiesConfiguration config = new DSpacePropertiesConfiguration(f); + this.addonsConfig.put(addon, config); + return true; + } catch (ConfigurationException e) { + log.error("Error while loading the addon properties from: " + path); + return false; + } catch (IOException e) { + log.error("Error while creating the addon properties file at: " + path); + return false; + } + + } + @Override + public boolean addProperty(String addon, String key, Object value, + String description) { + if (addonsConfig.containsKey(addon)) { + addonsConfig.get(addon).addProperty(key, value); + addonsConfig.get(addon).setPropertyDescription(key, description); + return true; + } + return false; + } +} diff --git a/impl/src/main/java/org/dspace/servicemanager/config/DSpacePropertiesConfiguration.java b/impl/src/main/java/org/dspace/servicemanager/config/DSpacePropertiesConfiguration.java new file mode 100644 index 0000000..48962f1 --- /dev/null +++ b/impl/src/main/java/org/dspace/servicemanager/config/DSpacePropertiesConfiguration.java @@ -0,0 +1,125 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.servicemanager.config; + +import java.io.File; +import java.net.URL; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.configuration.event.ConfigurationListener; +import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy; + +/** + * Class to read and write configuration files. + * + * @author DSpace @ Lyncode + */ +public class DSpacePropertiesConfiguration { + private PropertiesConfiguration write; + private PropertiesConfiguration read; + + public DSpacePropertiesConfiguration(File file) throws ConfigurationException { + write = new PropertiesConfiguration(file); + write.setAutoSave(true); + read = new PropertiesConfiguration(file); + read.setAutoSave(false); + FileChangedReloadingStrategy stretagy = new FileChangedReloadingStrategy(); + read.setReloadingStrategy(stretagy); + write.setReloadingStrategy(stretagy); + } + public DSpacePropertiesConfiguration(String fileName) throws ConfigurationException { + write = new PropertiesConfiguration(fileName); + write.setAutoSave(true); + read = new PropertiesConfiguration(fileName); + read.setAutoSave(false); + FileChangedReloadingStrategy stretagy = new FileChangedReloadingStrategy(); + read.setReloadingStrategy(stretagy); + write.setReloadingStrategy(stretagy); + } + public DSpacePropertiesConfiguration(URL url) throws ConfigurationException { + write = new PropertiesConfiguration(url); + write.setAutoSave(true); + read = new PropertiesConfiguration(url); + read.setAutoSave(false); + FileChangedReloadingStrategy stretagy = new FileChangedReloadingStrategy(); + read.setReloadingStrategy(stretagy); + write.setReloadingStrategy(stretagy); + } + + public void save() throws ConfigurationException { + write.save(); + } + public void addProperty(String key, Object value) { + write.addProperty(key, value); + read.addProperty(key, value); + } + + public void setPropertyDescription (String key, String description) { + write.getLayout().setComment(key, description); + read.getLayout().setComment(key, description); + } + + public void setProperty(String key, Object value) { + write.setProperty(key, value); + read.setProperty(key, value); + } + + public Properties getProperties () { + Properties p = new Properties(); + Iterator it = write.getKeys(); + while (it.hasNext()) { + String k = it.next(); + p.put(k, write.getString(k)); + } + return p; + } + + public Object getProperty (String key) { + return read.getProperty(key); + } + + public String getString (String key) { + return read.getString(key); + } + public String getString (String key, String defaultValue) { + return read.getString(key, defaultValue); + } + public List getList (String key) { + return Arrays.asList(read.getStringArray(key)); + } + + public boolean containsKey (String key) { + return read.containsKey(key); + } + + public Iterator getKeys () { + return write.getKeys(); + } + + public void load (File f) throws ConfigurationException { + read.load(f); + } + + public void addConfigurationEventListener (ConfigurationListener event) { + read.addConfigurationListener(event); + } + public int getInt(String key, int defaultValue) { + return read.getInt(key, defaultValue); + } + public long getLong(String key, long defaultValue) { + return read.getLong(key, defaultValue); + } + public boolean getBoolean(String key, boolean defaultValue) { + return read.getBoolean(key, defaultValue); + } +} From 70bd85e3c1036f8b2859c8ea1c68ca12634410ea Mon Sep 17 00:00:00 2001 From: Lyncode Date: Mon, 13 Aug 2012 16:02:51 +0100 Subject: [PATCH 2/4] Licensing Info added --- .../dspace/services/DynamicConfigurationService.java | 12 ++++++++++++ .../config/DSpaceDynamicConfigurationService.java | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/api/src/main/java/org/dspace/services/DynamicConfigurationService.java b/api/src/main/java/org/dspace/services/DynamicConfigurationService.java index a33eb9c..3a21602 100644 --- a/api/src/main/java/org/dspace/services/DynamicConfigurationService.java +++ b/api/src/main/java/org/dspace/services/DynamicConfigurationService.java @@ -1,9 +1,21 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ package org.dspace.services; import java.util.List; import org.apache.commons.configuration.event.ConfigurationListener; +/** + * Dynamic Configuration Service API + * + * @author DSpace @ Lyncode + */ public interface DynamicConfigurationService { // Main Configuration File API public Object getProperty (String key); diff --git a/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java b/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java index b356cad..b0c75ce 100644 --- a/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java +++ b/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java @@ -1,3 +1,10 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ package org.dspace.servicemanager.config; import java.io.File; @@ -15,6 +22,11 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +/** + * Dynamic Configuration Service Implementation + * + * @author DSpace @ Lyncode + */ public class DSpaceDynamicConfigurationService implements DynamicConfigurationService { private static final Logger log = LoggerFactory.getLogger(DSpaceDynamicConfigurationService.class); From 74d4b57b20ca2737d3e0538636fae1a3191bd4ef Mon Sep 17 00:00:00 2001 From: Lyncode Date: Mon, 13 Aug 2012 16:18:17 +0100 Subject: [PATCH 3/4] Get Properties Description feature added. --- .../services/DynamicConfigurationService.java | 3 +++ .../DSpaceDynamicConfigurationService.java | 16 ++++++++++++++++ .../config/DSpacePropertiesConfiguration.java | 3 +++ 3 files changed, 22 insertions(+) diff --git a/api/src/main/java/org/dspace/services/DynamicConfigurationService.java b/api/src/main/java/org/dspace/services/DynamicConfigurationService.java index 3a21602..7a55670 100644 --- a/api/src/main/java/org/dspace/services/DynamicConfigurationService.java +++ b/api/src/main/java/org/dspace/services/DynamicConfigurationService.java @@ -19,6 +19,7 @@ public interface DynamicConfigurationService { // Main Configuration File API public Object getProperty (String key); + public String getDescription (String key); public boolean setProperty (String key, Object value); public String getString (String key, String defaultValue); public int getInt (String key, int defaultValue); @@ -29,6 +30,7 @@ public interface DynamicConfigurationService { // Modules Configuration API public Object getModuleProperty (String module, String key); + public String getModuleDescription (String module, String key); public boolean setModuleProperty (String module, String key, Object value); public String getModuleString (String module, String key, String defaultValue); public int getModuleInt (String module, String key, int defaultValue); @@ -39,6 +41,7 @@ public interface DynamicConfigurationService { // Addon Configuration API public Object getAddonProperty (String addon, String key); + public String getAddonDescription (String addon, String key); public boolean setAddonProperty (String addon, String key, Object value); public String getAddonString (String addon, String key, String defaultValue); public long getAddonLong (String addon, String key, long defaultValue); diff --git a/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java b/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java index b0c75ce..c8b8b2b 100644 --- a/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java +++ b/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java @@ -296,4 +296,20 @@ public boolean addProperty(String addon, String key, Object value, } return false; } + @Override + public String getDescription(String key) { + return config.getDescription(key); + } + @Override + public String getModuleDescription(String module, String key) { + if (modulesConfig.containsKey(module)) + return modulesConfig.get(module).getDescription(key); + return null; + } + @Override + public String getAddonDescription(String addon, String key) { + if (addonsConfig.containsKey(addon)) + return addonsConfig.get(addon).getDescription(key); + return null; + } } diff --git a/impl/src/main/java/org/dspace/servicemanager/config/DSpacePropertiesConfiguration.java b/impl/src/main/java/org/dspace/servicemanager/config/DSpacePropertiesConfiguration.java index 48962f1..33b955f 100644 --- a/impl/src/main/java/org/dspace/servicemanager/config/DSpacePropertiesConfiguration.java +++ b/impl/src/main/java/org/dspace/servicemanager/config/DSpacePropertiesConfiguration.java @@ -122,4 +122,7 @@ public long getLong(String key, long defaultValue) { public boolean getBoolean(String key, boolean defaultValue) { return read.getBoolean(key, defaultValue); } + public String getDescription(String key) { + return read.getLayout().getComment(key); + } } From 96b800c1364fa7072301cc66ee4cb5977de0172a Mon Sep 17 00:00:00 2001 From: Lyncode Date: Mon, 13 Aug 2012 16:21:07 +0100 Subject: [PATCH 4/4] Creates dirs if they don't exist. --- .../servicemanager/config/DSpaceDynamicConfigurationService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java b/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java index c8b8b2b..2d93761 100644 --- a/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java +++ b/impl/src/main/java/org/dspace/servicemanager/config/DSpaceDynamicConfigurationService.java @@ -273,6 +273,7 @@ public boolean createAddonConfiguration(String addon) { String path = this.home + File.separator + DSPACE_ADDONS_CONFIG_PATH + File.separator + addon + DOT_CONFIG; try { File f = new File(path); + f.mkdirs(); f.createNewFile(); DSpacePropertiesConfiguration config = new DSpacePropertiesConfiguration(f); this.addonsConfig.put(addon, config);