Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
  
  package org.apache.marmotta.platform.core.services.config;
  
  import org.slf4j.Logger;
  
  import java.io.File;
  import java.net.URL;
  import java.util.*;
This service offers access to the system configuration of the LMF and takes care of initialising the system properly on startup.

Author(s):
Sebastian Schaffert
Sergio Fernández
  
  public class ConfigurationServiceImpl implements ConfigurationService {
  
      private String home;
  
      private static Logger log = LoggerFactory.getLogger(ConfigurationService.class);
  
      private String configFileNamemetaFileName;

    
The configuration wrapper, loads first the stored configuration and then all stored configuration options
  
      private CompositeConfiguration config;

    
The backend for storing configuration values, usually ${marmotta.home}/system-config.properties
  
      private Configuration saveConfiguration;

    
The backend for storing metadata about configuration values, usually ${marmotta.home}/system-meta.properties
  
      private Configuration saveMetadata;

    
The metadata about the configuration options
  
  
     private HashMap<StringBooleanruntimeFlags;
 
     @Inject
     @Any
 
     @Inject
     @Any
 
     @Inject
     @Any
 
     private int serverPort        = 0;
     //private String serverContext;
     private String serverName     = null;
 
     private boolean                          initialising;
     private boolean                          initialised = false;
 
     private ServletContext                   servletContext;


    
A lock to ensure proper concurrent access to the configuration. The system requests a write lock in case a setXXX() method is called and a read lock in case a getXXX() method is called.
 
     private ReadWriteLock lock;

    
Backlog for delayed event collection; only fires a configuration changed event if there has not been a further update in a specified amount of time (default 250ms);
 
     private Set<StringeventBacklog;
 
     private long EVENT_DELAY = 250L;
 
 
     /*
      * Timer and task for delayed execution of configuration changed events
      */
     private Timer          eventTimer;
     private ReentrantLock  eventLock;
 
 
     public ConfigurationServiceImpl() {
          = new HashMap<StringBoolean>();
          = new ReentrantReadWriteLock();
 
          = new Timer("Configuration Event Timer"true);
           = new ReentrantLock();
     }

    
Initialise the ConfigurationService. Takes the marmotta.home system property from the servlet init parameters (web.xml) as bootstrap home. In case a system-config.properties file is found in this directory, the configuration is then loaded from this file. In case a system-config.properties file does not yet exist, the method loads bootstrap settings from the resource default-config.properties in the classpath (in the standard bundling, the file is in the kiwi-core-XXX.jar archive). After loading the configuration, the service initialises the plugin subsystem and the SOLR home directory by unpacking the default configuration if the SOLR configuration does not yet exist.

Parameters:
override
 
     @Override
     public void initialize(String homeConfiguration override) {
         .writeLock().lock();
         try {
              = true;
 
             .info("Apache Marmotta Configuration Service starting up ...");
 
             if(isTomcat7()) {
                 .info("Apache Marmotta running on Apache Tomcat 7.x");
             } else if(isTomcat6()) {
                 .info("Apache Marmotta running on Apache Tomcat <= 6.x");
             } else if(isJetty7()) {
                 .info("Apache Marmotta running on Jetty 7.x");
             } else if(isJetty6()) {
                 .info("Apache Marmotta running on Jetty <= 6.x");
             } else {
                 .info("Apache Marmotta running on an unknown servlet container");
             }
 
             setHome(home);
 
             if (getHome() != null) {
                 File f1 = new File(getHome());
                 if (!f1.exists()) {
                     f1.mkdirs();
                 }
                 // ensure directory for user configuration files
                 File f2 = new File(getHome() + . + );
                 if(!f2.exists()) {
                     f2.mkdirs();
                 }
 
                 // ensure directory for logging messages
                 File f3 = new File(getHome() + . + );
                 if(!f3.exists()) {
                     f3.mkdirs();
                 }
 
                 // ensure directory for importing data
                 File f4 = new File(getHome() + . + );
                 if(!f4.exists()) {
                     f4.mkdirs();
                 }
 
             }
 
             // the save configuration will be in the  home directory
             try {
                 if (getHome() != null) {
                      = getHome() + . + "system-config.properties";
                      = getHome() + . + "system-meta.properties";
 
                     File configFile = new File();
                     if (!configFile.exists()) {
                         .info("creating system configuration in configuration file {}"configFile.getAbsolutePath());
                     } else {
                         .info("reading system configuration from existing configuration file {}"configFile.getAbsolutePath());
                     }
                      = new PropertiesConfiguration(configFile);
 
 
                     File metaFile = new File();
                     if (!metaFile.exists()) {
                         .info("creating system configuration metadata in configuration file {}"metaFile.getAbsolutePath());
                     } else {
                         .info("reading system configuration metadata from existing configuration file {}"metaFile.getAbsolutePath());
                     }
                      = new PropertiesConfiguration(metaFile);
 
                 } else {
                     .error("error while initialising configuration: no marmotta.home property given; creating memory-only configuration");
                      = new MapConfiguration(new HashMap<StringObject>());
                           = new MapConfiguration(new HashMap<StringObject>());
                 }
             } catch (Exception e) {
                 .error("error while initialising configuration file {}: {}; creating memory-only configuration"e.getMessage());
                  = new MapConfiguration(new HashMap<StringObject>());
                       = new MapConfiguration(new HashMap<StringObject>());
             }
              = new FallbackConfiguration();
             final ConfigurationInterpolator _int = .getInterpolator();
             _int.registerLookup("pattern.quote"new StrLookup() {
                 @Override
                 public String lookup(String key) {
                     return Pattern.quote(_int.getDefaultLookup().lookup(key));
                 }
             });
             _int.registerLookup("urlencode"new StrLookup() {
                 @Override
                 public String lookup(String key) {
                     try {
                         return URLEncoder.encode(_int.getDefaultLookup().lookup(key), "utf8");
                     } catch (UnsupportedEncodingException e) {
                         return _int.getDefaultLookup().lookup(key);
                     }
                 }
             });
             .addConfiguration(,true);
 
             // load all default-config.properties
 
             try {
                 Enumeration<URLconfigs = this.getClass().getClassLoader().getResources("config-defaults.properties");
                 while(configs.hasMoreElements()) {
                     URL url = configs.nextElement();
                     .addConfiguration(new PropertiesConfiguration(url));
                 }
 
             } catch (IOException e) {
                 .error("I/O error while loading default configurations",e);
             } catch (ConfigurationException e) {
                 .error("configuration error while loading default configurations",e);
             }
 
             // legacy support (to be removed)
             try {
                 Enumeration<URLconfigs = this.getClass().getClassLoader().getResources("default-config.properties");
                 while(configs.hasMoreElements()) {
                     URL url = configs.nextElement();
                     .addConfiguration(new PropertiesConfiguration(url));
                     .warn("found legacy configuration file {}; should be replaced with per-module configuration!",url);
                 }
 
             } catch (IOException e) {
                 .error("I/O error while loading default configurations",e);
             } catch (ConfigurationException e) {
                 .error("configuration error while loading default configurations",e);
             }
 
 
             // create the configuration that is responsible for getting metadata about configuration keys in the main
             // configuration; since the keys will be different, we store changes also to the main save configuration
              = new FallbackConfiguration();
             .addConfiguration(,true);
             try {
                 Enumeration<URLconfigs = this.getClass().getClassLoader().getResources("config-descriptions.properties");
                 while(configs.hasMoreElements()) {
                     URL url = configs.nextElement();
                     .addConfiguration(new PropertiesConfiguration(url));
                 }
 
             } catch (IOException e) {
                 .error("I/O error while loading configuration descriptions",e);
             } catch (ConfigurationException e) {
                 .error("configuration error while loading configuration descriptions",e);
             }
 
             // setup home if it is given as system property,
             // the bootstrap configuration is overwritten
             if (getHome() != null) {
                 .setProperty("marmotta.home"getHome());
             }
 
             // in case override configuration is given, change all settings in the configuration accordingly
             if(override != null) {
                 for (Iterator<Stringit = override.getKeys(); it.hasNext();) {
                     String key = it.next();
 
                     .setProperty(keyoverride.getProperty(key));
                 }
             }
 
             save();
 
             // configuration service is now ready to use
              = true;
 
 
             .fire(new LoggingStartEvent());
 
             // this should maybe move to the KiWiPreStartupFilter ...
             initDatabaseConfiguration();
 
             save();
 
             .info("Apache Marmotta Configuration Service: initialisation completed");
 
 
         } finally {
             .writeLock().unlock();
         }
 
     }
 
     @Override
     public boolean isInitialising() {
         return ;
     }

    
Signal that initialisation of the system has completed and configuration events are now enabled.

Parameters:
initialising
 
     @Override
     public void setInitialising(boolean initialising) {
         this. = initialising;
 
         .info("Initialisation completed, enabling configuration events");
     }
 
     private void initDatabaseConfiguration() {
         if (!.getBoolean("kiwi.setup.database")) {
             .info("SETUP: Setting up initial Apache Marmotta database configuration ...");
             String db_type = .getString("database.type""h2");
             .setProperty("database.h2.url""jdbc:h2:" + getHome() + "/db/marmotta;MVCC=true;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=10");
             if (db_type.equals("h2")) {
                 .setProperty("database.url""jdbc:h2:" + getHome() + "/db/marmotta;MVCC=true;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=10");
                 .setProperty("database.user""sa");
                 .setProperty("database.password""sa");
                 .setProperty("database.mode""create");
             }
             .setProperty("kiwi.setup.database"true);
         }
     }
 
     @PreDestroy
     public void shutdown() {
         .info("shutting down configuration service");
     }

    
Pass the servlet context over to the configuration service to provide runtime information about the environment to the rest of the system.

Parameters:
context
 
     @Override
     public void setServletContext(ServletContext context) {
         this. = context;
     }


    
Get the servlet context used when initialising the system

Returns:
 
     @Override
     public ServletContext getServletContext() {
         return ;
     }

    
Get the base URI out of the current request. The base URI is used e.g. to generate URIs of internal content items

 
 
     @Override
     public String getBaseUri() {
         return getStringConfiguration(.);
     }

    
Get the base path of the system, which is the relative path from the server host. For example, in the case of http://localhost:8080/LMF, /LMF would be returned as the path.

Returns:
a String representing the path
 
     @Override
     public String getPath() {
         return getStringConfiguration("kiwi.path");
     }

    
Get the server uri of the system, i.e. a uri that when entered in the browser accesses the server that runs the KiWi (and SOLR) applications. Can be used to compute the paths of other applications relative to the current application. Computed like the base uri.

 
     @Override
     public String getServerUri() {
         String serverUrl = getStringConfiguration(.);
 
         if (serverUrl.endsWith("/"))
             return serverUrl;
         else
             return serverUrl + "/";
     }

    
List all configuration keys defined for the system configuration of KiWi.

Returns:
 
     @Override
     public List<StringlistConfigurationKeys() {
         .readLock().lock();
         try {
             List<Stringkeys = new LinkedList<String>();
             for (Iterator<Stringit = .getKeys(); it.hasNext();) {
                 keys.add(it.next());
             }
             return keys;
         } finally {
             .readLock().unlock();
         }
     }

    
List all configuration keys defined for the system configuration of KiWi having prefix.

Parameters:
prefix the prefix of keys that should be returned
Returns:
 
     @Override
     public List<StringlistConfigurationKeys(String prefix) {
         .readLock().lock();
         try {
             List<Stringkeys = new LinkedList<String>();
             for (Iterator<Stringit = .getKeys(prefix); it.hasNext();) {
                 keys.add(it.next());
             }
             return keys;
         } finally {
             .readLock().unlock();
         }
     }

    
List all configuration keys matching a certain regular expression pattern. Returns a matcher object for all matching keys that can be used to access capturing groups

Parameters:
pattern
Returns:
 
     @Override
     public List<MatcherlistConfigurationKeys(Pattern pattern) {
         .readLock().lock();
         try {
             List<Matcherkeys = new LinkedList<Matcher>();
             for (Iterator<Stringit = .getKeys(); it.hasNext();) {
                 Matcher m = pattern.matcher(it.next());
                 if(m.matches()) {
                     keys.add(m);
                 }
             }
             return keys;
         } finally {
             .readLock().unlock();
         }
     }
 
     /*
          * (non-Javadoc)
          *
          * @see kiwi.api.config.ConfigurationService#isConfigurationSet(java.lang.String)
          */
     @Override
     public boolean isConfigurationSet(String key) {
         .readLock().lock();
         try {
             return .containsKey(key);
         } finally {
             .readLock().unlock();
         }
     }

    
Get the configuration for the given key. If there is no such configuration, a new one is created with empty value (returns null).

Parameters:
key unique configuration key for lookup
Returns:
a configuration object with either the configured value or null as value
 
     @Override
     public Object getConfiguration(String key) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             return .getProperty(key);
         } finally {
             .readLock().unlock();
         }
     }

    
