123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974 |
- 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.policies.DownloadErrorPolicy;
- import org.apache.archiva.policies.Policy;
- import org.apache.archiva.policies.PostDownloadPolicy;
- import org.apache.archiva.policies.PreDownloadPolicy;
- import org.apache.archiva.redback.components.evaluator.DefaultExpressionEvaluator;
- import org.apache.archiva.redback.components.evaluator.EvaluatorException;
- import org.apache.archiva.redback.components.evaluator.ExpressionEvaluator;
- import org.apache.archiva.redback.components.evaluator.sources.SystemPropertyExpressionSource;
- import org.apache.archiva.redback.components.registry.Registry;
- import org.apache.archiva.redback.components.registry.RegistryException;
- import org.apache.archiva.redback.components.registry.RegistryListener;
- import org.apache.archiva.redback.components.registry.commons.CommonsConfigurationRegistry;
- import org.apache.archiva.redback.components.springutils.ComponentContainer;
- import org.apache.commons.collections4.CollectionUtils;
- import org.apache.commons.collections4.ListUtils;
- import org.apache.commons.collections4.MapUtils;
- import org.apache.commons.configuration.BaseConfiguration;
- 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.ArrayList;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Locale;
- import java.util.Map;
- import java.util.Map.Entry;
- import java.util.Set;
-
- /**
- * <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;
-
- @Inject
- private ComponentContainer componentContainer;
-
- /**
- * The configuration that has been converted.
- */
- private Configuration configuration;
-
- /**
- * see #initialize
- *
- * @todo these don't strictly belong in here
- */
- private Map<String, PreDownloadPolicy> prePolicies;
-
- /**
- * see #initialize
- *
- * @todo these don't strictly belong in here
- */
- private Map<String, PostDownloadPolicy> postPolicies;
-
- /**
- * see #initialize
- *
- * @todo these don't strictly belong in here
- */
- private Map<String, DownloadErrorPolicy> downloadErrorPolicies;
-
-
- /**
- * 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.
- if (policyExists(policyId)) {
- Policy policy = findPolicy(policyId);
- // Does option exist?
- if (!policy.getOptions().contains(setting)) {
- setting = policy.getDefaultOption().getId();
- }
- connector.addPolicy(policyId, setting);
- } else {
- // Policy key doesn't exist. Don't add it to golden version.
- log.warn("Policy [{}] does not exist.", policyId);
- }
- }
-
- 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 Policy findPolicy(String policyId) {
- if (MapUtils.isEmpty(prePolicies)) {
- log.error("No PreDownloadPolicies found!");
- return null;
- }
-
- if (MapUtils.isEmpty(postPolicies)) {
- log.error("No PostDownloadPolicies found!");
- return null;
- }
-
- Policy policy;
-
- policy = prePolicies.get(policyId);
- if (policy != null) {
- return policy;
- }
-
- policy = postPolicies.get(policyId);
- if (policy != null) {
- return policy;
- }
-
- policy = downloadErrorPolicies.get(policyId);
- if (policy != null) {
- return policy;
- }
-
- return null;
- }
-
- private boolean policyExists(String policyId) {
- if (MapUtils.isEmpty(prePolicies)) {
- log.error("No PreDownloadPolicies found!");
- return false;
- }
-
- if (MapUtils.isEmpty(postPolicies)) {
- log.error("No PostDownloadPolicies found!");
- return false;
- }
-
- return (prePolicies.containsKey(policyId) || postPolicies.containsKey(policyId)
- || downloadErrorPolicies.containsKey(policyId));
- }
-
- 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).setProperties(contents);
-
- registry.initialize();
-
- for (RegistryListener regListener : registryListeners) {
- addRegistryChangeListener(regListener);
- }
-
- triggerEvent(ConfigurationEvent.SAVED);
-
- Registry section = registry.getSection(KEY + ".user");
- return section == null ? new CommonsConfigurationRegistry(new BaseConfiguration()) : 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() {
-
- this.postPolicies = componentContainer.buildMapWithRole(PostDownloadPolicy.class);
- this.prePolicies = componentContainer.buildMapWithRole(PreDownloadPolicy.class);
- this.downloadErrorPolicies = componentContainer.buildMapWithRole(DownloadErrorPolicy.class);
- // 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;
- }
- }
|