Adding classes for listener implementation

This commit is contained in:
Martin Stockhammer 2019-02-18 06:26:31 +01:00
parent 0366cbc7b9
commit 5cd2f362e9
11 changed files with 782 additions and 294 deletions

View File

@ -122,6 +122,12 @@
<artifactId>log4j-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,257 @@
package org.apache.archiva.redback.common.config.acc2;
/*
* 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.redback.common.config.api.AsyncListener;
import org.apache.archiva.redback.common.config.api.ConfigRegistry;
import org.apache.archiva.redback.common.config.api.EventType;
import org.apache.archiva.redback.common.config.api.RegistryListener;
import org.apache.commons.configuration2.event.ConfigurationEvent;
import org.apache.commons.configuration2.event.Event;
import org.apache.commons.configuration2.event.EventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.core.task.TaskExecutor;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.WeakHashMap;
/**
* This class maps apache commons configuration events into redback configuration events.
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class CfgListener implements EventListener
{
ConfigRegistry registry;
Map<String, ListenerInfo> listeners = new LinkedHashMap<>( );
WeakHashMap<EventInfo, Object> oldValueStore = new WeakHashMap<>( );
Logger logger = LoggerFactory.getLogger( CfgListener.class );
CfgListener( ConfigRegistry registry )
{
this.registry = registry;
}
TaskExecutor defaultExecutor;
ApplicationContext applicationContext;
private final class ListenerInfo
{
final String prefix;
final RegistryListener listener;
final boolean async;
final TaskExecutor executor;
public ListenerInfo( String prefix, RegistryListener listener )
{
this.prefix = prefix;
this.listener = listener;
Class<? extends RegistryListener> clazz = listener.getClass( );
boolean async = clazz.isAnnotationPresent( AsyncListener.class );
try
{
AsyncListener classAnnotation = clazz.getAnnotation( AsyncListener.class );
AsyncListener methodAnnotation = clazz.getMethod( "handleConfigurationChangeEvent", ConfigRegistry.class, EventType.class, String.class, Object.class, Object.class ).getAnnotation( AsyncListener.class );
this.async = methodAnnotation != null || classAnnotation != null;
String executorString = methodAnnotation != null ? methodAnnotation.value( ) : ( classAnnotation != null ? classAnnotation.value( ) : null );
TaskExecutor newExec;
if ( executorString == null )
{
newExec = defaultExecutor;
}
else
{
newExec = applicationContext.getBean( executorString, TaskExecutor.class );
if ( newExec == null )
{
newExec = defaultExecutor;
}
}
this.executor = newExec;
}
catch ( NoSuchMethodException e )
{
throw new RuntimeException( "Fatal error! EventListener methods not found. Maybe you have the wrong version of EventLister in your classpath." );
}
}
}
private final class EventInfo
{
final org.apache.commons.configuration2.event.EventType type;
final String name;
final Object value;
EventInfo( org.apache.commons.configuration2.event.EventType type, String name, Object value )
{
this.type = type;
this.name = name;
this.value = value;
}
@Override
public int hashCode( )
{
return Objects.hash( type, name, value );
}
public boolean equals( EventInfo obj )
{
return Objects.equals( this.type, obj.type ) && Objects.equals( this.name, obj.name ) && Objects.equals( this.value, obj.value );
}
}
/**
* This method stores old values in the
* @param event
*/
public void onEvent( org.apache.commons.configuration2.event.ConfigurationEvent event )
{
logger.debug( "Event " + event.getClass( ).getName( ) + " Source Class: " + event.getSource( ).getClass( ).getName( ) );
logger.debug( "EventType " + event.getEventType( ) + ", EventProperty: " + event.getPropertyName( ) + ", EventValue: " + event.getPropertyValue( ) );
if ( event.isBeforeUpdate( ) )
{
logger.debug( "Event before update" );
Object oldValue = registry.getValue( event.getPropertyName( ) );
oldValueStore.put( new EventInfo( event.getEventType( ), event.getPropertyName( ), event.getPropertyValue( ) ), oldValue );
}
else
{
logger.debug( "Event after update" );
final EventType type = transformEventType( event.getEventType( ) );
final Object oldValue = oldValueStore.remove( new EventInfo( event.getEventType( ), event.getPropertyName( ), event.getPropertyValue( ) ) );
final String propertyName = event.getPropertyName();
final Object newValue = event.getPropertyValue();
listeners.entrySet( ).stream( ).filter( entry -> event.getPropertyName( ).startsWith( entry.getKey( ) ) ).forEach(
entry ->
callListener( entry.getValue(), type, propertyName, newValue, oldValue )
);
}
}
private void callListener(ListenerInfo li, EventType type, String propertyName, Object newValue, Object oldValue) {
try
{
if ( li.async )
{
li.executor.execute( ( ) -> li.listener.handleConfigurationChangeEvent( registry, type, propertyName, newValue, oldValue ) );
}
else
{
li.listener.handleConfigurationChangeEvent( registry, type, propertyName, newValue, oldValue );
}
} catch (Throwable ex) {
logger.error( "Listener exception occured: "+ex.getMessage(), ex);
// Exception is catched allow to call the other listeners.
}
}
private EventType transformEventType( org.apache.commons.configuration2.event.EventType<? extends Event> type )
{
if ( type.equals( ConfigurationEvent.ADD_PROPERTY ) )
{
return EventType.PROPERTY_ADDED;
}
else if ( type.equals( ConfigurationEvent.CLEAR_PROPERTY ) )
{
return EventType.PROPERTY_CLEARED;
}
else if ( type.equals( ConfigurationEvent.SET_PROPERTY ) )
{
return EventType.PROPERTY_SET;
}
else
{
return EventType.UNDEFINED;
}
}
@Override
public void onEvent( Event event )
{
if ( event instanceof ConfigurationEvent )
{
onEvent( (ConfigurationEvent) event );
}
else
{
logger.debug( "Event " + event.getClass( ).getName( ) + " Source Class: " + event.getSource( ).getClass( ).getName( ) );
logger.debug( "EventType " + event.getEventType( ) );
}
}
public void registerChangeListener( RegistryListener listener, String prefix )
{
listeners.put( prefix, new ListenerInfo( prefix, listener ) );
}
public boolean unregisterChangeListener( RegistryListener listener )
{
boolean found = false;
Iterator<Map.Entry<String, ListenerInfo>> it = listeners.entrySet( ).iterator( );
while ( it.hasNext( ) )
{
Map.Entry<String, ListenerInfo> e = it.next( );
if ( e.getValue( ).listener == listener )
{
it.remove( );
found = true;
}
}
return found;
}
public TaskExecutor getDefaultExecutor( )
{
return defaultExecutor;
}
public void setDefaultExecutor( TaskExecutor defaultExecutor )
{
this.defaultExecutor = defaultExecutor;
}
public ApplicationContext getApplicationContext( )
{
return applicationContext;
}
public void setApplicationContext( ApplicationContext applicationContext )
{
this.applicationContext = applicationContext;
}
}