Return the comment for the configuration with the given key as string. If there is no such configuration, null is returned

Parameters:
key unique configuration key for lookup
Returns:
a string describing the configuration option or null if no comment was given
 
     @Override
     public String getComment(String key) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             return .getString(key + ".description");
         } finally {
             .readLock().unlock();
         }
 
     }

    
Return the type for the configuration with the given key as string. If there is no such configuration, null is returned

Parameters:
key unique configuration key for lookup
Returns:
a string describing the type for key or DEFAULT_TYPE (String) if no type was given
 
     @Override
     public String getType(String key) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             String s = .getString(key+".type");
             return s!=null?sString.class.getName();
         } finally {
             .readLock().unlock();
         }
     }

    
Set the configuration "key" to the string value "value".

Parameters:
key
value
 
     @Override
     public void setConfiguration(String keyObject value) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         if(!.containsKey(key) || !ObjectUtils.equals(value,.getProperty(key))) {
             .writeLock().lock();
             try {
                 .setProperty(keyvalue);
                 save();
             } finally {
                 .writeLock().unlock();
             }
 
             if (!) {
                 raiseDelayedConfigurationEvent(Collections.singleton(key));
             }
         }
     }

    
Set type for a configuration key

Parameters:
key key for configuration fields
type type for configuratino field
 
     @Override
     public void setType(String keyString type) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .writeLock().lock();
         try {
             .setProperty(key+".type",type);
             save();
         } finally {
             .writeLock().unlock();
         }
     }

    
