Fixing most tests for common configuration

This commit is contained in:
Martin Stockhammer 2019-02-14 22:29:49 +01:00
parent b40804b4ba
commit 6ffec226b8
7 changed files with 271 additions and 189 deletions

View File

@ -30,7 +30,9 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>redback-common-configuration</artifactId> <artifactId>redback-common-configuration</artifactId>
<name>Redback :: Common Configuration</name>
<packaging>pom</packaging> <packaging>pom</packaging>
<modules> <modules>
<module>redback-common-configuration-api</module> <module>redback-common-configuration-api</module>
<module>redback-common-configuration-acc2</module> <module>redback-common-configuration-acc2</module>
@ -42,7 +44,7 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<configuration> <configuration>
<skipTests>true</skipTests> <skipTests>false</skipTests>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>

View File

@ -30,6 +30,8 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>redback-common-configuration-acc2</artifactId> <artifactId>redback-common-configuration-acc2</artifactId>
<name>Redback :: Common Configuration - Apache Commons Configuration 2</name>
<description>Implementation of Common Configuration API based on apache commons configuration version 2.</description>
<dependencies> <dependencies>
<dependency> <dependency>
@ -52,6 +54,7 @@
<groupId>commons-beanutils</groupId> <groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId> <artifactId>commons-beanutils</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>

View File

