blob: 97777d051a438826378ca5b9e3d7744e3fb86aed [file] [log] [blame]
package org.apache.archiva.configuration;
/*
* 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.
*/
import org.apache.archiva.configuration.functors.ProxyConnectorConfigurationOrderComparator;
import org.apache.archiva.configuration.io.registry.ConfigurationRegistryReader;
import org.apache.archiva.configuration.io.registry.ConfigurationRegistryWriter;
import org.apache.archiva.policies.AbstractUpdatePolicy;
import org.apache.archiva.policies.CachedFailuresPolicy;
import org.apache.archiva.policies.ChecksumPolicy;
import org.apache.archiva.components.evaluator.DefaultExpressionEvaluator;
import org.apache.archiva.components.evaluator.EvaluatorException;
import org.apache.archiva.components.evaluator.ExpressionEvaluator;
import org.apache.archiva.components.evaluator.sources.SystemPropertyExpressionSource;
import org.apache.archiva.components.registry.Registry;
import org.apache.archiva.components.registry.RegistryException;
import org.apache.archiva.components.registry.RegistryListener;
import org.apache.archiva.components.registry.commons.CommonsConfigurationRegistry;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.Map.Entry;
/**
* <p>
* Implementation of configuration holder that retrieves it from the registry.
* </p>
* <p>
* The registry layers and merges the 2 configuration files: user, and application server.
* </p>
* <p>
* Instead of relying on the model defaults, if the registry is empty a default configuration file is loaded and
* applied from a resource. The defaults are not loaded into the registry as the lists (eg repositories) could no longer
* be removed if that was the case.
* </p>
* <p>
* When saving the configuration, it is saved to the location it was read from. If it was read from the defaults, it
* will be saved to the user location.
* However, if the configuration contains information from both sources, an exception is raised as this is currently
* unsupported. The reason for this is that it is not possible to identify where to re-save elements, and can result
* in list configurations (eg repositories) becoming inconsistent.
* </p>
* <p>
* If the configuration is outdated, it will be upgraded when it is loaded. This is done by checking the version flag
* before reading it from the registry.
* <p>
* FIXME: The synchronization must be improved, the current impl may lead to inconsistent data or multiple getConfiguration() calls (martin_s@apache.org)
* </p>
*/
@Service("archivaConfiguration#default")
public class DefaultArchivaConfiguration
implements ArchivaConfiguration, RegistryListener {
private final Logger log = LoggerFactory.getLogger(DefaultArchivaConfiguration.class);
private static String FILE_ENCODING = "UTF-8";
/**
* Plexus registry to read the configuration from.
*/
@Inject
@Named(value = "commons-configuration")
private Registry registry;
/**
* The configuration that has been converted.
*/
private Configuration configuration;
/**
* see #initialize
* default-value="${user.home}/.m2/archiva.xml"
*/
private String userConfigFilename = "${user.home}/.m2/archiva.xml";
/**
* see #initialize
* default-value="${appserver.base}/conf/archiva.xml"
*/
private String altConfigFilename = "${appserver.base}/conf/archiva.xml";
/**
* Configuration Listeners we've registered.
*/
private Set<ConfigurationListener> listeners = new HashSet<>();
/**
* Registry Listeners we've registered.
*/
private Set<RegistryListener> registryListeners = new HashSet<>();
/**
* Boolean to help determine if the configuration exists as a result of pulling in
* the default-archiva.xml
*/
private boolean isConfigurationDefaulted = false;
private static final String KEY = "org.apache.archiva";
// Section used for default only configuration
private static final String KEY_DEFAULT_ONLY = "org.apache.archiva_default";
private Locale defaultLocale = Locale.getDefault();
private List<Locale.LanguageRange> languagePriorities = new ArrayList<>();
private volatile Path dataDirectory;
private volatile Path repositoryBaseDirectory;
private volatile Path remoteRepositoryBaseDirectory;
private volatile Path repositoryGroupBaseDirectory;
@PostConstruct
private void init() {
languagePriorities = Locale.LanguageRange.parse("en,fr,de");
}
@Override
public Configuration getConfiguration() {
return loadConfiguration();
}
private synchronized Configuration loadConfiguration() {
if (configuration == null) {
configuration = load();
configuration = unescapeExpressions(configuration);
if (isConfigurationDefaulted) {
configuration = checkRepositoryLocations(configuration);
}
}
return configuration;
}
private boolean hasConfigVersionChanged(Configuration current, Registry defaultOnlyConfiguration) {
return current == null || current.getVersion() == null ||
!current.getVersion().trim().equals(defaultOnlyConfiguration.getString("version", "").trim());
}
@SuppressWarnings("unchecked")
private Configuration load() {
// TODO: should this be the same as section? make sure unnamed sections still work (eg, sys properties)
Registry subset = registry.getSubset(KEY);
if (subset.getString("version") == null) {
if (subset.getSubset("repositoryScanning").isEmpty()) {
// only for empty
subset = readDefaultConfiguration();
} else {
throw new RuntimeException("No version tag found in configuration. Archiva configuration version 1.x is not longer supported.");
}
}
Configuration config = new ConfigurationRegistryReader().read(subset);
// Resolving data and repositories directories
// If the config entries are absolute, the path is used as it is
// if the config entries are empty, they are resolved:
// dataDirectory = ${appserver.base}/data
// repositoryDirectory = ${dataDirectory}/repositories
// If the entries are relative they are resolved
// relative to the appserver.base, for dataDirectory
// relative to dataDirectory for repositoryBase
String dataDir = config.getArchivaRuntimeConfiguration().getDataDirectory();
if (StringUtils.isEmpty(dataDir)) {
dataDirectory = getAppServerBaseDir().resolve("data");
} else {
Path tmpDataDir = Paths.get(dataDir);
if (tmpDataDir.isAbsolute()) {
dataDirectory = tmpDataDir;
} else {
dataDirectory = getAppServerBaseDir().resolve(tmpDataDir);
}
}
config.getArchivaRuntimeConfiguration().setDataDirectory(dataDirectory.normalize().toString());
String repoBaseDir = config.getArchivaRuntimeConfiguration().getRepositoryBaseDirectory();
if (StringUtils.isEmpty(repoBaseDir)) {
repositoryBaseDirectory = dataDirectory.resolve("repositories");
} else {
Path tmpRepoBaseDir = Paths.get(repoBaseDir);
if (tmpRepoBaseDir.isAbsolute()) {
repositoryBaseDirectory = tmpRepoBaseDir;
} else {
dataDirectory.resolve(tmpRepoBaseDir);
}
}
String remoteRepoBaseDir = config.getArchivaRuntimeConfiguration().getRemoteRepositoryBaseDirectory();
if (StringUtils.isEmpty(remoteRepoBaseDir)) {
remoteRepositoryBaseDirectory = dataDirectory.resolve("remotes");
} else {
Path tmpRemoteRepoDir = Paths.get(remoteRepoBaseDir);
if (tmpRemoteRepoDir.isAbsolute()) {
remoteRepositoryBaseDirectory = tmpRemoteRepoDir;
} else {
dataDirectory.resolve(tmpRemoteRepoDir);
}
}
String repositoryGroupBaseDir = config.getArchivaRuntimeConfiguration().getRepositoryGroupBaseDirectory();
if (StringUtils.isEmpty(repositoryGroupBaseDir)) {
repositoryGroupBaseDirectory = dataDirectory.resolve("groups");
} else {
Path tmpGroupDir = Paths.get(repositoryGroupBaseDir);
if (tmpGroupDir.isAbsolute()) {
repositoryGroupBaseDirectory = tmpGroupDir;
} else {
dataDirectory.resolve(tmpGroupDir);
}
}
config.getRepositoryGroups();
config.getRepositoryGroupsAsMap();
if (!CollectionUtils.isEmpty(config.getRemoteRepositories())) {
List<RemoteRepositoryConfiguration> remoteRepos = config.getRemoteRepositories();
for (RemoteRepositoryConfiguration repo : remoteRepos) {
// [MRM-582] Remote Repositories with empty <username> and <password> fields shouldn't be created in configuration.
if (StringUtils.isBlank(repo.getUsername())) {
repo.setUsername(null);
}
if (StringUtils.isBlank(repo.getPassword())) {
repo.setPassword(null);
}
}
}
if (!config.getProxyConnectors().isEmpty()) {
// Fix Proxy Connector Settings.
// Create a copy of the list to read from (to prevent concurrent modification exceptions)
List<ProxyConnectorConfiguration> proxyConnectorList = new ArrayList<>(config.getProxyConnectors());
// Remove the old connector list.
config.getProxyConnectors().clear();
for (ProxyConnectorConfiguration connector : proxyConnectorList) {
// Fix policies
boolean connectorValid = true;
Map<String, String> policies = new HashMap<>();
// Make copy of policies
policies.putAll(connector.getPolicies());
// Clear out policies
connector.getPolicies().clear();
// Work thru policies. cleaning them up.
for (Entry<String, String> entry : policies.entrySet()) {
String policyId = entry.getKey();
String setting = entry.getValue();
// Upgrade old policy settings.
if ("releases".equals(policyId) || "snapshots".equals(policyId)) {
if ("ignored".equals(setting)) {
setting = AbstractUpdatePolicy.ALWAYS.getId();
} else if ("disabled".equals(setting)) {
setting = AbstractUpdatePolicy.NEVER.getId();
}
} else if ("cache-failures".equals(policyId)) {
if ("ignored".equals(setting)) {
setting = CachedFailuresPolicy.NO.getId();
} else if ("cached".equals(setting)) {
setting = CachedFailuresPolicy.YES.getId();
}
} else if ("checksum".equals(policyId)) {
if ("ignored".equals(setting)) {
setting = ChecksumPolicy.IGNORE.getId();
}
}
// Validate existance of policy key.
connector.addPolicy(policyId, setting);
}
if (connectorValid) {
config.addProxyConnector(connector);
}
}
// Normalize the order fields in the proxy connectors.
Map<String, java.util.List<ProxyConnectorConfiguration>> proxyConnectorMap =
config.getProxyConnectorAsMap();
for (List<ProxyConnectorConfiguration> connectors : proxyConnectorMap.values()) {
// Sort connectors by order field.
Collections.sort(connectors, ProxyConnectorConfigurationOrderComparator.getInstance());
// Normalize the order field values.
int order = 1;
for (ProxyConnectorConfiguration connector : connectors) {
connector.setOrder(order++);
}
}
}
this.defaultLocale = Locale.forLanguageTag(config.getArchivaRuntimeConfiguration().getDefaultLanguage());
this.languagePriorities = Locale.LanguageRange.parse(config.getArchivaRuntimeConfiguration().getLanguageRange());
return config;
}
/*
* Updates the checkpath list for repositories.
*
* We are replacing existing ones and adding new ones. This allows to update the list with new releases.
*
* We are also updating existing remote repositories, if they exist already.
*
* This update method should only be called, if the config version changes to avoid overwriting
* user repository settings all the time.
*/
private void updateCheckPathDefaults(Configuration config, Registry defaultConfiguration) {
List<RepositoryCheckPath> existingCheckPathList = config.getArchivaDefaultConfiguration().getDefaultCheckPaths();
HashMap<String, RepositoryCheckPath> existingCheckPaths = new HashMap<>();
HashMap<String, RepositoryCheckPath> newCheckPaths = new HashMap<>();
for (RepositoryCheckPath path : config.getArchivaDefaultConfiguration().getDefaultCheckPaths()) {
existingCheckPaths.put(path.getUrl(), path);
}
List defaultCheckPathsSubsets = defaultConfiguration.getSubsetList("archivaDefaultConfiguration.defaultCheckPaths.defaultCheckPath");
for (Iterator i = defaultCheckPathsSubsets.iterator(); i.hasNext(); ) {
RepositoryCheckPath v = readRepositoryCheckPath((Registry) i.next());
if (existingCheckPaths.containsKey(v.getUrl())) {
existingCheckPathList.remove(existingCheckPaths.get(v.getUrl()));
}
existingCheckPathList.add(v);
newCheckPaths.put(v.getUrl(), v);
}
// Remote repositories update
for (RemoteRepositoryConfiguration remoteRepositoryConfiguration : config.getRemoteRepositories()) {
String url = remoteRepositoryConfiguration.getUrl().toLowerCase();
if (newCheckPaths.containsKey(url)) {
String currentPath = remoteRepositoryConfiguration.getCheckPath();
String newPath = newCheckPaths.get(url).getPath();
log.info("Updating connection check path for repository {}, from '{}' to '{}'.", remoteRepositoryConfiguration.getId(),
currentPath, newPath);
remoteRepositoryConfiguration.setCheckPath(newPath);
}
}
}
private RepositoryCheckPath readRepositoryCheckPath(Registry registry) {
RepositoryCheckPath value = new RepositoryCheckPath();
String url = registry.getString("url", value.getUrl());
value.setUrl(url);
String path = registry.getString("path", value.getPath());
value.setPath(path);
return value;
}
private Registry readDefaultConfiguration() {
// if it contains some old configuration, remove it (Archiva 0.9)
registry.removeSubset(KEY);
try {
registry.addConfigurationFromResource("org/apache/archiva/configuration/default-archiva.xml", KEY);
this.isConfigurationDefaulted = true;
} catch (RegistryException e) {
throw new ConfigurationRuntimeException(
"Fatal error: Unable to find the built-in default configuration and load it into the registry", e);
}
return registry.getSubset(KEY);
}
/*
* Reads the default only configuration into a special prefix. This allows to check for changes
* of the default configuration.
*/
private Registry readDefaultOnlyConfiguration() {
registry.removeSubset(KEY_DEFAULT_ONLY);
try {
registry.addConfigurationFromResource("org/apache/archiva/configuration/default-archiva.xml", KEY_DEFAULT_ONLY);
} catch (RegistryException e) {
throw new ConfigurationRuntimeException(
"Fatal error: Unable to find the built-in default configuration and load it into the registry", e);
}
return registry.getSubset(KEY_DEFAULT_ONLY);
}
@SuppressWarnings("unchecked")
@Override
public synchronized void save(Configuration configuration)
throws IndeterminateConfigurationException, RegistryException {
Registry section = registry.getSection(KEY + ".user");
Registry baseSection = registry.getSection(KEY + ".base");
if (section == null) {
section = baseSection;
if (section == null) {
section = createDefaultConfigurationFile();
}
} else if (baseSection != null) {
Collection<String> keys = baseSection.getKeys();
boolean foundList = false;
for (Iterator<String> i = keys.iterator(); i.hasNext() && !foundList; ) {
String key = i.next();
// a little aggressive with the repositoryScanning and databaseScanning - should be no need to split
// that configuration
if (key.startsWith("repositories") //
|| key.startsWith("proxyConnectors") //
|| key.startsWith("networkProxies") //
|| key.startsWith("repositoryScanning") //
|| key.startsWith("remoteRepositories") //
|| key.startsWith("managedRepositories") //
|| key.startsWith("repositoryGroups")) //
{
foundList = true;
}
}
if (foundList) {
this.configuration = null;
throw new IndeterminateConfigurationException(
"Configuration can not be saved when it is loaded from two sources");
}
}
// escape all cron expressions to handle ','
escapeCronExpressions(configuration);
// [MRM-661] Due to a bug in the modello registry writer, we need to take these out by hand. They'll be put back by the writer.
if (section != null) {
if (configuration.getManagedRepositories().isEmpty()) {
section.removeSubset("managedRepositories");
}
if (configuration.getRemoteRepositories().isEmpty()) {
section.removeSubset("remoteRepositories");
}
if (configuration.getProxyConnectors().isEmpty()) {
section.removeSubset("proxyConnectors");
}
if (configuration.getNetworkProxies().isEmpty()) {
section.removeSubset("networkProxies");
}
if (configuration.getLegacyArtifactPaths().isEmpty()) {
section.removeSubset("legacyArtifactPaths");
}
if (configuration.getRepositoryGroups().isEmpty()) {
section.removeSubset("repositoryGroups");
}
if (configuration.getRepositoryScanning() != null) {
if (configuration.getRepositoryScanning().getKnownContentConsumers().isEmpty()) {
section.removeSubset("repositoryScanning.knownContentConsumers");
}
if (configuration.getRepositoryScanning().getInvalidContentConsumers().isEmpty()) {
section.removeSubset("repositoryScanning.invalidContentConsumers");
}
}
if (configuration.getArchivaRuntimeConfiguration() != null) {
section.removeSubset("archivaRuntimeConfiguration.defaultCheckPaths");
}
new ConfigurationRegistryWriter().write(configuration, section);
section.save();
}
this.configuration = unescapeExpressions(configuration);
isConfigurationDefaulted = false;
triggerEvent(ConfigurationEvent.SAVED);
}
private void escapeCronExpressions(Configuration configuration) {
for (ManagedRepositoryConfiguration c : configuration.getManagedRepositories()) {
c.setRefreshCronExpression(escapeCronExpression(c.getRefreshCronExpression()));
}
}
private Registry createDefaultConfigurationFile()
throws RegistryException {
// TODO: may not be needed under commons-configuration 1.4 - check
String contents = "<configuration />";
String fileLocation = userConfigFilename;
if (!writeFile("user configuration", userConfigFilename, contents)) {
fileLocation = altConfigFilename;
if (!writeFile("alternative configuration", altConfigFilename, contents, true)) {
throw new RegistryException(
"Unable to create configuration file in either user [" + userConfigFilename + "] or alternative ["
+ altConfigFilename
+ "] locations on disk, usually happens when not allowed to write to those locations.");
}
}
// olamy hackish I know :-)
contents = "<configuration><xml fileName=\"" + fileLocation
+ "\" config-forceCreate=\"true\" config-name=\"org.apache.archiva.user\"/>" + "</configuration>";
((CommonsConfigurationRegistry) registry).setInitialConfiguration(contents);
registry.initialize();
for (RegistryListener regListener : registryListeners) {
addRegistryChangeListener(regListener);
}
triggerEvent(ConfigurationEvent.SAVED);
Registry section = registry.getSection(KEY + ".user");
if (section == null) {
return new CommonsConfigurationRegistry( );
} else {
return section;
}
}
private boolean writeFile(String filetype, String path, String contents) {
return writeFile( filetype, path, contents, false );
}
/**
* Attempts to write the contents to a file, if an IOException occurs, return false.
* <p/>
* The file will be created if the directory to the file exists, otherwise this will return false.
*
* @param filetype the filetype (freeform text) to use in logging messages when failure to write.
* @param path the path to write to.
* @param contents the contents to write.
* @return true if write successful.
*/
private boolean writeFile(String filetype, String path, String contents, boolean createDirs) {
Path file = Paths.get(path);
try {
// Check parent directory (if it is declared)
final Path parent = file.getParent();
if (parent != null) {
// Check that directory exists
if (!Files.exists( parent ) && createDirs) {
Files.createDirectories( parent );
}
if (!Files.isDirectory(parent)) {
// Directory to file must exist for file to be created
return false;
}
}
FileUtils.writeStringToFile(file.toFile(), contents, FILE_ENCODING);
return true;
} catch (IOException e) {
log.error("Unable to create {} file: {}", filetype, e.getMessage(), e);
return false;
}
}
private void triggerEvent(int type) {
ConfigurationEvent evt = new ConfigurationEvent(type);
for (ConfigurationListener listener : listeners) {
listener.configurationEvent(evt);
}
}
@Override
public void addListener(ConfigurationListener listener) {
if (listener == null) {
return;
}
listeners.add(listener);
}
@Override
public void removeListener(ConfigurationListener listener) {
if (listener == null) {
return;
}
listeners.remove(listener);
}
@Override
public void addChangeListener(RegistryListener listener) {
addRegistryChangeListener(listener);
// keep track for later
registryListeners.add(listener);
}
private void addRegistryChangeListener(RegistryListener listener) {
Registry section = registry.getSection(KEY + ".user");
if (section != null) {
section.addChangeListener(listener);
}
section = registry.getSection(KEY + ".base");
if (section != null) {
section.addChangeListener(listener);
}
}
@Override
public void removeChangeListener(RegistryListener listener) {
boolean removed = registryListeners.remove(listener);
log.debug("RegistryListener: '{}' removed {}", listener, removed);
Registry section = registry.getSection(KEY + ".user");
if (section != null) {
section.removeChangeListener(listener);
}
section = registry.getSection(KEY + ".base");
if (section != null) {
section.removeChangeListener(listener);
}
}
@PostConstruct
public void initialize() {
// Resolve expressions in the userConfigFilename and altConfigFilename
try {
ExpressionEvaluator expressionEvaluator = new DefaultExpressionEvaluator();
expressionEvaluator.addExpressionSource(new SystemPropertyExpressionSource());
String userConfigFileNameSysProps = System.getProperty(USER_CONFIG_PROPERTY);
if (StringUtils.isNotBlank(userConfigFileNameSysProps)) {
userConfigFilename = userConfigFileNameSysProps;
} else {
String userConfigFileNameEnv = System.getenv(USER_CONFIG_ENVVAR);
if (StringUtils.isNotBlank(userConfigFileNameEnv)) {
userConfigFilename = userConfigFileNameEnv;
} else {
userConfigFilename = expressionEvaluator.expand(userConfigFilename);
}
}
altConfigFilename = expressionEvaluator.expand(altConfigFilename);
loadConfiguration();
handleUpgradeConfiguration();
} catch (IndeterminateConfigurationException | RegistryException e) {
throw new RuntimeException("failed during upgrade from previous version" + e.getMessage(), e);
} catch (EvaluatorException e) {
throw new RuntimeException(
"Unable to evaluate expressions found in " + "userConfigFilename or altConfigFilename.", e);
}
registry.addChangeListener(this);
}
/**
* Handle upgrade to newer version
*/
private void handleUpgradeConfiguration()
throws RegistryException, IndeterminateConfigurationException {
List<String> dbConsumers = Arrays.asList("update-db-artifact", "update-db-repository-metadata");
// remove database consumers if here
List<String> intersec =
ListUtils.intersection(dbConsumers, configuration.getRepositoryScanning().getKnownContentConsumers());
if (!intersec.isEmpty()) {
List<String> knowContentConsumers =
new ArrayList<>(configuration.getRepositoryScanning().getKnownContentConsumers().size());
for (String knowContentConsumer : configuration.getRepositoryScanning().getKnownContentConsumers()) {
if (!dbConsumers.contains(knowContentConsumer)) {
knowContentConsumers.add(knowContentConsumer);
}
}
configuration.getRepositoryScanning().setKnownContentConsumers(knowContentConsumers);
}
// ensure create-archiva-metadata is here
if (!configuration.getRepositoryScanning().getKnownContentConsumers().contains("create-archiva-metadata")) {
List<String> knowContentConsumers =
new ArrayList<>(configuration.getRepositoryScanning().getKnownContentConsumers());
knowContentConsumers.add("create-archiva-metadata");
configuration.getRepositoryScanning().setKnownContentConsumers(knowContentConsumers);
}
// ensure duplicate-artifacts is here
if (!configuration.getRepositoryScanning().getKnownContentConsumers().contains("duplicate-artifacts")) {
List<String> knowContentConsumers =
new ArrayList<>(configuration.getRepositoryScanning().getKnownContentConsumers());
knowContentConsumers.add("duplicate-artifacts");
configuration.getRepositoryScanning().setKnownContentConsumers(knowContentConsumers);
}
Registry defaultOnlyConfiguration = readDefaultOnlyConfiguration();
// Currently we check only for configuration version change, not certain version numbers.
if (hasConfigVersionChanged(configuration, defaultOnlyConfiguration)) {
updateCheckPathDefaults(configuration, defaultOnlyConfiguration);
String newVersion = defaultOnlyConfiguration.getString("version");
if (newVersion == null) {
throw new IndeterminateConfigurationException("The default configuration has no version information!");
}
configuration.setVersion(newVersion);
try {
save(configuration);
} catch (IndeterminateConfigurationException e) {
log.error("Error occured during configuration update to new version: {}", e.getMessage());
} catch (RegistryException e) {
log.error("Error occured during configuration update to new version: {}", e.getMessage());
}
}
}
@Override
public void reload() {
this.configuration = null;
try {
this.registry.initialize();
} catch (RegistryException e) {
throw new ConfigurationRuntimeException(e.getMessage(), e);
}
this.initialize();
}
@Override
public Locale getDefaultLocale() {
return defaultLocale;
}
@Override
public List<Locale.LanguageRange> getLanguagePriorities() {
return languagePriorities;
}
@Override
public Path getAppServerBaseDir() {
String basePath = registry.getString("appserver.base");
if (!StringUtils.isEmpty(basePath)) {
return Paths.get(basePath);
} else {
return Paths.get("");
}
}
@Override
public Path getRepositoryBaseDir() {
if (repositoryBaseDirectory == null) {
getConfiguration();
}
return repositoryBaseDirectory;
}
@Override
public Path getRemoteRepositoryBaseDir() {
if (remoteRepositoryBaseDirectory == null) {
getConfiguration();
}
return remoteRepositoryBaseDirectory;
}
@Override
public Path getRepositoryGroupBaseDir() {
if (repositoryGroupBaseDirectory == null) {
getConfiguration();
}
return repositoryGroupBaseDirectory;
}
@Override
public Path getDataDirectory() {
if (dataDirectory == null) {
getConfiguration();
}
return dataDirectory;
}
@Override
public void beforeConfigurationChange(Registry registry, String propertyName, Object propertyValue) {
// nothing to do here
}
@Override
public synchronized void afterConfigurationChange(Registry registry, String propertyName, Object propertyValue) {
// configuration = null;
// this.dataDirectory = null;
// this.repositoryBaseDirectory = null;
}
private String removeExpressions(String directory) {
String value = StringUtils.replace(directory, "${appserver.base}",
registry.getString("appserver.base", "${appserver.base}"));
value = StringUtils.replace(value, "${appserver.home}",
registry.getString("appserver.home", "${appserver.home}"));
return value;
}
private String unescapeCronExpression(String cronExpression) {
return StringUtils.replace(cronExpression, "\\,", ",");
}
private String escapeCronExpression(String cronExpression) {
return StringUtils.replace(cronExpression, ",", "\\,");
}
private Configuration unescapeExpressions(Configuration config) {
// TODO: for commons-configuration 1.3 only
for (ManagedRepositoryConfiguration c : config.getManagedRepositories()) {
c.setLocation(removeExpressions(c.getLocation()));
c.setRefreshCronExpression(unescapeCronExpression(c.getRefreshCronExpression()));
}
return config;
}
private Configuration checkRepositoryLocations(Configuration config) {
// additional check for [MRM-789], ensure that the location of the default repositories
// are not installed in the server installation
for (ManagedRepositoryConfiguration repo : (List<ManagedRepositoryConfiguration>) config.getManagedRepositories()) {
String repoPath = repo.getLocation();
Path repoLocation = Paths.get(repoPath);
if (Files.exists(repoLocation) && Files.isDirectory(repoLocation) && !repoPath.endsWith(
"data/repositories/" + repo.getId())) {
repo.setLocation(repoPath + "/data/repositories/" + repo.getId());
}
}
return config;
}
public String getUserConfigFilename() {
return userConfigFilename;
}
public String getAltConfigFilename() {
return altConfigFilename;
}
@Override
public boolean isDefaulted() {
return this.isConfigurationDefaulted;
}
public Registry getRegistry() {
return registry;
}
public void setRegistry(Registry registry) {
this.registry = registry;
}
public void setUserConfigFilename(String userConfigFilename) {
this.userConfigFilename = userConfigFilename;
}
public void setAltConfigFilename(String altConfigFilename) {
this.altConfigFilename = altConfigFilename;
}
}