Set type for a configuration key

Parameters:
key key for configuration fields
description type for configuratino field
 
     @Override
     public void setComment(String keyString description) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .writeLock().lock();
         try {
             .setProperty(key+".description",description);
             save();
         } finally {
             .writeLock().unlock();
         }
     }

    
 
     @Override
     public String getStringConfiguration(String key) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             if ( instanceof AbstractConfiguration) {
                 ((AbstractConfiguration).setDelimiterParsingDisabled(true);
             }
             String result = .getString(key);
             if ( instanceof AbstractConfiguration) {
                 ((AbstractConfiguration).setDelimiterParsingDisabled(false);
             }
             return result;
         } finally {
             .readLock().unlock();
         }
     }
 
     @Override
     public String getStringConfiguration(String keyString defaultValue) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             if ( instanceof AbstractConfiguration) {
                 ((AbstractConfiguration).setDelimiterParsingDisabled(true);
             }
             String result = .getString(keydefaultValue);
             if ( instanceof AbstractConfiguration) {
                 ((AbstractConfiguration).setDelimiterParsingDisabled(false);
             }
             return result;
         } finally {
             .readLock().unlock();
         }
     }
 
     @Override
     public double getDoubleConfiguration(String key) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             return .getDouble(key, 0.0);
         } finally {
             .readLock().unlock();
         }
     }
 
     @Override
     public double getDoubleConfiguration(String keydouble defaultValue) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             return .getDouble(keydefaultValue);
         } finally {
             .readLock().unlock();
         }
     }
 
     /*
      * (non-Javadoc)
      * 
      * @see kiwi.api.config.ConfigurationService#setDoubleConfiguration(java.lang.String, double)
      */
     @Override
     public void setDoubleConfiguration(String keydouble value) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         if(!.containsKey(key) || !ObjectUtils.equals(value,.getDouble(key))) {
             .writeLock().lock();
             try {
                 .setProperty(keyvalue);
                 save();
             } finally {
                 .writeLock().unlock();
             }
 
             if (!) {
                 raiseDelayedConfigurationEvent(Collections.singleton(key));
             }
         }
     }
 
     @Override
     public int getIntConfiguration(String key) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState("ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             return .getInt(key, 0);
         } finally {
             .readLock().unlock();
         }
     }
 
     @Override
     public int getIntConfiguration(String keyint defaultValue) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             return .getInt(keydefaultValue);
         } finally {
             .readLock().unlock();
         }
     }
 
     /*
      * (non-Javadoc)
      * 
      * @see kiwi.api.config.ConfigurationService#setIntConfiguration(java.lang.String, int)
      */
     @Override
     public void setIntConfiguration(String keyint value) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         if(!.containsKey(key) || !ObjectUtils.equals(value,.getInt(key))) {
             .writeLock().lock();
             try {
                 .setProperty(keyvalue);
                 save();
             } finally {
                 .writeLock().unlock();
             }
 
             if (!) {
                 raiseDelayedConfigurationEvent(Collections.singleton(key));
             }
         }
     }


    
