/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/kernel/trunk/component-manager/src/main/java/org/sakaiproject/component/api/ServerConfigurationService.java $
* $Id: ServerConfigurationService.java 122219 2013-04-04 21:01:10Z azeckoski@unicon.net $
***********************************************************************************
*
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 Sakai Foundation
*
* Licensed under the Educational Community 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.opensource.org/licenses/ECL-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.sakaiproject.component.api;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.sakaiproject.component.locales.SakaiLocales;
/**
* <p>
* ServerConfigurationService provides information about how the server is configured.
* </p>
*/
public interface ServerConfigurationService
{
/** This string can be used to find the service in the service manager. */
public static final String SERVICE_NAME = ServerConfigurationService.class.getName();
/** Key in the ThreadLocalManager for the serverUrl based on the current request. */
final static String CURRENT_SERVER_URL = "sakai:request.server.url";
/** Key in the ThreadLocalManager for the path based on the current request. */
final static String CURRENT_PORTAL_PATH = "sakai:request.portal.path";
/**
* Access the unique (to the cluster) id of the server.
*
* @return The unique (to the cluster) id of the server.
*/
String getServerId();
/**
* Access the unique (to the cluster) instance id of the server.
*
* @return The unique (to the cluster) instance id of the server.
*/
String getServerInstance();
/**
* Access the combined server / instance id.
*
* @return The combined server / instance id.
*/
String getServerIdInstance();
/**
* Access the server DNS name.
*
* @return The server DNS name.
*/
String getServerName();
/**
* Access the URL to the root of the server - append any additional path to the end.
*
* @return The URL to the root of the server.
*/
String getServerUrl();
/**
* Access the URL to the help service on the server - append in the path the tool well known id for context sensitive help.
*
* @param helpContext
* The context string.
* @return The URL to the help service on the server.
*/
String getHelpUrl(String helpContext);
/**
* Access the URL to the access service on the server - append any additional path to the end.
*
* @return The URL to the access service on the server.
*/
String getAccessUrl();
/**
* Access the path to the access service on the server relative to the base URL for the server.
*
* @return The path to the access service on the server.
*/
String getAccessPath();
/**
* Access the URL to the portal service on the server - append any additional path to the end.
*
* @return The URL to the portal service on the server.
*/
String getPortalUrl();
/**
* Access the URL to the tool dispatcher service on the server - append any additional path to the end.
*
* @return The URL to the tool dispatcher service on the server.
*/
String getToolUrl();
/**
* Access the site id for the gateway (public) site.
*
* @return The site id for the gateway (public) site.
*/
String getGatewaySiteId();
/**
* Access the URL to use as a redirect when the user has logged out.
*
* @return The URL to use as a redirect when the user has logged out.
*/
String getLoggedOutUrl();
/**
* Access the URL to the user's "home" (My Workspace) in the service.
*
* @return The URL to the user's "home" (My Workspace) in the service.
*/
String getUserHomeUrl();
/**
* Access the file path to the "sakai home" on the app server.
*
* @return The file path to the "sakai home" on the app server.
*/
String getSakaiHomePath();
/**
* Access some named configuration value as a string.
* 1) IF "name=value" THEN this will return "value"
* 2) IF "name=" THEN this will return null
* 3) IF name is not defined in the config THEN this will return "" (empty string)
*
* @param name The configuration value name (or key).
* @return The configuration value for this name OR null if defined as 'blank' OR "" (empty string) if not defined.
*/
String getString(String name);
/**
* Access some named configuration value as a string.
* 1) IF "name=value" THEN this will return "value"
* 2) IF "name=" THEN this will return null
* 3) IF name is not defined in the config THEN this will return the provided default value
*
* @param name The configuration value name (or key).
* @param dflt The value to return if not found in the config.
* @return The configuration value for this name OR null if defined as 'blank' OR default value if not defined.
*/
String getString(String name, String dflt);
/**
* Access some named configuration values as an array of strings.
* There are 2 ways this is indicated in the system:
* 1) The name is the base name. name + ".count" must be defined to be a positive integer - how many are defined. name + "." + i (1..count) must be defined to be the values.
* 2) A comma delimited list of values: name=val1,val2,val3
* If count is 0 or the value is empty then an empty string array is the resulting return value.
* Null is returned ONLY in the case the value cannot be found at all.
*
* @param name
* The configuration value name base.
* @return The configuration value with this name, empty array if no values or count=0, OR null if config name is not found.
*/
String[] getStrings(String name);
/**
* Access some named configuration value as an int.
*
* @param name
* The configuration value name.
* @param dflt
* The value to return if not found.
* @return The configuration value with this name, or the default value if not found.
*/
int getInt(String name, int dflt);
/**
* Access some named configuration value as a boolean.
*
* @param name
* The configuration value name.
* @param dflt
* The value to return if not found.
* @return The configuration value with this name, or the default value if not found.
*/
boolean getBoolean(String name, boolean dflt);
/**
* Access the undereferenced value of the given property. That is,
* Spring-style property placeholders will not be expanded as
* they would be in other getters on this interface. For example,
* consider the following configuration:
*
* <pre>
* <code>
* property1=foo
* property2=${property1}
* </code>
* </pre>
*
* <p>Invoking {@link #getString(String)}, passing <code>"property2"</code>
* will return <code>"foo"</code>. However, invoking this method
* with the same argument will return <code>"${property1}"</code>.</p>
*
* <p>Typically, a client of this method, e.g. a dynamic
* configuration management tool, is interested in reporting on the system's
* actual state from which return values of other getters are calculated.
* In such cases, caller-specified default values have no utility. Thus this
* method does not accept an argument specifying the property's default value.</p>
*
* <p>For a given undefined property "X", this method should return
* exactly the same value as <code>getString("X")</code>. Thus it may
* not be possible in all cases to distinguish between defined and
* undefined properties.</p>
*
* @param name a property name. Must not be <code>null</code>
* @return the property value. Property placeholders will not have
* been dereferenced. The value representing an non-existent property
* is implementation dependent.
*/
String getRawProperty(String name);
/**
* KNL-989
* Access the list of tools by group
*
* @param category
* The tool category
* @return An unordered list of tool ids (String) in selected group, or an empty list if there are none for this category.
*/
List<String> getToolGroup(String category);
/**
* KNL-989
* Access the list of tool ids in order for this category, to impose on the displays of many tools
*
* @param category Site type
* @return An unordered list of group names (String), or an empty list if there are none for this category.
*/
List<String> getToolOrder(String category);
/**
* KNL-989
* Returns true if selected tool is contained in pre-initialized list of selected items
* @parms toolId id of the selected tool
*/
public boolean toolGroupIsSelected(String groupName, String toolId) ;
/**
* KNL-989
* Returns true if selected tool is contained in pre-initialized list of required items
* @parms toolId id of the selected tool
*/
public boolean toolGroupIsRequired(String groupName, String toolId);
/**
* KNL-989
* Access the list of groups by category (site type)
*
* @param category
* The tool category
* @return An ordered list of tool ids (String) indicating the desired tool display order, or an empty list if there are none for this category.
*/
List<String> getCategoryGroups(String category);
/**
* Access the list of tool ids that are required for this category.
*
* @param category
* The tool category.
* @return A list of tool ids (String) that are required for this category, or an empty list if there are none for this category.
*/
List<String> getToolsRequired(String category);
/**
* Access the list of tool ids that are selected by default for this category.
*
* @param category
* The tool category.
* @return A list of tool ids (String) for this category to use by default, or an empty list if there are none for this category.
*/
List<String> getDefaultTools(String category);
/**
* access the list of tool categories for the given site type
*
* @param category the site type
* @return a list of tool category ids in order
*/
List<String> getToolCategories(String category);
/**
* access the map of tool categories to tool ids for this site type
* @param category the site type
* @return a map of tool category ids to tool ids
*/
Map<String, List<String>> getToolCategoriesAsMap(String category);
/**
* access a map of tool id to tool category id for this site type
* @param category the site type
* @return map with tool id as key and category id as value
*/
Map<String, String> getToolToCategoryMap(String category);
/**
* Get the list of allowed locales as controlled by config params for "locales" and "locales.more"
* Defaults when nothing is specified in the config files come from {@link SakaiLocales#SAKAI_LOCALES_DEFAULT}
* @return an array of all allowed Locales for this installation
* @see SakaiLocales
*/
public Locale[] getSakaiLocales();
/**
* Parse a string into a Locale
* @return Locale based on its string representation (language_region) OR default Locale if the string cannot be parsed
*/
public Locale getLocaleFromString(String localeString);
// improved methods
public static final String UNKNOWN = "UNKNOWN";
public static final String TYPE_BOOLEAN = "boolean";
public static final String TYPE_INT = "int";
public static final String TYPE_ARRAY = "array";
public static final String TYPE_STRING = "string";
public static final String[] TYPES = {
TYPE_BOOLEAN,
TYPE_INT,
TYPE_ARRAY,
TYPE_STRING,
UNKNOWN
};
/**
* Retrieves config values from the configuration service
*
* @param name the name of the setting to retrieve, Should be a string name: e.g. auto.ddl,
* mystuff.config, etc.
* @param defaultValue a specified default value to return if this setting cannot be found,
* <b>NOTE:</b> You can set the default value to null but you must specify the class type in parens
* @return the value of the configuration setting OR the default value if none can be found
*/
public <T> T getConfig(String name, T defaultValue);
/**
* Retrieve the internally stored the config item,
* this is not really for general use, if you want the value of a configuration variable then
* you should use {@link #getConfig(String, Object)}
*
* @param name the name of the setting to retrieve, Should be a string name: e.g. auto.ddl,
* mystuff.config, etc.
* @return the config item OR null if none exists
*/
public ConfigItem getConfigItem(String name);
/**
* Register a configuration item (or override an existing config),
* this should be called when changing or creating a configuration setting
*
* @param configItem an instance of the {@link ConfigItem} interface with the name, value, source params set,
* use {@link BasicConfigItem} as an easy way to construct a {@link ConfigItem}
* @return the registered {@link ConfigItem}
* @throws IllegalArgumentException if the {@link ConfigItem} is not valid (does not have all required fields set)
*/
public ConfigItem registerConfigItem(ConfigItem configItem);
/**
* Register a listener which will be notified whenever there is a configuration setting change,
* there is no need to unregister a listener as all listener references will be held weakly
* (if there are no more variables which reference the listener then it will be GCed and removed from the list of listeners)
*
* Registering the same {@link ConfigurationListener} object multiple times has no effect
*
* @param configurationListener a {@link ConfigurationListener} object
*/
public void registerListener(ConfigurationListener configurationListener);
/**
* Returns data about all the configuration values which are known
* to the system at the time and some stats which are useful
*
* @return a config data class with data about the known configuration values
*/
public ConfigData getConfigData();
// STATICS
/**
* Defines the config data holding class
*/
public static interface ConfigData {
/**
* @return the total number of config items known to the service
*/
public int getTotalConfigItems();
/**
* @return the total number of registered config items known to the service
*/
public int getRegisteredConfigItems();
/**
* @return the total number of requested but not registered config items known to the service
*/
public int getUnRegisteredConfigItems();
/**
* @return the array of all current source names
*/
public String[] getSources();
/**
* @return the total set of all known config items
*/
public List<ConfigItem> getItems();
}
/**
* Defines the config item holding class
*/
public static interface ConfigItem {
/**
* Called whenever this config item is requested
* @return the current number of times requested
*/
public int requested();
/**
* Called whenever this config item is changed
* @param value the new value
* @param source the source which is making the change
* @return the current number of times the item was changed
*/
public int changed(Object value, String source);
/**
* Duplicate this config item
* This is mostly used to ensure we do not send the internal objects out where they could be changed
* @return a config item with all the same values
*/
public ConfigItem copy();
/**
* @return the name/key for this configuration value
*/
public String getName();
/**
* @return the actual stored value for this config (null indicates it is not set)
*/
public Object getValue();
/**
* @return the type of the value (string, int, boolean, array) - from {@link ServerConfigurationService#TYPES}
*/
public String getType();
/**
* @return the name of the most recent source for this config value (e.g. sakai/sakai.properties)
*/
public String getSource();
/**
* @return the default value for this config (null indicates it is not set)
*/
public Object getDefaultValue();
/**
* @return the human readable description of this configuration value
*/
public String getDescription();
/**
* @return the number of times the config value was requested (or looked up)
*/
public int getRequested();
/**
* @return the number of times this config value was changed (or updated)
*/
public int getChanged();
/**
* @return the version of this config item (a newly created item is version 1), incremented with each change
*/
public int getVersion();
/**
* @return the history of the config item over time (empty array if it has never changed)
*/
public ConfigHistory[] getHistory();
/**
* @return indicates if this config is registered (true) or if it is only requested (false)
* (requested means someone asked for it but the setting has not been stored in the config service)
*/
public boolean isRegistered();
/**
* @return indicates is this config is has a default value defined
* (this can only be known for items which are requested)
*/
public boolean isDefaulted();
/**
* @return indicates is this config value should not be revealed because there are security implications
*/
public boolean isSecured();
/**
* Indicates is this config item is dynamic or static (default is static)
* @return true is this config can be modified at runtime (dynamic), false if runtime changes are not allowed (static)
*/
public boolean isDynamic();
}
/**
* Defines the config item history class
*/
public static interface ConfigHistory {
/**
* @return the version of the config item this history refers to (a newly created item is version 1)
*/
public int getVersion();
/**
* @return the time at which this historical version of the config item became irrelevant (this is when this version was replaced)
*/
public long getTimestamp();
/**
* @return the source name for this version of the config item
*/
public String getSource();
/**
* @return the value of the config item in this version of it
*/
public Object getValue();
}
/**
* Allows registration of configuration settings (config items) from outside the
* Server Configuration Service and the standard set of properties files which
* will be loaded early on the configuration cycle
*
* NOTE: the implemented ConfigurationProvider MUST be a Spring singleton and it
* MUST be registered in the main Sakai application context from a component (from a webapp will not work),
* it also must be set explicitly to not lazy initialize (lazy-init="false"),
* it is always possible to update the configuration later using {@link #registerConfigItems(ConfigData)}
* so this is mainly for loading configurations very early in the system startup
*/
public static interface ConfigurationProvider {
/* This is part of supporting a more flexible and persistent configuration -AZ
*/
/**
* Register a set of configuration items,
* these will be loaded after the base properties are loaded (from properties files)
* but before the rest of Sakai starts up so they will be allowed to override the base properties
* @param configData the set of current config data that currently exists
* @return a list of ConfigItems which will be loaded into the current configuration,
* these MUST have the name, value (OR defaultValue), and source set to non-null/non-empty values,
* use {@link BasicConfigItem} as an easy way to ensure the configitems are setup correctly
*/
public List<ConfigItem> registerConfigItems(ConfigData configData);
}
/**
* Allows a service to be notified when configuration settings are changed,
* It is up to the implementor to ignore the changes they do not care about.
* Filter on the {@link ConfigItem#getName()}.
*
* NOTE: this does NOT include any changes which happen during the initial properties file loading
*/
public static interface ConfigurationListener {
/* This is part of supporting a more flexible and persistent configuration -AZ
*/
/**
* This will be called each time a {@link ConfigItem} is changed,
* this will be called before the item has been changed and will reflect
* the current values for this config item.
* NOTE: the default implementation of this should be to just return null
* if processing should be allowed to continue unimpeded
*
* NOTE: it does NOT include the the initial registration of that config item and
* initial startup of the {@link ServerConfigurationService}
*
* @param currentConfigItem the {@link ConfigItem} which is changing (will be null if item is new),
* this item should not be changed by this method
* @param newConfigItem the {@link ConfigItem} which will become the new one
* @return null to allow processing to continue as usual
* OR instance of {@link BlockingConfigItem} to block the change from happening (change will be discarded and processing will stop)
* OR the modified newConfigItem item which will be used as the new config value
*/
public ConfigItem changing(ConfigItem currentConfigItem, ConfigItem newConfigItem);
/**
* This will be called each time a {@link ConfigItem} is changed,
* this will be called after the item has been changed and will reflect the new values
* for this config item
*
* NOTE: it does NOT include the the initial registration of that config item and
* initial startup of the {@link ServerConfigurationService}
*
* @param configItem the {@link ConfigItem} which changed,
* this item should not be changed by this method
* @param previousConfigItem the {@link ConfigItem} before the change (will be null if item is new)
*/
public void changed(ConfigItem configItem, ConfigItem previousConfigItem);
/**
* This is a special marker class that is used in the {@link ServerConfigurationService.ConfigurationListener},
* returning this indicates that the config change should stop processing the change and retain the original value
*/
public static class BlockingConfigItem implements ConfigItem {
public static BlockingConfigItem instance() {
return new BlockingConfigItem();
}
/**
* SPECIAL marker class, indicates that the config change should stop processing the change and retain the original value
*/
public BlockingConfigItem() {}
public int requested() {
return 0;
}
public int changed(Object value, String source) {
return 0;
}
public ConfigItem copy() {
return new BlockingConfigItem();
}
public String getName() {
return "BLOCKING";
}
public Object getValue() {
return null;
}
public String getType() {
return "BLOCKING";
}
public String getDescription() {
return null;
}
public String getSource() {
return null;
}
public Object getDefaultValue() {
return null;
}
public int getRequested() {
return 0;
}
public int getChanged() {
return 0;
}
public int getVersion() {
return 0;
}
public ConfigHistory[] getHistory() {
return null;
}
public boolean isRegistered() {
return false;
}
public boolean isDefaulted() {
return false;
}
public boolean isSecured() {
return false;
}
public boolean isDynamic() {
return false;
}
}
}
}