@ -23,6 +23,7 @@ import org.apache.archiva.redback.common.config.api.ConfigRegistry;
import org.apache.archiva.redback.common.config.api.RegistryException; import org.apache.archiva.redback.common.config.api.RegistryException;
import org.apache.archiva.redback.common.config.api.RegistryListener; import org.apache.archiva.redback.common.config.api.RegistryListener;
import org.apache.commons.configuration2.*; import org.apache.commons.configuration2.*;
import org.apache.commons.configuration2.builder.ConfigurationBuilder;
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder; import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
import org.apache.commons.configuration2.builder.combined.CombinedConfigurationBuilder; import org.apache.commons.configuration2.builder.combined.CombinedConfigurationBuilder;
import org.apache.commons.configuration2.builder.fluent.Parameters; import org.apache.commons.configuration2.builder.fluent.Parameters;
@ -33,8 +34,8 @@ import org.apache.commons.configuration2.interpol.DefaultLookups;
import org.apache.commons.configuration2.interpol.InterpolatorSpecification; import org.apache.commons.configuration2.interpol.InterpolatorSpecification;
import org.apache.commons.configuration2.io.ClasspathLocationStrategy; import org.apache.commons.configuration2.io.ClasspathLocationStrategy;
import org.apache.commons.configuration2.io.FileHandler; import org.apache.commons.configuration2.io.FileHandler;
import org.apache.commons.configuration2.io.FileLocatorUtils;
import org.apache.commons.configuration2.io.FileSystem; import org.apache.commons.configuration2.io.FileSystem;
import org.apache.commons.configuration2.io.FileSystemLocationStrategy;
import org.apache.commons.configuration2.tree.DefaultExpressionEngine; import org.apache.commons.configuration2.tree.DefaultExpressionEngine;
import org.apache.commons.configuration2.tree.DefaultExpressionEngineSymbols; import org.apache.commons.configuration2.tree.DefaultExpressionEngineSymbols;
import org.apache.commons.configuration2.tree.NodeCombiner; import org.apache.commons.configuration2.tree.NodeCombiner;
@ -51,19 +52,18 @@ import java.net.URL;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
/** /**
* Implementation of the registry component using * Implementation of the registry component using
* <a href="http://commons.apache.org/commons/configuration">Commons Configuration</a>. The use of Commons Configuration * <a href="https://commons.apache.org/proper/commons-configuration/index.html">Commons Configuration 2</a>.
* enables a variety of sources to be used, including XML files, properties, JNDI, JDBC, etc. * The use of Commons Configuration enables a variety of sources to be used, including XML files, properties, JNDI, JDBC, etc.
* <p/> * <p/>
* The component can be configured using the {@link #properties} configuration item, the content of which should take * The component can be configured using the {@link #combinedConfigurationDefinition} configuration item, the content of which should take
* the format of an input to the Commons Configuration * the format of an input to the Commons Configuration
* <a href="http://commons.apache.org/commons/configuration/howto_configurationbuilder.html">configuration * <a href="http://commons.apache.org/commons/configuration/howto_configurationbuilder.html">configuration
* builder</a>. * builder</a>.
*/ */
@Service( "acc2-configuration" ) @Service("acc2-configuration")
public class CommonsConfigurationRegistry public class CommonsConfigurationRegistry
implements ConfigRegistry implements ConfigRegistry
{ {
@ -72,76 +72,96 @@ public class CommonsConfigurationRegistry
*/ */
private Configuration configuration; private Configuration configuration;
private Logger logger = LoggerFactory.getLogger( getClass() );
private ConfigurationBuilder<? extends Configuration> configurationBuilder;
boolean combined = true;
private Map<String, ConfigurationBuilder<? extends Configuration>> builderMap = new HashMap<>( );
private Logger logger = LoggerFactory.getLogger( getClass( ) );
private String propertyDelimiter = "."; private String propertyDelimiter = ".";
/** /**
* The configuration properties for the registry. This should take the format of an input to the Commons * The configuration properties for the registry. This should take the format of an input to the Commons
* Configuration * Configuration
* <a href="http://commons.apache.org/configuration/howto_configurationbuilder.html">configuration * <a href="https://commons.apache.org/proper/commons-configuration/userguide/howto_combinedbuilder.html#The_configuration_definition_file">configuration
* builder</a>. * builder</a>.
*/ */
private String properties; private String combinedConfigurationDefinition;
public CommonsConfigurationRegistry() public CommonsConfigurationRegistry()
{ {
// default constructor // Default constructor
logger.debug( "empty constructor" );
} }
public CommonsConfigurationRegistry( Configuration configuration ) public CommonsConfigurationRegistry(CombinedConfiguration configuration, ConfigurationBuilder<? extends Configuration> configurationBuilder)
{ {
if ( configuration == null ) if ( configuration == null )
{ {
throw new NullPointerException( "configuration can not be null" ); throw new NullPointerException( "configuration can not be null" );
} }
if ( configurationBuilder == null )
{
throw new NullPointerException( "configuration builder cannot be null for a combined configuration" );
}
this.combined = true;
this.configuration = configuration; this.configuration = configuration;
this.configurationBuilder = configurationBuilder;
}
public CommonsConfigurationRegistry(Configuration configuration, ConfigurationBuilder<? extends Configuration> configurationBuilder)
{
if ( configuration == null )
{
throw new NullPointerException( "configuration can not be null" );
}
this.configuration = configuration;
this.configurationBuilder = configurationBuilder;
} }
public String dump() public String dump()
{ {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder( );
buffer.append( "Configuration Dump." ); buffer.append( "Configuration Dump." );
for ( Iterator i = configuration.getKeys(); i.hasNext(); ) for ( Iterator i = configuration.getKeys( ); i.hasNext( ); )
{ {
String key = (String) i.next(); String key = ( String ) i.next( );
Object value = configuration.getProperty( key ); Object value = configuration.getProperty( key );
buffer.append( "\n\"" ).append( key ).append( "\" = \"" ).append( value ).append( "\"" ); buffer.append( "\n\"" ).append( key ).append( "\" = \"" ).append( value ).append( "\"" );
} }
return buffer.toString(); return buffer.toString( );
} }
public boolean isEmpty() public boolean isEmpty()
{ {
return configuration.isEmpty(); return configuration.isEmpty( );
} }
public ConfigRegistry getSubset( String key ) public ConfigRegistry getSubset(String key)
{ {
return new CommonsConfigurationRegistry( configuration.subset( key ) ); return new CommonsConfigurationRegistry( configuration.subset( key ), configurationBuilder );
} }
public List<String> getList( String key ) public List<String> getList(String key)
{ {
return configuration.getList(String.class, key ); List<String> result = configuration.getList( String.class, key );
return result == null ? new ArrayList<>( ) : result;
} }
public List<ConfigRegistry> getSubsetList( String key ) public List<ConfigRegistry> getSubsetList(String key)
{ {
List<ConfigRegistry> subsets = new ArrayList<>(); List<ConfigRegistry> subsets = new ArrayList<>( );
boolean done = false; boolean done = false;
do do
{ {
ConfigRegistry registry = getSubset( key + "(" + subsets.size() + ")" ); ConfigRegistry registry = getSubset( key + "(" + subsets.size( ) + ")" );
if ( !registry.isEmpty() ) if ( !registry.isEmpty( ) )
{ {
subsets.add( registry ); subsets.add( registry );
} } else
else
{ {
done = true; done = true;
} }
@ -152,23 +172,46 @@ public class CommonsConfigurationRegistry
} }
@Override @Override
public ConfigRegistry getSource( String name ) public ConfigRegistry getPartOfCombined(String name)
{ {
if ( combined )
{
CombinedConfiguration config = ( CombinedConfiguration ) configuration;
Configuration newCfg = config.getConfiguration( name );
ConfigurationBuilder<? extends Configuration> cfgBuilder = null;
try
{
if ( builderMap.containsKey( name ) )
{
cfgBuilder = builderMap.get( name );
} else
{
cfgBuilder = configurationBuilder == null ? null :
(( CombinedConfigurationBuilder ) configurationBuilder).getNamedBuilder( name );
builderMap.put( name, cfgBuilder );
}
}
catch ( ConfigurationException e )
{
logger.error( "Could not retrieve configuration builder: " + e.getMessage( ) );
}
return newCfg == null ? null : new CommonsConfigurationRegistry( newCfg, cfgBuilder );
}
return null; return null;
} }
public Map<String,String> getProperties( String key ) public Map<String, String> getProperties(String key)
{ {
Configuration configuration = this.configuration.subset( key ); Configuration configuration = this.configuration.subset( key );
Map<String,String> properties = new TreeMap<>(); Map<String, String> properties = new TreeMap<>( );
Iterator<String> cfgIter = configuration.getKeys( ); Iterator<String> cfgIter = configuration.getKeys( );
String property; String property;
while ( cfgIter.hasNext() ) while ( cfgIter.hasNext( ) )
{ {
property = cfgIter.next(); property = cfgIter.next( );
List<String> l = configuration.getList( String.class, property ); List<String> l = configuration.getList( String.class, property );
String value = String.join(",", l); String value = String.join( ",", l );
properties.put( property, value ); properties.put( property, value );
} }
return properties; return properties;
@ -179,30 +222,38 @@ public class CommonsConfigurationRegistry
{ {
if ( configuration instanceof FileBasedConfiguration ) if ( configuration instanceof FileBasedConfiguration )
{ {
FileBasedConfiguration fileConfiguration = (FileBasedConfiguration) configuration; FileBasedConfiguration fileConfiguration = ( FileBasedConfiguration ) configuration;
FileHandler fileHandler;
if ( configurationBuilder != null && configurationBuilder instanceof FileBasedConfigurationBuilder )
{
FileBasedConfigurationBuilder cfgBuilder = ( FileBasedConfigurationBuilder ) configurationBuilder;
fileHandler = cfgBuilder.getFileHandler( );
} else
{
fileHandler = new FileHandler( fileConfiguration );
}
try try
{ {
new FileHandler( fileConfiguration ).save(); fileHandler.save( );
} }
catch ( ConfigurationException e ) catch ( ConfigurationException e )
{ {
throw new RegistryException( e.getMessage(), e ); throw new RegistryException( e.getMessage( ), e );
} }
} } else
else
{ {
throw new RegistryException( "Can only save file-based configurations" ); throw new RegistryException( "Can only save file-based configurations" );
} }
} }
@Override @Override
public void registerChangeListener( RegistryListener listener, Pattern... filter ) public void registerChangeListener(RegistryListener listener, Pattern... filter)
{ {
} }
@Override @Override
public boolean unregisterChangeListener( RegistryListener listener ) public boolean unregisterChangeListener(RegistryListener listener)
{ {
return false; return false;
} }
@ -210,18 +261,17 @@ public class CommonsConfigurationRegistry
public Collection<String> getKeys() public Collection<String> getKeys()
{ {
Set<String> keys = new HashSet<String>(); Set<String> keys = new HashSet<String>( );
for ( Iterator<String> i = configuration.getKeys(); i.hasNext(); ) for ( Iterator<String> i = configuration.getKeys( ); i.hasNext( ); )
{ {
String key = i.next(); String key = i.next( );
int index = key.indexOf( '.' ); int index = key.indexOf( '.' );
if ( index < 0 ) if ( index < 0 )
{ {
keys.add( key ); keys.add( key );
} } else
else
{ {
keys.add( key.substring( 0, index ) ); keys.add( key.substring( 0, index ) );
} }
@ -232,255 +282,270 @@ public class CommonsConfigurationRegistry
public Collection getFullKeys() public Collection getFullKeys()
{ {
Set<String> keys = new HashSet<String>(); Set<String> keys = new HashSet<String>( );
for ( Iterator<String> i = configuration.getKeys(); i.hasNext(); ) for ( Iterator<String> i = configuration.getKeys( ); i.hasNext( ); )
{ {
keys.add( i.next() ); keys.add( i.next( ) );
} }
return keys; return keys;
} }
public void remove( String key ) public void remove(String key)
{ {
configuration.clearProperty( key ); configuration.clearProperty( key );
} }
public void removeSubset( String key ) public void removeSubset(String key)
{ {
// create temporary list since removing a key will modify the iterator from configuration // create temporary list since removing a key will modify the iterator from configuration
List keys = new ArrayList(); List keys = new ArrayList( );
for ( Iterator i = configuration.getKeys( key ); i.hasNext(); ) for ( Iterator i = configuration.getKeys( key ); i.hasNext( ); )
{ {
keys.add( i.next() ); keys.add( i.next( ) );
} }
for ( Iterator i = keys.iterator(); i.hasNext(); ) for ( Iterator i = keys.iterator( ); i.hasNext( ); )
{ {
configuration.clearProperty( (String) i.next() ); configuration.clearProperty( ( String ) i.next( ) );
} }
} }
public String getString( String key ) public String getString(String key)
{ {
return configuration.getString( key ); return configuration.getString( key );
} }
public String getString( String key, String defaultValue ) public String getString(String key, String defaultValue)
{ {
return configuration.getString( key, defaultValue ); return configuration.getString( key, defaultValue );
} }
public void setString( String key, String value ) public void setString(String key, String value)
{ {
configuration.setProperty( key, value ); configuration.setProperty( key, value );
} }
public int getInt( String key ) public int getInt(String key)
{ {
return configuration.getInt( key ); return configuration.getInt( key );
} }
public int getInt( String key, int defaultValue ) public int getInt(String key, int defaultValue)
{ {
return configuration.getInt( key, defaultValue ); return configuration.getInt( key, defaultValue );
} }
public void setInt( String key, int value ) public void setInt(String key, int value)
{ {
configuration.setProperty( key, Integer.valueOf( value ) ); configuration.setProperty( key, Integer.valueOf( value ) );
} }
public boolean getBoolean( String key ) public boolean getBoolean(String key)
{ {
return configuration.getBoolean( key ); return configuration.getBoolean( key );
} }
public boolean getBoolean( String key, boolean defaultValue ) public boolean getBoolean(String key, boolean defaultValue)
{ {
return configuration.getBoolean( key, defaultValue ); return configuration.getBoolean( key, defaultValue );
} }
public void setBoolean( String key, boolean value ) public void setBoolean(String key, boolean value)
{ {
configuration.setProperty( key, Boolean.valueOf( value ) ); configuration.setProperty( key, Boolean.valueOf( value ) );
} }
public void addConfigurationFromResource( String name, String resource ) public void addConfigurationFromResource(String name, String resource)
throws RegistryException throws RegistryException
{ {
addConfigurationFromResource( name, resource, null ); addConfigurationFromResource( name, resource, null );
} }
public void addConfigurationFromResource( String name, String resource, String prefix ) public void addConfigurationFromResource(String name, String resource, String prefix)
throws RegistryException throws RegistryException
{ {
if (configuration instanceof CombinedConfiguration) if ( configuration instanceof CombinedConfiguration )
{ {
String atPrefix = StringUtils.isEmpty( prefix ) ? null : prefix; String atPrefix = StringUtils.isEmpty( prefix ) ? null : prefix;
CombinedConfiguration configuration = (CombinedConfiguration) this.configuration; CombinedConfiguration configuration = ( CombinedConfiguration ) this.configuration;
if ( resource.endsWith( ".properties" ) ) if ( resource.endsWith( ".properties" ) )
{ {
try try
{ {
logger.debug( "Loading properties configuration from classloader resource: {}", resource ); logger.debug( "Loading properties configuration from classloader resource: {}", resource );
FileBasedConfigurationBuilder<PropertiesConfiguration> builder = new FileBasedConfigurationBuilder<>( PropertiesConfiguration.class ) FileBasedConfigurationBuilder<PropertiesConfiguration> builder = new FileBasedConfigurationBuilder<>( PropertiesConfiguration.class )
.configure( new Parameters().properties() .configure( new Parameters( ).properties( )
.setLocationStrategy( new ClasspathLocationStrategy() ) .setLocationStrategy( new ClasspathLocationStrategy( ) )
.setFileName( resource ) ); .setFileName( resource ) );
configuration.addConfiguration( builder.getConfiguration() , name, atPrefix ); builderMap.put( name, builder );
configuration.addConfiguration( builder.getConfiguration( ), name, atPrefix );
} }
catch ( ConfigurationException e ) catch ( ConfigurationException e )
{ {
throw new RegistryException( throw new RegistryException(
"Unable to add configuration from resource '" + resource + "': " + e.getMessage( ), e ); "Unable to add configuration from resource '" + resource + "': " + e.getMessage( ), e );
} }
} } else if ( resource.endsWith( ".xml" ) )
else if ( resource.endsWith( ".xml" ) )
{ {
try try
{ {
logger.debug( "Loading XML configuration from classloader resource: {}", resource ); logger.debug( "Loading XML configuration from classloader resource: {}", resource );
FileBasedConfigurationBuilder<XMLConfiguration> builder = new FileBasedConfigurationBuilder<>( XMLConfiguration.class ) FileBasedConfigurationBuilder<XMLConfiguration> builder = new FileBasedConfigurationBuilder<>( XMLConfiguration.class )
.configure( new Parameters().xml() .configure( new Parameters( ).xml( )
.setLocationStrategy( new ClasspathLocationStrategy() ) .setLocationStrategy( new ClasspathLocationStrategy( ) )
.setFileName( resource ) ); .setFileName( resource ) );
configuration.addConfiguration( builder.getConfiguration(), name, atPrefix ); builderMap.put( name, builder );
configuration.addConfiguration( builder.getConfiguration( ), name, atPrefix );
} }
catch ( ConfigurationException e ) catch ( ConfigurationException e )
{ {
throw new RegistryException( throw new RegistryException(
"Unable to add configuration from resource '" + resource + "': " + e.getMessage( ), e ); "Unable to add configuration from resource '" + resource + "': " + e.getMessage( ), e );
} }
} } else
else
{ {
throw new RegistryException( throw new RegistryException(
"Unable to add configuration from resource '" + resource + "': unrecognised type" ); "Unable to add configuration from resource '" + resource + "': unrecognised type" );
} }
} else { } else
{
throw new RegistryException( "The underlying configuration object is not a combined configuration " ); throw new RegistryException( "The underlying configuration object is not a combined configuration " );
} }
} }
@Override @Override
public void addConfigurationFromFile( String name, Path file ) throws RegistryException public void addConfigurationFromFile(String name, Path file) throws RegistryException
{ {
addConfigurationFromFile( name, file, "" ); addConfigurationFromFile( name, file, "" );
} }
public void addConfigurationFromFile( String name, Path file, String prefix ) public void addConfigurationFromFile(String name, Path file, String prefix)
throws RegistryException throws RegistryException
{ {
if (this.configuration instanceof CombinedConfiguration) if ( this.configuration instanceof CombinedConfiguration )
{ {
String atPrefix = StringUtils.isEmpty( prefix ) ? null : prefix; String atPrefix = StringUtils.isEmpty( prefix ) ? null : prefix;
CombinedConfiguration configuration = (CombinedConfiguration) this.configuration; CombinedConfiguration configuration = ( CombinedConfiguration ) this.configuration;
String fileName = file.getFileName().toString(); String fileName = file.getFileName( ).toString( );
if ( fileName.endsWith( ".properties" ) ) if ( fileName.endsWith( ".properties" ) )
{ {
try try
{ {
logger.debug( "Loading properties configuration from file: {}", file ); logger.debug( "Loading properties configuration from file: {}", file );
FileBasedConfigurationBuilder<PropertiesConfiguration> builder = new FileBasedConfigurationBuilder<>( PropertiesConfiguration.class ) FileBasedConfigurationBuilder<PropertiesConfiguration> builder = new FileBasedConfigurationBuilder<>( PropertiesConfiguration.class )
.configure( new Parameters().properties() .configure( new Parameters( ).properties( )
.setLocationStrategy( new FileSystemLocationStrategy() ) .setFileSystem( FileLocatorUtils.DEFAULT_FILE_SYSTEM )
.setFile( file.toFile() ) ); .setLocationStrategy( FileLocatorUtils.DEFAULT_LOCATION_STRATEGY )
configuration.addConfiguration( builder.getConfiguration() , name, atPrefix ); .setFile( file.toFile( ) ) );
// builder is needed for save
builderMap.put( name, builder );
configuration.addConfiguration( builder.getConfiguration( ), name, atPrefix );
} }
catch ( ConfigurationException e ) catch ( ConfigurationException e )
{ {
throw new RegistryException( throw new RegistryException(
"Unable to add configuration from file '" + file.getFileName( ) + "': " + e.getMessage( ), e ); "Unable to add configuration from file '" + file.getFileName( ) + "': " + e.getMessage( ), e );
} }
} } else if ( fileName.endsWith( ".xml" ) )
else if ( fileName.endsWith( ".xml" ) )
{ {
try try
{ {
logger.debug( "Loading XML configuration from file: {}", file ); logger.debug( "Loading XML configuration from file: {}", file );
FileBasedConfigurationBuilder<XMLConfiguration> builder = new FileBasedConfigurationBuilder<>( XMLConfiguration.class ) FileBasedConfigurationBuilder<XMLConfiguration> builder = new FileBasedConfigurationBuilder<>( XMLConfiguration.class )
.configure( new Parameters().xml() .configure( new Parameters( ).xml( )
.setLocationStrategy( new ClasspathLocationStrategy() ) .setFileSystem( FileLocatorUtils.DEFAULT_FILE_SYSTEM )
.setFile( file.toFile()) ); .setLocationStrategy( FileLocatorUtils.DEFAULT_LOCATION_STRATEGY )
configuration.addConfiguration( builder.getConfiguration(), name, atPrefix ); .setFile( file.toFile( ) ) );
builderMap.put( name, builder );
configuration.addConfiguration( builder.getConfiguration( ), name, atPrefix );
} }
catch ( ConfigurationException e ) catch ( ConfigurationException e )
{ {
throw new RegistryException( throw new RegistryException(
"Unable to add configuration from file '" + file.getFileName( ) + "': " + e.getMessage( ), e ); "Unable to add configuration from file '" + file.getFileName( ) + "': " + e.getMessage( ), e );
} }
} } else
else
{ {
throw new RegistryException( throw new RegistryException(
"Unable to add configuration from file '" + file.getFileName( ) + "': unrecognised type" ); "Unable to add configuration from file '" + file.getFileName( ) + "': unrecognised type" );
} }
} else { } else
{
throw new RegistryException( "The underlying configuration is not a combined configuration object." ); throw new RegistryException( "The underlying configuration is not a combined configuration object." );
} }
} }
class StringFileSystem extends FileSystem { /**
* This is a dummy FileSystem needed to load the CombinedConfiguration declaration from a String.
*/
class StringFileSystem extends FileSystem
{
String content; String content;
String encoding = "UTF-8"; String encoding = "UTF-8";
StringFileSystem(String content) { StringFileSystem(String content)
{
this.content = content;
}
StringFileSystem(String encoding, String content) {
this.encoding = encoding;
this.content = content; this.content = content;
} }
@Override @Override
public InputStream getInputStream( URL url ) throws ConfigurationException public InputStream getInputStream(URL url) throws ConfigurationException
{ {
try try
{ {
return new ByteArrayInputStream( content.getBytes(encoding) ); return new ByteArrayInputStream( content.getBytes( encoding ) );
} }
catch ( UnsupportedEncodingException e ) catch ( UnsupportedEncodingException e )
{ {
logger.error("Bad encoding for FileSystem"); logger.error( "Bad encoding for FileSystem" );
throw new ConfigurationException( "Bad encoding specified" ); throw new ConfigurationException( "Bad encoding specified" );
} }
} }
@Override @Override
public OutputStream getOutputStream( URL url ) throws ConfigurationException public OutputStream getOutputStream(URL url) throws ConfigurationException
{ {
return new ByteArrayOutputStream( 0 ); return new ByteArrayOutputStream( 0 );
} }
@Override @Override
public OutputStream getOutputStream( File file ) throws ConfigurationException public OutputStream getOutputStream(File file) throws ConfigurationException
{ {
return new ByteArrayOutputStream( 0 ); return new ByteArrayOutputStream( 0 );
} }
@Override @Override
public String getPath( File file, URL url, String basePath, String fileName ) public String getPath(File file, URL url, String basePath, String fileName)
{ {
return basePath+"/"+fileName; return basePath + "/" + fileName;
} }
@Override @Override
public String getBasePath( String path ) public String getBasePath(String path)
{ {
return path; return path;
} }
@Override @Override
public String getFileName( String path ) public String getFileName(String path)
{ {
return path; return path;
} }
@Override @Override
public URL locateFromURL( String basePath, String fileName ) public URL locateFromURL(String basePath, String fileName)
{ {
try try
{ {
return new URL("file://"+getPath(null, null, basePath, fileName)); return new URL( "file://" + getPath( null, null, basePath, fileName ) );
} }
catch ( MalformedURLException e ) catch ( MalformedURLException e )
{ {
@ -490,11 +555,11 @@ public class CommonsConfigurationRegistry
} }
@Override @Override
public URL getURL( String basePath, String fileName ) throws MalformedURLException public URL getURL(String basePath, String fileName) throws MalformedURLException
{ {
try try
{ {
return new URL("file://"+getPath(null, null, basePath, fileName)); return new URL( "file://" + getPath( null, null, basePath, fileName ) );
} }
catch ( MalformedURLException e ) catch ( MalformedURLException e )
{ {
@ -512,71 +577,69 @@ public class CommonsConfigurationRegistry
try try
{ {
CombinedConfiguration configuration; CombinedConfiguration configuration;
if ( StringUtils.isNotBlank( properties ) ) if ( StringUtils.isNotBlank( combinedConfigurationDefinition ) )
{ {
System.out.println("Configuration");
System.out.println(properties); // This part is mainly for backwards compatibility.
Parameters params = new Parameters(); // It allows to use system properties in the XML declaration.
DefaultExpressionEngineSymbols symbols = new DefaultExpressionEngineSymbols.Builder(DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS ) Parameters params = new Parameters( );
DefaultExpressionEngineSymbols symbols = new DefaultExpressionEngineSymbols.Builder( DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS )
.setPropertyDelimiter( propertyDelimiter ) .setPropertyDelimiter( propertyDelimiter )
.setIndexStart( "(" ) .setIndexStart( "(" )
.setIndexEnd( ")" ) .setIndexEnd( ")" )
.setEscapedDelimiter( "\\"+propertyDelimiter ) .setEscapedDelimiter( "\\" + propertyDelimiter )
. create( ); .create( );
DefaultExpressionEngine expressionEngine = new DefaultExpressionEngine( symbols ); DefaultExpressionEngine expressionEngine = new DefaultExpressionEngine( symbols );
ConfigurationInterpolator interpolator = ConfigurationInterpolator.fromSpecification( new InterpolatorSpecification.Builder().withDefaultLookup( DefaultLookups.SYSTEM_PROPERTIES.getLookup() ).create() ); ConfigurationInterpolator interpolator = ConfigurationInterpolator.fromSpecification( new InterpolatorSpecification.Builder( ).withDefaultLookup( DefaultLookups.SYSTEM_PROPERTIES.getLookup( ) ).create( ) );
System.out.println(interpolator.getDefaultLookups().stream( ).map(p -> p.toString()).collect( Collectors.joining( ","))); String interpolatedProps = interpolator.interpolate( combinedConfigurationDefinition ).toString( );
String interpolatedProps = interpolator.interpolate( properties ).toString();
logger.debug( "Loading configuration into commons-configuration, xml {}", interpolatedProps ); logger.debug( "Loading configuration into commons-configuration, xml {}", interpolatedProps );
// This is the builder configuration for the XML declaration, that contains the definition
// for the sources that are used for the CombinedConfiguration.
FileSystem fs = new StringFileSystem( interpolatedProps ); FileSystem fs = new StringFileSystem( interpolatedProps );
FileBasedConfigurationBuilder<XMLConfiguration> cfgBuilder = FileBasedConfigurationBuilder<XMLConfiguration> cfgBuilder =
new FileBasedConfigurationBuilder<>( new FileBasedConfigurationBuilder<>(
XMLConfiguration.class) XMLConfiguration.class )
.configure(params.xml() .configure( params.xml( )
.setInterpolator( interpolator ) .setInterpolator( interpolator )
.setFileSystem( fs ) .setFileSystem( fs )
.setFileName( "config.xml") .setFileName( "config.xml" )
.setListDelimiterHandler( .setListDelimiterHandler(
new DefaultListDelimiterHandler(',')) new DefaultListDelimiterHandler( ',' ) )
.setExpressionEngine( expressionEngine ) .setExpressionEngine( expressionEngine )
.setThrowExceptionOnMissing(false)); .setThrowExceptionOnMissing( false ) );
CombinedConfigurationBuilder builder = new CombinedConfigurationBuilder(). CombinedConfigurationBuilder builder = new CombinedConfigurationBuilder( ).
configure(params.combined().setDefinitionBuilder( cfgBuilder )); configure( params.combined( ).setDefinitionBuilder( cfgBuilder ) );
// The builder is needed later for saving of the file parts in the combined configuration.
this.configurationBuilder = builder;
configuration = builder.getConfiguration( );
configuration = builder.getConfiguration();
// interpolation as plexus did it before } else
//configuration.set
}
else
{ {
logger.debug( "Creating a default configuration - no configuration was provided" ); logger.debug( "Creating a default configuration - no configuration was provided" );
NodeCombiner combiner = new UnionCombiner(); NodeCombiner combiner = new UnionCombiner( );
configuration = new CombinedConfiguration(combiner); configuration = new CombinedConfiguration( combiner );
this.configurationBuilder = null;
} }
configuration.addConfiguration( new SystemConfiguration(), "SystemProperties" ); // In the end, we add the system properties to the combined configuration
configuration.addConfiguration( new SystemConfiguration( ), "SystemProperties" );
this.configuration = configuration; this.configuration = configuration;
} }
catch ( ConfigurationException e ) catch ( ConfigurationException e )
{ {
throw new RuntimeException( e.getMessage(), e ); logger.error("Fatal error, while reading the configuration definition: "+e.getMessage());
logger.error("The definition was:");
logger.error( combinedConfigurationDefinition );
throw new RuntimeException( e.getMessage( ), e );
} }
} }
public void setProperties( String properties ) public void setCombinedConfigurationDefinition(String combinedConfigurationDefinition)
{ {
this.properties = properties; this.combinedConfigurationDefinition = combinedConfigurationDefinition;
}
public ConfigRegistry getSection( String name )
{
CombinedConfiguration combinedConfiguration = (CombinedConfiguration) configuration;
Configuration configuration = combinedConfiguration.getConfiguration( name );
return configuration == null ? null : new CommonsConfigurationRegistry( configuration );
} }
public String getPropertyDelimiter() public String getPropertyDelimiter()
@ -584,8 +647,19 @@ public class CommonsConfigurationRegistry
return propertyDelimiter; return propertyDelimiter;
} }
public void setPropertyDelimiter( String propertyDelimiter ) public void setPropertyDelimiter(String propertyDelimiter)
{ {
this.propertyDelimiter = propertyDelimiter; this.propertyDelimiter = propertyDelimiter;
} }
public ConfigurationBuilder<? extends Configuration> getConfigurationBuilder()
{
return configurationBuilder;
}
public void setConfigurationBuilder(ConfigurationBuilder<? extends Configuration> configurationBuilder)
{
this.configurationBuilder = configurationBuilder;
}
} }

View File

@ -28,6 +28,7 @@ import org.slf4j.LoggerFactory;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -151,7 +152,6 @@ public class CommonsConfigurationRegistryTest
registry = getRegistry( "default" ); registry = getRegistry( "default" );
registry.addConfigurationFromFile( "test.xml", Paths.get( "src/test/resources/test.xml" ) ); registry.addConfigurationFromFile( "test.xml", Paths.get( "src/test/resources/test.xml" ) );
System.out.println(registry.dump());
assertEquals( "Check system property default", System.getProperty( "user.dir" ), assertEquals( "Check system property default", System.getProperty( "user.dir" ),
registry.getString( "user.dir" ) ); registry.getString( "user.dir" ) );
assertEquals( "Check other properties are loaded", "foo", registry.getString( "test.value" ) ); assertEquals( "Check other properties are loaded", "foo", registry.getString( "test.value" ) );
@ -292,9 +292,9 @@ public class CommonsConfigurationRegistryTest
public void testGetSection() public void testGetSection()
throws Exception throws Exception
{ {
registry = getRegistry( "builder" ); this.registry = getRegistry( "builder" );
ConfigRegistry registry = this.registry.getPartOfCombined( "properties" );
ConfigRegistry registry = this.registry.getSource( "properties" ); assertNotNull(registry);
assertNull( registry.getString( "test.value" ) ); assertNull( registry.getString( "test.value" ) );
assertEquals( "baz", registry.getString( "foo.bar" ) ); assertEquals( "baz", registry.getString( "foo.bar" ) );
} }
@ -304,8 +304,8 @@ public class CommonsConfigurationRegistryTest
throws Exception throws Exception
{ {
registry = getRegistry( "builder" ); registry = getRegistry( "builder" );
assertNotNull(registry);
ConfigRegistry registry = this.registry.getSource( "properties" ); ConfigRegistry registry = this.registry.getPartOfCombined( "properties" );
assertEquals( "baz", registry.getString( "foo.bar" ) ); assertEquals( "baz", registry.getString( "foo.bar" ) );
registry.remove( "foo.bar" ); registry.remove( "foo.bar" );
assertNull( registry.getString( "foo.bar" ) ); assertNull( registry.getString( "foo.bar" ) );
@ -316,11 +316,12 @@ public class CommonsConfigurationRegistryTest
throws Exception throws Exception
{ {
registry = getRegistry( "builder" ); registry = getRegistry( "builder" );
assertNotNull(registry);
registry.removeSubset( "strings" ); registry.removeSubset( "strings" );
assertEquals( Collections.EMPTY_LIST, registry.getList( "strings.string" ) ); assertEquals( Collections.EMPTY_LIST, registry.getList( "strings.string" ) );
ConfigRegistry registry = this.registry.getSource( "properties" ); ConfigRegistry registry = this.registry.getPartOfCombined( "properties" );
assertEquals( "baz", registry.getString( "foo.bar" ) ); assertEquals( "baz", registry.getString( "foo.bar" ) );
registry.remove( "foo" ); registry.remove( "foo" );
assertEquals( "baz", registry.getString( "foo.bar" ) ); assertEquals( "baz", registry.getString( "foo.bar" ) );
@ -347,7 +348,7 @@ public class CommonsConfigurationRegistryTest
{ {
registry = getRegistry( "noForceCreate" ); registry = getRegistry( "noForceCreate" );
assertNull( registry.getSource( "foo" ) ); assertNull( registry.getPartOfCombined( "foo" ) );
} }
@Test @Test
@ -356,11 +357,11 @@ public class CommonsConfigurationRegistryTest
{ {
Path src = Paths.get( "src/test/resources/test-save.xml" ); Path src = Paths.get( "src/test/resources/test-save.xml" );
Path dest = Paths.get( "target/test-classes/test-save.xml" ); Path dest = Paths.get( "target/test-classes/test-save.xml" );
Files.copy( src, dest ); Files.copy( src, dest, StandardCopyOption.REPLACE_EXISTING );
registry = getRegistry( "test-save" ); registry = getRegistry( "test-save" );
ConfigRegistry registry = this.registry.getSource( "org.codehaus.plexus.registry" ); ConfigRegistry registry = this.registry.getPartOfCombined( "org.codehaus.plexus.registry" );
assertEquals( "check list elements", Arrays.asList( new String[]{ "1", "2", "3" } ), assertEquals( "check list elements", Arrays.asList( new String[]{ "1", "2", "3" } ),
registry.getList( "listElements.listElement" ) ); registry.getList( "listElements.listElement" ) );

View File

@ -27,7 +27,7 @@
<alias name="acc2-configuration" alias="default"/> <alias name="acc2-configuration" alias="default"/>
<bean name="builder" class="org.apache.archiva.redback.common.config.acc2.CommonsConfigurationRegistry"> <bean name="builder" class="org.apache.archiva.redback.common.config.acc2.CommonsConfigurationRegistry">
<property name="properties"> <property name="combinedConfigurationDefinition">
<value> <value>
<![CDATA[ <![CDATA[
<configuration> <configuration>
@ -41,7 +41,7 @@
</bean> </bean>
<bean name="test-save" class="org.apache.archiva.redback.common.config.acc2.CommonsConfigurationRegistry"> <bean name="test-save" class="org.apache.archiva.redback.common.config.acc2.CommonsConfigurationRegistry">
<property name="properties"> <property name="combinedConfigurationDefinition">
<value> <value>
<![CDATA[ <![CDATA[
<configuration> <configuration>
@ -75,7 +75,7 @@
</bean> </bean>
<bean name="forceCreate" class="org.apache.archiva.redback.common.config.acc2.CommonsConfigurationRegistry"> <bean name="forceCreate" class="org.apache.archiva.redback.common.config.acc2.CommonsConfigurationRegistry">
<property name="properties"> <property name="combinedConfigurationDefinition">
<value> <value>
<![CDATA[ <![CDATA[
<configuration> <configuration>
@ -87,7 +87,7 @@
</bean> </bean>
<bean name="noForceCreate" class="org.apache.archiva.redback.common.config.acc2.CommonsConfigurationRegistry"> <bean name="noForceCreate" class="org.apache.archiva.redback.common.config.acc2.CommonsConfigurationRegistry">
<property name="properties"> <property name="combinedConfigurationDefinition">
<value> <value>
<![CDATA[ <![CDATA[
<configuration> <configuration>

View File

@ -30,6 +30,8 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>redback-common-configuration-api</artifactId> <artifactId>redback-common-configuration-api</artifactId>
<name>Redback :: Common Configuration API</name>
<description>Configuration API used by different modules.</description>
</project> </project>

View File

@ -207,7 +207,7 @@ public interface ConfigRegistry
* @param name The source name of the configuration source. * @param name The source name of the configuration source.
* @return the The config registry object that represents this source part. * @return the The config registry object that represents this source part.
*/ */
ConfigRegistry getSource( String name ); ConfigRegistry getPartOfCombined(String name );
/** /**
* Save any changes to the registry since it was loaded. * Save any changes to the registry since it was loaded.