Get the configuration for the given key. If there is no such configuration, 0 is returned

Parameters:
key unique configuration key for lookup
Returns:
a int value with either the configured value or 0
 
     @Override
     public long getLongConfiguration(String key) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState("ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             return .getLong(key, 0);
         } finally {
             .readLock().unlock();
         }
     }

    
Get the configuration for the given key. If there is no such configuration, a new one is created using the provided defaultValue as double value.

Parameters:
key unique configuration key for lookup
defaultValue default value if configuration not found
Returns:
a configuration object with either the configured value or defaultValue
 
     @Override
     public long getLongConfiguration(String keylong defaultValue) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             return .getLong(keydefaultValue);
         } finally {
             .readLock().unlock();
         }
     }

    
Set the system configuration with the given key to the given int value.

Parameters:
key
value
 
     @Override
     public void setLongConfiguration(String keylong value) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         if(!.containsKey(key) || !ObjectUtils.equals(value,.getLong(key))) {
             .writeLock().lock();
             try {
                 .setProperty(keyvalue);
                 save();
             } finally {
                 .writeLock().unlock();
             }
 
             if (!) {
                 raiseDelayedConfigurationEvent(Collections.singleton(key));
             }
         }
     }
 
     @Override
     public boolean getBooleanConfiguration(String key) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             return .getBoolean(keyfalse);
         } finally {
             .readLock().unlock();
         }
 
     }
 
     @Override
     public boolean getBooleanConfiguration(String keyboolean defaultValue) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             return .getBoolean(keydefaultValue);
         } finally {
             .readLock().unlock();
         }
 
     }
 
     /*
      * (non-Javadoc)
      * 
      * @see kiwi.api.config.ConfigurationService#setIntConfiguration(java.lang.String, int)
      */
     @Override
     public void setBooleanConfiguration(String keyboolean value) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         if(!.containsKey(key) || value != .getBoolean(key)) {
 
             .writeLock().lock();
             try {
                 .setProperty(keyvalue);
                 save();
             } finally {
                 .writeLock().unlock();
             }
 
 
             if (!) {
                 raiseDelayedConfigurationEvent(Collections.singleton(key));
             }
         }
     }
 
     /*
      * (non-Javadoc)
      * 
      * @see kiwi.api.config.ConfigurationService#getListConfiguration(java.lang.String)
      */
     @Override
     public Properties getPropertiesConfiguration(String key) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             return .getProperties(key);
         } finally {
             .readLock().unlock();
         }
 
     }
 
     /*
      * (non-Javadoc)
      * 
      * @see kiwi.api.config.ConfigurationService#getListConfiguration(java.lang.String)
      */
     @Override
     public List<StringgetListConfiguration(String key) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             String[] result = .getStringArray(key);
 
             if (result.length == 1 && "".equals(result[0].trim())) return Collections.emptyList();
 
             return Lists.newArrayList(result);
         } finally {
             .readLock().unlock();
         }
 
     }
 
     /*
      * (non-Javadoc)
      * 
      * @see kiwi.api.config.ConfigurationService#getListConfiguration(java.lang.String,
      * java.util.List)
      */
     @Override
     public List<StringgetListConfiguration(String keyList<StringdefaultValue) {
         Preconditions.checkNotNull(key);
         Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
 
         .readLock().lock();
         try {
             if (.containsKey(key)) {
                 String[] values = .getStringArray(key);
                 if (values.length > 0) return Lists.newArrayList(values);
                 else
                     return Lists.newArrayList();
             } else
                 return defaultValue;
         } finally {
             .readLock().unlock();
         }
 
     }
 
     /*
      * (non-Javadoc)
      * 
      * @see kiwi.api.config.ConfigurationService#setListConfiguration(java.lang.String,
     * java.util.List)
     */
    @Override
    public void setListConfiguration(String keyList<Stringvalue) {
        Preconditions.checkNotNull(key);
        Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
        if(!.containsKey(key) || !ObjectUtils.equals(value,.getList(key))) {
            .writeLock().lock();
            try {
                .setProperty(keyvalue);
                save();
            } finally {
                .writeLock().unlock();
            }
            if (!) {
                .debug("firing configuration changed event for key {}"key);
                raiseDelayedConfigurationEvent(Collections.singleton(key));
            }
        }
    }
    @Override
    public void removeConfiguration(String key) {
        Preconditions.checkNotNull(key);
        Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
        .writeLock().lock();
        try {
            .clearProperty(key);
            .clearProperty(key+".type");
            .clearProperty(key+".description");
            save();
        } finally {
            .writeLock().unlock();
        }
    }
    @Override
    public void setConfiguration(String keyString value) {
        Preconditions.checkNotNull(key);
        Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
        .debug("setting configuration {} = {}"keyvalue);
        if(!.containsKey(key) || !ObjectUtils.equals(value,.getString(key))) {
            .writeLock().lock();
            try {
                if ( instanceof AbstractConfiguration) {
                    ((AbstractConfiguration).setDelimiterParsingDisabled(true);
                }
                .setProperty(keyvalue);
                if ( instanceof AbstractConfiguration) {
                    ((AbstractConfiguration).setDelimiterParsingDisabled(false);
                }
                save();
            } finally {
                .writeLock().unlock();
            }
            if (!) {
                .debug("firing configuration changed event for key {}"key);
                raiseDelayedConfigurationEvent(Collections.singleton(key));
            }
        }
    }

    
Set a configuration value without firing an event. This is in rare cases needed to avoid propagation of events.

Parameters:
key
value
    @Override
    public void setConfigurationWithoutEvent(String keyObject value) {
        Preconditions.checkNotNull(key);
        Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
        .writeLock().lock();
        try {
            if ( instanceof AbstractConfiguration) {
                ((AbstractConfiguration).setDelimiterParsingDisabled(true);
            }
            .setProperty(keyvalue);
            if ( instanceof AbstractConfiguration) {
                ((AbstractConfiguration).setDelimiterParsingDisabled(false);
            }
            save();
        } finally {
            .writeLock().unlock();
        }
    }
    @Override
    public void setConfigurations(Map<String, ?> values) {
        Preconditions.checkNotNull(values);
        Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
        .writeLock().lock();
        try {
            if ( instanceof AbstractConfiguration) {
                ((AbstractConfiguration).setDelimiterParsingDisabled(true);
            }
            for (Map.Entry<String, ?> entry : values.entrySet()) {
                .setProperty(entry.getKey(), entry.getValue());
            }
            if ( instanceof AbstractConfiguration) {
                ((AbstractConfiguration).setDelimiterParsingDisabled(false);
            }
            save();
        } finally {
            .writeLock().unlock();
        }
        if (!) {
            raiseDelayedConfigurationEvent((values.keySet()));
        }
    }
    @Override
    public void setConfiguration(String keyList<Stringvalues) {
        Preconditions.checkNotNull(key);
        Preconditions.checkState(,"ConfigurationService not yet initialised; call initialise() manually");
        if(!.containsKey(key) || !ObjectUtils.equals(values,.getList(key))) {
            .writeLock().lock();
            try {
                .setProperty(keyvalues);
                save();
            } finally {
                .writeLock().unlock();
            }
            if (!) {
                raiseDelayedConfigurationEvent(Collections.singleton(key));
            }
        }
    }

    
The work directory for marmotta, where all applications will create their own subdirectories

Deprecated:
This name is misleading, use getHome() instead.
    @Override
    public String getWorkDir() {
        return getHome();
    }