View File

@ -28,7 +28,10 @@ import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
import org.apache.commons.configuration2.builder.combined.CombinedConfigurationBuilder;
import org.apache.commons.configuration2.builder.fluent.Parameters;
import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
import org.apache.commons.configuration2.event.ConfigurationEvent;
import org.apache.commons.configuration2.event.EventSource;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.configuration2.ex.ConfigurationRuntimeException;
import org.apache.commons.configuration2.interpol.ConfigurationInterpolator;
import org.apache.commons.configuration2.interpol.DefaultLookups;
import org.apache.commons.configuration2.interpol.InterpolatorSpecification;
@ -51,6 +54,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
@ -65,9 +69,9 @@ import java.util.stream.StreamSupport;
* <a href="http://commons.apache.org/commons/configuration/howto_configurationbuilder.html">configuration
* builder</a>.
*/
@Service("acc2-configuration")
@Service( "acc2-configuration" )
public class CommonsConfigurationRegistry
implements ConfigRegistry
implements ConfigRegistry
{
private static final Pattern DOT_NAME_PATTERN = Pattern.compile( "([^.]+)(\\..*)*" );
@ -78,15 +82,17 @@ public class CommonsConfigurationRegistry
private ConfigurationBuilder<? extends Configuration> configurationBuilder;
boolean combined = true;
private Map<String, ConfigurationBuilder<? extends Configuration>> builderMap = new HashMap<>( );
private boolean combined = true;
private final Map<String, ConfigurationBuilder<? extends Configuration>> builderMap = new HashMap<>( );
private Logger logger = LoggerFactory.getLogger( getClass( ) );
private final Logger logger = LoggerFactory.getLogger( getClass( ) );
private String propertyDelimiter = ".";
private boolean addSystemProperties = false;
final CfgListener listener = new CfgListener( this );
/**
* The configuration properties for the registry. This should take the format of an input to the Commons
* Configuration
@ -96,12 +102,13 @@ public class CommonsConfigurationRegistry
private String combinedConfigurationDefinition;
public CommonsConfigurationRegistry()
public CommonsConfigurationRegistry( )
{
// Default constructor
}
public CommonsConfigurationRegistry(CombinedConfiguration configuration, ConfigurationBuilder<? extends Configuration> configurationBuilder)
public CommonsConfigurationRegistry( CombinedConfiguration configuration, CombinedConfigurationBuilder configurationBuilder )
{
if ( configuration == null )
{
@ -112,76 +119,120 @@ public class CommonsConfigurationRegistry
throw new NullPointerException( "configuration builder cannot be null for a combined configuration" );
}
this.combined = true;
this.configuration = configuration;
setConfiguration(configuration);
this.configurationBuilder = configurationBuilder;
}
public CommonsConfigurationRegistry(Configuration configuration, ConfigurationBuilder<? extends Configuration> configurationBuilder)
@SuppressWarnings( "WeakerAccess" )
public CommonsConfigurationRegistry( Configuration configuration, ConfigurationBuilder<? extends Configuration> configurationBuilder )
{
if ( configuration == null )
{
throw new NullPointerException( "configuration can not be null" );
}
this.configuration = configuration;
setConfiguration(configuration);
this.configurationBuilder = configurationBuilder;
}
public String dump()
{
StringBuilder buffer = new StringBuilder( );
buffer.append( "Configuration Dump." );
for ( Iterator i = configuration.getKeys( ); i.hasNext( ); )
{
String key = ( String ) i.next( );
Object value = configuration.getProperty( key );
buffer.append( "\n\"" ).append( key ).append( "\" = \"" ).append( value ).append( "\"" );
if (configuration instanceof CombinedConfiguration) {
this.combined = true;
}
return buffer.toString( );
}
public boolean isEmpty()
public void setConfiguration( Configuration configuration )
{
this.configuration = configuration;
if (configuration instanceof EventSource ) {
EventSource evs = (EventSource) configuration;
evs.removeEventListener( ConfigurationEvent.ANY, listener );
evs.addEventListener( ConfigurationEvent.ANY, listener );
evs.addEventListener( ConfigurationEvent.SUBNODE_CHANGED, listener );
}
}
@Override
public String dump( )
{
StringBuilder buffer = new StringBuilder( "Configuration Dump:\n");
Iterable<String> it = () -> configuration.getKeys();
return buffer.append(StreamSupport.stream( it.spliterator(), false ).map( k ->
"\""+k+"\" = \""+configuration.getProperty( k ).toString() + "\"").collect(Collectors.joining( "\n" ) )).toString();
}
@Override
public boolean isEmpty( )
{
return configuration.isEmpty( );
}
public ConfigRegistry getSubset(String key)
@Override
public ConfigRegistry getSubset( String key ) throws RegistryException
{
if (configuration instanceof BaseHierarchicalConfiguration) {
BaseHierarchicalConfiguration cfg = (BaseHierarchicalConfiguration) configuration;
if (cfg.containsKey( key ))
{
try
{
return new CommonsConfigurationRegistry( cfg.configurationAt( key, true ), null );
} catch ( ConfigurationRuntimeException ex ) {
logger.error("There are multiple entries for the given key");
throw new RegistryException( "Subset for multiple key entries is not possible.");
}
} else {
return new CommonsConfigurationRegistry( cfg.subset( key ), null );
}
}
return new CommonsConfigurationRegistry( configuration.subset( key ), configurationBuilder );
}
public List<String> getList(String key)
@Override
public List<String> getList( String key )
{
List<String> result = configuration.getList( String.class, key );
return result == null ? new ArrayList<>( ) : result;
}
public List<ConfigRegistry> getSubsetList(String key)
@Override
public List<ConfigRegistry> getSubsetList( String key ) throws RegistryException
{
List<ConfigRegistry> subsets = new ArrayList<>( );
boolean done = false;
do
if (configuration instanceof BaseHierarchicalConfiguration) {
BaseHierarchicalConfiguration cfg = (BaseHierarchicalConfiguration)configuration;
return cfg.configurationsAt( key, true ).stream().map(c -> new CommonsConfigurationRegistry( c, null )).collect( Collectors.toList() );
} else
{
ConfigRegistry registry = getSubset( key + "(" + subsets.size( ) + ")" );
if ( !registry.isEmpty( ) )
List<ConfigRegistry> subsets = new ArrayList<>( );
boolean done = false;
do
{
subsets.add( registry );
} else
{
done = true;
ConfigRegistry registry = null;
try
{
registry = getSubset( key + "(" + subsets.size( ) + ")" );
}
catch ( RegistryException e )
{
throw new RegistryException( "Could not retrieve subset from key "+key+": "+e.getMessage() );
}
if ( !registry.isEmpty( ) )
{
subsets.add( registry );
}
else
{
done = true;
}
}
while ( !done );
return subsets;
}
while ( !done );
return subsets;
}
@Override
public ConfigRegistry getPartOfCombined(String name)
public ConfigRegistry getPartOfCombined( String name )
{
if ( combined )
{
CombinedConfiguration config = ( CombinedConfiguration ) configuration;
CombinedConfiguration config = (CombinedConfiguration) configuration;
Configuration newCfg = config.getConfiguration( name );
ConfigurationBuilder<? extends Configuration> cfgBuilder = null;
try
@ -189,10 +240,11 @@ public class CommonsConfigurationRegistry
if ( builderMap.containsKey( name ) )
{
cfgBuilder = builderMap.get( name );
} else
}
else
{
cfgBuilder = configurationBuilder == null ? null :
(( CombinedConfigurationBuilder ) configurationBuilder).getNamedBuilder( name );
( (CombinedConfigurationBuilder) configurationBuilder ).getNamedBuilder( name );
builderMap.put( name, cfgBuilder );
}
}
@ -205,7 +257,8 @@ public class CommonsConfigurationRegistry
return null;
}
public Map<String, String> getProperties(String key)
@Override
public Map<String, String> getProperties( String key )
{
Configuration configuration = this.configuration.subset( key );
@ -222,18 +275,20 @@ public class CommonsConfigurationRegistry
return properties;
}
public void save()
throws RegistryException
@Override
public void save( )
throws RegistryException
{
if ( configuration instanceof FileBasedConfiguration )
{
FileBasedConfiguration fileConfiguration = ( FileBasedConfiguration ) configuration;
FileBasedConfiguration fileConfiguration = (FileBasedConfiguration) configuration;
FileHandler fileHandler;
if ( configurationBuilder != null && configurationBuilder instanceof FileBasedConfigurationBuilder )
{
FileBasedConfigurationBuilder cfgBuilder = ( FileBasedConfigurationBuilder ) configurationBuilder;
FileBasedConfigurationBuilder cfgBuilder = (FileBasedConfigurationBuilder) configurationBuilder;
fileHandler = cfgBuilder.getFileHandler( );
} else
}
else
{
fileHandler = new FileHandler( fileConfiguration );
}
@ -245,177 +300,198 @@ public class CommonsConfigurationRegistry
{
throw new RegistryException( e.getMessage( ), e );
}
} else
}
else
{
throw new RegistryException( "Can only save file-based configurations" );
}
}
@Override
public void registerChangeListener(RegistryListener listener, Pattern... filter)
public void registerChangeListener( RegistryListener listener, String prefix)
{
this.listener.registerChangeListener(listener, prefix);
}
@Override
public boolean unregisterChangeListener( RegistryListener listener )
{
return this.listener.unregisterChangeListener(listener);
}
@Override
public Collection<String> getBaseKeys( )
{
Iterable<String> iterable = ( ) -> configuration.getKeys( );
return StreamSupport.stream( iterable.spliterator( ), true )
.map( DOT_NAME_PATTERN::matcher )
.filter( Matcher::matches )
.map( k -> k.group( 1 ) ).collect( Collectors.toSet( ) );
}
@Override
public boolean unregisterChangeListener(RegistryListener listener)
public Collection<String> getKeys( )
{
return false;
Iterable<String> iterable = ( ) -> configuration.getKeys( );
return StreamSupport.stream( iterable.spliterator( ), true ).collect( Collectors.toSet( ) );
}
public Collection<String> getKeys()
@Override
public Collection<String> getKeys( String prefix )
{
Iterable<String> iterable = () -> configuration.getKeys( );
return StreamSupport.stream( iterable.spliterator( ), false )
.map( k -> DOT_NAME_PATTERN.matcher( k ) )
.filter( k -> k.matches( ) )
.map( k -> k.group( 1 ) ).collect( Collectors.toSet( ) );
Iterable<String> iterable = ( ) -> configuration.getKeys( prefix );
return StreamSupport.stream( iterable.spliterator( ), true ).collect( Collectors.toSet( ) );
}
public Collection getFullKeys()
{
Iterable<String> iterable = () -> configuration.getKeys( );
return StreamSupport.stream( iterable.spliterator( ), false ).collect( Collectors.toSet( ) );
}
public void remove(String key)
@Override
public void remove( String key )
{
configuration.clearProperty( key );
}
public void removeSubset(String key)
@Override
public void removeSubset( String key )
{
// create temporary list since removing a key will modify the iterator from configuration
List keys = new ArrayList( );
for ( Iterator i = configuration.getKeys( key ); i.hasNext( ); )
{
keys.add( i.next( ) );
}
for ( Iterator i = keys.iterator( ); i.hasNext( ); )
{
configuration.clearProperty( ( String ) i.next( ) );
}
getKeys( key ).forEach( k -> configuration.clearProperty( k ) );
}
public String getString(String key)
@Override
public Object getValue( String key ) {
return configuration.getProperty( key );
}
@Override
public String getString( String key )
{
return configuration.getString( key );
}
public String getString(String key, String defaultValue)
@Override
public String getString( String key, String defaultValue )
{
return configuration.getString( key, defaultValue );
}
public void setString(String key, String value)
@Override
public void setString( String key, String value )
{
configuration.setProperty( key, value );
}
public int getInt(String key)
@Override
public int getInt( String key )
{
return configuration.getInt( key );
}
public int getInt(String key, int defaultValue)
@Override
public int getInt( String key, int defaultValue )
{
return configuration.getInt( key, defaultValue );
}
public void setInt(String key, int value)
@Override
public void setInt( String key, int value )
{
configuration.setProperty( key, Integer.valueOf( value ) );
configuration.setProperty( key, value );
}
public boolean getBoolean(String key)
@Override
public boolean getBoolean( String key )
{
return configuration.getBoolean( key );
}
public boolean getBoolean(String key, boolean defaultValue)
@Override
public boolean getBoolean( String key, boolean defaultValue )
{
return configuration.getBoolean( key, defaultValue );
}
public void setBoolean(String key, boolean value)
@Override
public void setBoolean( String key, boolean value )
{
configuration.setProperty( key, Boolean.valueOf( value ) );
configuration.setProperty( key, value );
}
public void addConfigurationFromResource(String name, String resource)
throws RegistryException
@Override
public void addConfigurationFromResource( String name, String resource )
throws RegistryException
{
addConfigurationFromResource( name, resource, null );
}
public void addConfigurationFromResource(String name, String resource, String prefix)
throws RegistryException
@Override
public void addConfigurationFromResource( String name, String resource, String prefix )
throws RegistryException
{
if ( configuration instanceof CombinedConfiguration )
{
String atPrefix = StringUtils.isEmpty( prefix ) ? null : prefix;
CombinedConfiguration configuration = ( CombinedConfiguration ) this.configuration;
CombinedConfiguration configuration = (CombinedConfiguration) this.configuration;
if ( resource.endsWith( ".properties" ) )
{
try
{
logger.debug( "Loading properties configuration from classloader resource: {}", resource );
FileBasedConfigurationBuilder<PropertiesConfiguration> builder = new FileBasedConfigurationBuilder<>( PropertiesConfiguration.class )
.configure( new Parameters( ).properties( )
.setLocationStrategy( new ClasspathLocationStrategy( ) )
.setFileName( resource ) );
.configure( new Parameters( ).properties( )
.setLocationStrategy( new ClasspathLocationStrategy( ) )
.setFileName( resource ) );
builderMap.put( name, builder );
configuration.addConfiguration( builder.getConfiguration( ), name, atPrefix );
}
catch ( ConfigurationException e )
{
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
{
logger.debug( "Loading XML configuration from classloader resource: {}", resource );
FileBasedConfigurationBuilder<XMLConfiguration> builder = new FileBasedConfigurationBuilder<>( XMLConfiguration.class )
.configure( new Parameters( ).xml( )
.setLocationStrategy( new ClasspathLocationStrategy( ) )
.setFileName( resource ) );
.configure( new Parameters( ).xml( )
.setLocationStrategy( new ClasspathLocationStrategy( ) )
.setFileName( resource ) );
builderMap.put( name, builder );
configuration.addConfiguration( builder.getConfiguration( ), name, atPrefix );
}
catch ( ConfigurationException e )
{
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(
"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 " );
}
}
@Override
public void addConfigurationFromFile(String name, Path file) throws RegistryException
public void addConfigurationFromFile( String name, Path file ) throws RegistryException
{
addConfigurationFromFile( name, file, "" );
}
public void addConfigurationFromFile(String name, Path file, String prefix)
throws RegistryException
@Override
public void addConfigurationFromFile( String name, Path file, String prefix )
throws RegistryException
{
if ( this.configuration instanceof CombinedConfiguration )
{
String atPrefix = StringUtils.isEmpty( prefix ) ? null : prefix;
CombinedConfiguration configuration = ( CombinedConfiguration ) this.configuration;
CombinedConfiguration configuration = (CombinedConfiguration) this.configuration;
String fileName = file.getFileName( ).toString( );
if ( fileName.endsWith( ".properties" ) )
{
@ -423,10 +499,10 @@ public class CommonsConfigurationRegistry
{
logger.debug( "Loading properties configuration from file: {}", file );
FileBasedConfigurationBuilder<PropertiesConfiguration> builder = new FileBasedConfigurationBuilder<>( PropertiesConfiguration.class )
.configure( new Parameters( ).properties( )
.setFileSystem( FileLocatorUtils.DEFAULT_FILE_SYSTEM )
.setLocationStrategy( FileLocatorUtils.DEFAULT_LOCATION_STRATEGY )
.setFile( file.toFile( ) ) );
.configure( new Parameters( ).properties( )
.setFileSystem( FileLocatorUtils.DEFAULT_FILE_SYSTEM )
.setLocationStrategy( FileLocatorUtils.DEFAULT_LOCATION_STRATEGY )
.setFile( file.toFile( ) ) );
// builder is needed for save
builderMap.put( name, builder );
configuration.addConfiguration( builder.getConfiguration( ), name, atPrefix );
@ -434,32 +510,35 @@ public class CommonsConfigurationRegistry
catch ( ConfigurationException e )
{
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
{
logger.debug( "Loading XML configuration from file: {}", file );
FileBasedConfigurationBuilder<XMLConfiguration> builder = new FileBasedConfigurationBuilder<>( XMLConfiguration.class )
.configure( new Parameters( ).xml( )
.setFileSystem( FileLocatorUtils.DEFAULT_FILE_SYSTEM )
.setLocationStrategy( FileLocatorUtils.DEFAULT_LOCATION_STRATEGY )
.setFile( file.toFile( ) ) );
.configure( new Parameters( ).xml( )
.setFileSystem( FileLocatorUtils.DEFAULT_FILE_SYSTEM )
.setLocationStrategy( FileLocatorUtils.DEFAULT_LOCATION_STRATEGY )
.setFile( file.toFile( ) ) );
builderMap.put( name, builder );
configuration.addConfiguration( builder.getConfiguration( ), name, atPrefix );
}
catch ( ConfigurationException e )
{
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(
"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." );
}
@ -471,22 +550,24 @@ public class CommonsConfigurationRegistry
class StringFileSystem extends FileSystem
{
String content;
final String content;
String encoding = "UTF-8";
StringFileSystem(String content)
StringFileSystem( String content )
{
this.content = content;
}
StringFileSystem(String encoding, String content)
@SuppressWarnings( "unused" )
StringFileSystem( String encoding, String content )
{
this.encoding = encoding;
this.content = content;
}
@Override
public InputStream getInputStream(URL url) throws ConfigurationException
public InputStream getInputStream( URL url ) throws ConfigurationException
{
try
{
@ -500,37 +581,37 @@ public class CommonsConfigurationRegistry
}
@Override
public OutputStream getOutputStream(URL url) throws ConfigurationException
public OutputStream getOutputStream( URL url )
{
return new ByteArrayOutputStream( 0 );
}
@Override
public OutputStream getOutputStream(File file) throws ConfigurationException
public OutputStream getOutputStream( File file )
{
return new ByteArrayOutputStream( 0 );
}
@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;
}
@Override
public String getBasePath(String path)
public String getBasePath( String path )
{
return path;
}
@Override
public String getFileName(String path)
public String getFileName( String path )
{
return path;
}
@Override
public URL locateFromURL(String basePath, String fileName)
public URL locateFromURL( String basePath, String fileName )
{
try
{
@ -544,24 +625,17 @@ public class CommonsConfigurationRegistry
}
@Override
public URL getURL(String basePath, String fileName) throws MalformedURLException
public URL getURL( String basePath, String fileName ) throws MalformedURLException
{
try
{
return new URL( "file://" + getPath( null, null, basePath, fileName ) );
}
catch ( MalformedURLException e )
{
// ignore
return null;
}
return new URL( "file://" + getPath( null, null, basePath, fileName ) );
}
}
@Override
@PostConstruct
public void initialize()
throws RegistryException
public void initialize( )
throws RegistryException
{
try
{
@ -571,11 +645,11 @@ public class CommonsConfigurationRegistry
String interpolatedProps;
Parameters params = new Parameters( );
DefaultExpressionEngineSymbols symbols = new DefaultExpressionEngineSymbols.Builder( DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS )
.setPropertyDelimiter( propertyDelimiter )
.setIndexStart( "(" )
.setIndexEnd( ")" )
.setEscapedDelimiter( "\\" + propertyDelimiter )
.create( );
.setPropertyDelimiter( propertyDelimiter )
.setIndexStart( "(" )
.setIndexEnd( ")" )
.setEscapedDelimiter( "\\" + propertyDelimiter )
.create( );
DefaultExpressionEngine expressionEngine = new DefaultExpressionEngine( symbols );
// It allows to use system properties in the XML declaration.
@ -587,24 +661,25 @@ public class CommonsConfigurationRegistry
// for the sources that are used for the CombinedConfiguration.
FileSystem fs = new StringFileSystem( interpolatedProps );
FileBasedConfigurationBuilder<XMLConfiguration> cfgBuilder =
new FileBasedConfigurationBuilder<>(
XMLConfiguration.class )
.configure( params.xml( )
.setFileSystem( fs )
.setFileName( "config.xml" )
.setListDelimiterHandler(
new DefaultListDelimiterHandler( ',' ) )
.setExpressionEngine( expressionEngine )
.setThrowExceptionOnMissing( false ) );
new FileBasedConfigurationBuilder<>(
XMLConfiguration.class )
.configure( params.xml( )
.setFileSystem( fs )
.setFileName( "config.xml" )
.setListDelimiterHandler(
new DefaultListDelimiterHandler( ',' ) )
.setExpressionEngine( expressionEngine )
.setThrowExceptionOnMissing( false ) );
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( );
} else
}
else
{
logger.debug( "Creating a default configuration - no configuration was provided" );
NodeCombiner combiner = new UnionCombiner( );
@ -625,43 +700,38 @@ public class CommonsConfigurationRegistry
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 );
throw new RegistryException( e.getMessage( ), e );
}
}
public void setCombinedConfigurationDefinition(String combinedConfigurationDefinition)
public void setCombinedConfigurationDefinition( String combinedConfigurationDefinition )
{
this.combinedConfigurationDefinition = combinedConfigurationDefinition;
}
public String getPropertyDelimiter()
public String getPropertyDelimiter( )
{
return propertyDelimiter;
}
public void setPropertyDelimiter(String propertyDelimiter)
public void setPropertyDelimiter( String propertyDelimiter )
{
this.propertyDelimiter = propertyDelimiter;
}
public ConfigurationBuilder<? extends Configuration> getConfigurationBuilder()
public ConfigurationBuilder<? extends Configuration> getConfigurationBuilder( )
{
return configurationBuilder;
}
public void setConfigurationBuilder(ConfigurationBuilder<? extends Configuration> configurationBuilder)
{
this.configurationBuilder = configurationBuilder;
}
/**
* Returns true, if the system properties are added to the base configuration. Otherwise system properties
* can be interpolated by ${sys:var} syntax.
* can still be interpolated by ${sys:var} syntax.
*
* @return
* @return True, if system properties are added to the configuration root
*/
public boolean isAddSystemProperties()
public boolean isAddSystemProperties( )
{
return addSystemProperties;
}
@ -670,9 +740,9 @@ public class CommonsConfigurationRegistry
* Set to true, if the system properties should be added to the base configuration.
* If set to false, system properties are no direct part of the configuration.
*
* @param addSystemProperties
* @param addSystemProperties True, or false.
*/
public void setAddSystemProperties(boolean addSystemProperties)
public void setAddSystemProperties( boolean addSystemProperties )
{
this.addSystemProperties = addSystemProperties;
}

View File

@ -82,7 +82,7 @@ public abstract class AbstractRegistryTest
try
{
registry.getInt( "unknown" );
assertTrue( "no NoSuchElementException", false );
fail( "no NoSuchElementException" );
}
catch ( NoSuchElementException e )
{
@ -113,7 +113,7 @@ public abstract class AbstractRegistryTest
throws Exception
{
ConfigRegistry registry = getRegistry();
assertEquals( "not true ", true, registry.getBoolean( "boolean" ) );
assertTrue( "not true ", registry.getBoolean( "boolean" ) );
}
@Test
@ -124,7 +124,7 @@ public abstract class AbstractRegistryTest
try
{
registry.getBoolean( "unknown" );
assertTrue( "no NoSuchElementException", false );
fail( "no NoSuchElementException" );
}
catch ( NoSuchElementException e )
{

View File

@ -32,7 +32,6 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.rmi.registry.Registry;
import java.util.*;
/**
@ -48,84 +47,108 @@ public class CommonsConfigurationRegistryTest
private static final int INT_TEST_VALUE = 8080;
public String getRoleHint()
public String getRoleHint( )
{
return "builder";
}
@Test
public void requirementTest() {
assertNotNull(System.getProperty("basedir"));
assertTrue( System.getProperty( "basedir" ).length()>0 );
assertNotNull(System.getProperty("user.dir"));
assertTrue( System.getProperty( "user.dir" ).length()>0 );
public void requirementTest( )
{
assertNotNull( System.getProperty( "basedir" ) );
assertTrue( System.getProperty( "basedir" ).length( ) > 0 );
assertNotNull( System.getProperty( "user.dir" ) );
assertTrue( System.getProperty( "user.dir" ).length( ) > 0 );
}
@Test
public void testDefaultConfiguration()
public void testDefaultConfiguration( )
throws Exception
{
registry = getRegistry( "default" , true);
registry = getRegistry( "default", true );
assertEquals( "Check system property override", System.getProperty( "user.dir" ),
registry.getString( "user.dir" ) );
registry.getString( "user.dir" ) );
assertEquals( "Check system property", System.getProperty( "user.home" ), registry.getString( "user.home" ) );
assertNull( "Check other properties are not loaded", registry.getString( "test.value" ) );
}
@Test
public void testGetKeys() throws Exception
public void testGetKeys( ) throws Exception
{
registry = getRegistry( "builder" );
Collection<String> keys = registry.getBaseKeys( );
HashSet<Object> expectedKeySet = new HashSet<>( );
expectedKeySet.add( "test" );
expectedKeySet.add( "repository" );
expectedKeySet.add( "objects" );
expectedKeySet.add( "properties" );
expectedKeySet.add( "strings" );
expectedKeySet.add( "user" );
expectedKeySet.add( "foo" );
expectedKeySet.add( "string" );
expectedKeySet.add( "boolean" );
expectedKeySet.add( "subOne" );
expectedKeySet.add( "two" );
assertEquals( expectedKeySet, keys );
}
@Test
public void testGetFullKeys( ) throws Exception
{
registry = getRegistry( "builder" );
Collection<String> keys = registry.getKeys( );
HashSet<Object> expectedKeySet = new HashSet<>( );
expectedKeySet.add("test");
expectedKeySet.add("repository");
expectedKeySet.add("objects");
expectedKeySet.add("properties");
expectedKeySet.add("strings");
expectedKeySet.add("user");
expectedKeySet.add("foo");
expectedKeySet.add("string");
expectedKeySet.add("boolean");
expectedKeySet.add("subOne");
expectedKeySet.add( "two" );
String[] expStrings = new String[]{
"test.value",
"test.number",
"test.boolean",
"test.interpolation",
"repository",
"objects.object.foo",
"properties.foo",
"properties.bar",
"strings.string",
"user.dir",
"foo.bar",
"subOne.firstEntry",
"subOne.secondEntry",
"two",
"string",
"boolean"
};
Collections.addAll( expectedKeySet, expStrings );
assertEquals( expectedKeySet, keys );
expectedKeySet.clear();
}
@Test
public void testBuilderConfiguration()
public void testBuilderConfiguration( )
throws Exception
{
registry = getRegistry( "builder", true );
assertEquals( "Check system property override", "new user dir", registry.getString( "user.dir" ) );
assertEquals( "Check system property default", System.getProperty( "user.home" ),
registry.getString( "user.home" ) );
registry.getString( "user.home" ) );
assertEquals( "Check other properties are loaded", "foo", registry.getString( "test.value" ) );
assertEquals( "Check other properties are loaded", 1, registry.getInt( "test.number" ) );
assertTrue( "Check other properties are loaded", registry.getBoolean( "test.boolean" ) );
}
@Test
public void testDump()
public void testDump( )
throws Exception
{
registry = getRegistry( "default" );
String dump = registry.dump();
System.out.println( dump );
assertTrue( dump.startsWith( "Configuration Dump." ) );
registry = getRegistry( "builder" );
String dump = registry.dump( );
System.out.println(dump);
assertTrue( dump.startsWith( "Configuration Dump:" ) );
assertTrue( dump.contains( "\"properties.foo\" = \"bar\"" ));
}
@Test
public void testDefaults()
public void testDefaults( )
throws Exception
{
registry = getRegistry( "builder" );
@ -136,7 +159,7 @@ public class CommonsConfigurationRegistryTest
try
{
registry.getInt( "foo" );
fail();
fail( );
}
catch ( NoSuchElementException e )
{
@ -148,7 +171,7 @@ public class CommonsConfigurationRegistryTest
try
{
registry.getBoolean( "foo" );
fail();
fail( );
}
catch ( NoSuchElementException e )
{
@ -159,60 +182,60 @@ public class CommonsConfigurationRegistryTest
}
@Test
public void testInterpolation()
public void testInterpolation( )
throws Exception
{
registry = getRegistry( "builder" , true );
registry = getRegistry( "builder", true );
assertEquals( "Check system property interpolation", System.getProperty( "user.home" ) + "/.m2/repository",
registry.getString( "repository" ) );
registry.getString( "repository" ) );
assertEquals( "Check configuration value interpolation", "foo/bar",
registry.getString( "test.interpolation" ) );
registry.getString( "test.interpolation" ) );
}
@Test
public void testAddConfigurationXmlFile()
public void testAddConfigurationXmlFile( )
throws Exception
{
registry = getRegistry( "default" , true);
registry = getRegistry( "default", true );
registry.addConfigurationFromFile( "test.xml", Paths.get( "src/test/resources/test.xml" ) );
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" ) );
}
@Test
public void testAddConfigurationPropertiesFile()
public void testAddConfigurationPropertiesFile( )
throws Exception
{
registry = getRegistry( "default", true );
registry.addConfigurationFromFile(
"test.properties", Paths.get("src/test/resources/test.properties" ) );
"test.properties", Paths.get( "src/test/resources/test.properties" ) );
assertEquals( "Check system property default", System.getProperty( "user.dir" ),
registry.getString( "user.dir" ) );
registry.getString( "user.dir" ) );
assertEquals( "Check other properties are loaded", "baz", registry.getString( "foo.bar" ) );
assertNull( "Check other properties are not loaded", registry.getString( "test.value" ) );
}
@Test
public void testAddConfigurationXmlResource()
public void testAddConfigurationXmlResource( )
throws Exception
{
registry = getRegistry( "default" , true);
registry = getRegistry( "default", true );
registry.addConfigurationFromResource( "test.xml-r", "test.xml" );
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" ) );
}
@Test
public void testAddConfigurationPropertiesResource()
public void testAddConfigurationPropertiesResource( )
throws Exception
{
registry = getRegistry( "default", true );
@ -220,13 +243,13 @@ public class CommonsConfigurationRegistryTest
registry.addConfigurationFromResource( "test.properties-r", "test.properties" );
assertEquals( "Check system property default", System.getProperty( "user.dir" ),
registry.getString( "user.dir" ) );
registry.getString( "user.dir" ) );
assertEquals( "Check other properties are loaded", "baz", registry.getString( "foo.bar" ) );
assertNull( "Check other properties are not loaded", registry.getString( "test.value" ) );
}
@Test
public void testAddConfigurationUnrecognisedType()
public void testAddConfigurationUnrecognisedType( )
throws Exception
{
registry = getRegistry( "default" );
@ -234,7 +257,7 @@ public class CommonsConfigurationRegistryTest
try
{
registry.addConfigurationFromResource( "test.foo", "test.foo" );
fail();
fail( );
}
catch ( RegistryException e )
{
@ -245,7 +268,7 @@ public class CommonsConfigurationRegistryTest
{
registry.addConfigurationFromFile( "test.foo-file",
Paths.get( "src/test/resources/test.foo" ) );
fail();
fail( );
}
catch ( RegistryException e )
{
@ -254,26 +277,25 @@ public class CommonsConfigurationRegistryTest
}
@Test
public void testIsEmpty()
public void testIsEmpty( )
throws Exception
{
registry = getRegistry( "default", true );
assertFalse( registry.isEmpty() );
assertTrue( registry.getSubset( "foo" ).isEmpty() );
assertFalse( registry.isEmpty( ) );
assertTrue( registry.getSubset( "foo" ).isEmpty( ) );
}
@Test
public void testIsEmptyWithoutSysProps()
throws Exception
public void testIsEmptyWithoutSysProps( )
throws Exception
{
registry = getRegistry( "default");
registry = getRegistry( "default" );
assertTrue( registry.isEmpty() );
assertTrue( registry.isEmpty( ) );
}
@Test
public void testGetSubset()
public void testGetSubset( )
throws Exception
{
registry = getRegistry( "builder" );
@ -285,13 +307,13 @@ public class CommonsConfigurationRegistryTest
}
@Test
public void testGetSubsetList()
public void testGetSubsetList( )
throws Exception
{
registry = getRegistry( "builder" );
List list = registry.getSubsetList( "objects.object" );
assertEquals( 2, list.size() );
assertEquals( 2, list.size( ) );
ConfigRegistry r = (ConfigRegistry) list.get( 0 );
assertTrue( "bar".equals( r.getString( "foo" ) ) || "baz".equals( r.getString( "foo" ) ) );
r = (ConfigRegistry) list.get( 1 );
@ -299,47 +321,47 @@ public class CommonsConfigurationRegistryTest
}
@Test
public void testGetProperties()
public void testGetProperties( )
throws Exception
{
registry = getRegistry( "builder" );
Map<String,String> properties = registry.getProperties( "properties" );
assertEquals( 2, properties.size() );
Map<String, String> properties = registry.getProperties( "properties" );
assertEquals( 2, properties.size( ) );
assertEquals( "bar", properties.get( "foo" ) );
assertEquals( "baz", properties.get( "bar" ) );
}
@Test
public void testGetList()
public void testGetList( )
throws Exception
{
registry = getRegistry( "builder" );
List list = registry.getList( "strings.string" );
assertEquals( 3, list.size() );
assertEquals( 3, list.size( ) );
assertEquals( "s1", list.get( 0 ) );
assertEquals( "s2", list.get( 1 ) );
assertEquals( "s3", list.get( 2 ) );
}
@Test
public void testGetSection()
public void testGetSection( )
throws Exception
{
this.registry = getRegistry( "builder" );
ConfigRegistry registry = this.registry.getPartOfCombined( "properties" );
assertNotNull(registry);
assertNotNull( registry );
assertNull( registry.getString( "test.value" ) );
assertEquals( "baz", registry.getString( "foo.bar" ) );
}
@Test
public void testRemoveKey()
public void testRemoveKey( )
throws Exception
{
registry = getRegistry( "builder" );
assertNotNull(registry);
assertNotNull( registry );
ConfigRegistry registry = this.registry.getPartOfCombined( "properties" );
assertEquals( "baz", registry.getString( "foo.bar" ) );
registry.remove( "foo.bar" );
@ -347,11 +369,11 @@ public class CommonsConfigurationRegistryTest
}
@Test
public void testRemoveSubset()
public void testRemoveSubset( )
throws Exception
{
registry = getRegistry( "builder" );
assertNotNull(registry);
assertNotNull( registry );
registry.removeSubset( "strings" );
assertEquals( Collections.EMPTY_LIST, registry.getList( "strings.string" ) );
@ -378,7 +400,7 @@ public class CommonsConfigurationRegistryTest
*/
@Test
public void testGetDontForceCreateByName()
public void testGetDontForceCreateByName( )
throws Exception
{
registry = getRegistry( "noForceCreate" );
@ -387,7 +409,7 @@ public class CommonsConfigurationRegistryTest
}
@Test
public void testSaveSection()
public void testSaveSection( )
throws Exception
{
Path src = Paths.get( "src/test/resources/test-save.xml" );
@ -397,24 +419,24 @@ public class CommonsConfigurationRegistryTest
registry = getRegistry( "test-save" );
ConfigRegistry registry = this.registry.getPartOfCombined( "org.codehaus.plexus.registry" );
assertEquals( "check list elements", Arrays.asList( new String[]{ "1", "2", "3" } ),
registry.getList( "listElements.listElement" ) );
assertEquals( "check list elements", Arrays.asList( new String[]{"1", "2", "3"} ),
registry.getList( "listElements.listElement" ) );
registry.remove( "listElements.listElement(1)" );
registry.save();
registry.save( );
FileBasedConfigurationBuilder<XMLConfiguration> builder = new FileBasedConfigurationBuilder<>( XMLConfiguration.class)
.configure( new Parameters().xml().setFile(dest.toFile()) );
XMLConfiguration configuration = builder.getConfiguration();
assertEquals( Arrays.asList( new String[]{ "1", "3" } ), configuration.getList( "listElements.listElement" ) );
FileBasedConfigurationBuilder<XMLConfiguration> builder = new FileBasedConfigurationBuilder<>( XMLConfiguration.class )
.configure( new Parameters( ).xml( ).setFile( dest.toFile( ) ) );
XMLConfiguration configuration = builder.getConfiguration( );
assertEquals( Arrays.asList( new String[]{"1", "3"} ), configuration.getList( "listElements.listElement" ) );
// file in ${basedir}/target/conf/shared.xml
ConfigRegistry section = this.registry.getPartOfCombined( "org.apache.maven.shared.app.user" );
section.setString( "foo", "zloug" );
section.save();
builder = new FileBasedConfigurationBuilder<>( XMLConfiguration.class)
.configure( new Parameters().xml().setFile( Paths.get("target/conf/shared.xml").toFile() ) );
configuration = builder.getConfiguration();
section.save( );
builder = new FileBasedConfigurationBuilder<>( XMLConfiguration.class )
.configure( new Parameters( ).xml( ).setFile( Paths.get( "target/conf/shared.xml" ).toFile( ) ) );
configuration = builder.getConfiguration( );
assertNotNull( configuration.getString( "foo" ) );
}

View File

@ -0,0 +1,37 @@
package org.apache.archiva.redback.common.config.acc2;
/*
* 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.redback.common.config.api.ConfigRegistry;
import org.apache.archiva.redback.common.config.api.EventType;
import org.apache.archiva.redback.common.config.api.RegistryListener;
/**
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class MockChangeListener implements RegistryListener
{
@Override
public void handleConfigurationChangeEvent( ConfigRegistry registry, EventType eventType, String propertyName, Object propertyValue, Object oldValue )
{
}
}

View File

@ -26,13 +26,17 @@
</appenders>
<loggers>
<logger name="org.apache.archiva.redback" level="INFO" />
<logger name="commons.beanutils" level="ERROR" />
<logger name="commons.beanutils.FluentPropertyBeanIntrospector" level="ERROR" />
<logger name="org.apache.cxf" level="info"/>
<logger name="org.springframework" level="error"/>
<logger name="org.apache.archiva.redback.components.cache" level="error"/>
<logger name="org.apache.archiva.redback.rest" level="error"/>
<logger name="org.springframework" level="ERROR"/>
<logger name="org.apache.archiva.redback.components.cache" level="ERROR"/>
<logger name="org.apache.archiva.redback.rest" level="ERROR"/>
<logger name="org.apache.catalina" level="off" />
<logger name="JPOX" level="ERROR"/>
<root level="info">
<logger name="org.apache.archiva.redback.common.config.acc2.CfgListener" level="DEBUG" />
<root level="ERROR">
<appender-ref ref="console"/>
</root>
</loggers>

View File

@ -0,0 +1,49 @@
package org.apache.archiva.redback.common.config.api;
/*
* 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 java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
*
* A annotation that marks a event listener method as asynchronous. That means the listener event methods
* are run in a separated thread. How tasks are executed is dependent on the implementation.
*
* @author Martin Stockhammer <martin_s@apache.org>
* @since 3.0
*/
@Target(value={METHOD, TYPE})
@Retention(value=RUNTIME)
@Documented
public @interface AsyncListener
{
/**
* May be set to set the executor. The meaning of this value is implementation specific.
* @return The value.
*/
String value() default "";
}

View File

@ -23,6 +23,7 @@ import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.regex.Pattern;
/**
@ -48,6 +49,14 @@ public interface ConfigRegistry
*/
String dump( );
/**
* Get the original value stored in the registry. If not found, <code>null</code> is returned.
*
* @param key The key in the registry.
* @return The value.
*/
Object getValue( String key);
/**
* Get a string value from the registry. If not found, <code>null</code> is returned.
*
@ -81,7 +90,7 @@ public interface ConfigRegistry
* @throws java.util.NoSuchElementException
* if the key is not found
*/
int getInt( String key );
int getInt( String key ) throws NoSuchElementException;
/**
* Get an integer value from the registry. If not found, the default value is used.
@ -108,7 +117,7 @@ public interface ConfigRegistry
* @throws java.util.NoSuchElementException
* if the key is not found
*/
boolean getBoolean( String key );
boolean getBoolean( String key ) throws NoSuchElementException;
/**
* Get a boolean value from the registry. If not found, the default value is used.
@ -177,7 +186,7 @@ public interface ConfigRegistry
boolean isEmpty( );
/**
* Get a list of strings at the given key in the registry.
* Get a list of strings at the given key in the registry. If not found a empty list will be returned.
*
* @param key the key to lookup
* @return the list of strings
@ -198,7 +207,7 @@ public interface ConfigRegistry
* @param key the key to take the subset from
* @return the registry subset
*/
ConfigRegistry getSubset( String key );
ConfigRegistry getSubset( String key ) throws RegistryException;
/**
* Get a list of subsets of the registry, for all keys descended from the given key.
@ -206,7 +215,7 @@ public interface ConfigRegistry
* @param key the key to take the subsets from
* @return the registry subsets
*/
List<ConfigRegistry> getSubsetList( String key );
List<ConfigRegistry> getSubsetList( String key ) throws RegistryException;
/**
* Get a configuration source part of the registry, identified by the given name. If it doesn't exist, <code>null</code> will be
@ -234,7 +243,7 @@ public interface ConfigRegistry
*
* @param listener the listener
*/
void registerChangeListener( RegistryListener listener, Pattern... filter );
void registerChangeListener( RegistryListener listener, String prefix );
/**
* Unregister the change listener for all events.
@ -245,17 +254,25 @@ public interface ConfigRegistry
boolean unregisterChangeListener( RegistryListener listener );
/**
* Get all the keys in this registry. Keys are only retrieved at a depth of 1.
* Get all keys on the base level in this registry. Keys are only retrieved at a depth of 1.
*
* @return the set of keys
*/
Collection<String> getKeys( );
Collection<String> getBaseKeys( );
/**
* Get all the keys in this registry.
* @return the set of keys
*/
Collection<String> getFullKeys( );
Collection<String> getKeys( );
/**
* Return the keys that match the given prefix.
*
* @param prefix The prefix
* @return A collection of keys
*/
Collection<String> getKeys( String prefix);
/**
* Remove a keyed element from the registry.

View File

@ -0,0 +1,28 @@
package org.apache.archiva.redback.common.config.api;
/*
* 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.
*/
/**
* @author Martin Stockhammer <martin_s@apache.org>
*/
public enum EventType
{
PROPERTY_SET,PROPERTY_CLEARED,PROPERTY_ADDED,UNDEFINED
}

View File

@ -24,22 +24,20 @@ package org.apache.archiva.redback.common.config.api;
*/
public interface RegistryListener
{
/**
* Notify the object that there is about to be a configuration change.
*
* @param registry the registry that was changed
* @param propertyName the property being changed
* @param propertyValue the value the property is about to be changed to
*/
void beforeConfigurationChange( ConfigRegistry registry, String propertyName, Object propertyValue );
/**
* Notify the object that there has been a configuration change.
*
* The method may be annotated by the {@link AsyncListener @AsyncListener} annotation. Which means the method will be
* executed asynchronously.
*
* @param registry the registry that was changed
* @param propertyName the property what was changed
* @param propertyValue the value the property was changed to
* @param oldValue The value the property had before
*/
void afterConfigurationChange( ConfigRegistry registry, String propertyName, Object propertyValue, Object oldValue );
void handleConfigurationChangeEvent( ConfigRegistry registry, EventType eventType, String propertyName, Object propertyValue, Object oldValue );
}