From 5cd2f362e9c64d628f596cd463a25c6c344c33bc Mon Sep 17 00:00:00 2001 From: Martin Stockhammer Date: Mon, 18 Feb 2019 06:26:31 +0100 Subject: [PATCH] Adding classes for listener implementation --- .../redback-common-configuration-acc2/pom.xml | 6 + .../common/config/acc2/CfgListener.java | 257 +++++++++++ .../acc2/CommonsConfigurationRegistry.java | 426 ++++++++++-------- .../config/acc2/AbstractRegistryTest.java | 6 +- .../CommonsConfigurationRegistryTest.java | 204 +++++---- .../config/acc2/MockChangeListener.java | 37 ++ .../src/test/resources/log4j2-test.xml | 12 +- .../common/config/api/AsyncListener.java | 49 ++ .../common/config/api/ConfigRegistry.java | 35 +- .../redback/common/config/api/EventType.java | 28 ++ .../common/config/api/RegistryListener.java | 16 +- 11 files changed, 782 insertions(+), 294 deletions(-) create mode 100644 redback-common/redback-common-configuration/redback-common-configuration-acc2/src/main/java/org/apache/archiva/redback/common/config/acc2/CfgListener.java create mode 100644 redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/java/org/apache/archiva/redback/common/config/acc2/MockChangeListener.java create mode 100644 redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/AsyncListener.java create mode 100644 redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/EventType.java diff --git a/redback-common/redback-common-configuration/redback-common-configuration-acc2/pom.xml b/redback-common/redback-common-configuration/redback-common-configuration-acc2/pom.xml index dcc2fd09..15050405 100644 --- a/redback-common/redback-common-configuration/redback-common-configuration-acc2/pom.xml +++ b/redback-common/redback-common-configuration/redback-common-configuration-acc2/pom.xml @@ -122,6 +122,12 @@ log4j-slf4j-impl test + + org.apache.logging.log4j + log4j-jcl + test + + diff --git a/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/main/java/org/apache/archiva/redback/common/config/acc2/CfgListener.java b/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/main/java/org/apache/archiva/redback/common/config/acc2/CfgListener.java new file mode 100644 index 00000000..2b1c793f --- /dev/null +++ b/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/main/java/org/apache/archiva/redback/common/config/acc2/CfgListener.java @@ -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 + */ + +public class CfgListener implements EventListener +{ + + ConfigRegistry registry; + + Map listeners = new LinkedHashMap<>( ); + WeakHashMap 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 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 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> it = listeners.entrySet( ).iterator( ); + while ( it.hasNext( ) ) + { + Map.Entry 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; + } +} diff --git a/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/main/java/org/apache/archiva/redback/common/config/acc2/CommonsConfigurationRegistry.java b/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/main/java/org/apache/archiva/redback/common/config/acc2/CommonsConfigurationRegistry.java index 4d3f7587..d9fdc7a7 100644 --- a/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/main/java/org/apache/archiva/redback/common/config/acc2/CommonsConfigurationRegistry.java +++ b/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/main/java/org/apache/archiva/redback/common/config/acc2/CommonsConfigurationRegistry.java @@ -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; * configuration * builder. */ -@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 configurationBuilder; - boolean combined = true; - private Map> builderMap = new HashMap<>( ); + private boolean combined = true; + private final Map> 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 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 configurationBuilder) + @SuppressWarnings( "WeakerAccess" ) + public CommonsConfigurationRegistry( Configuration configuration, ConfigurationBuilder 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 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 getList(String key) + @Override + public List getList( String key ) { List result = configuration.getList( String.class, key ); return result == null ? new ArrayList<>( ) : result; } - public List getSubsetList(String key) + @Override + public List getSubsetList( String key ) throws RegistryException { - List 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 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 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 getProperties(String key) + @Override + public Map 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 getBaseKeys( ) + { + Iterable 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 getKeys( ) { - return false; + Iterable iterable = ( ) -> configuration.getKeys( ); + return StreamSupport.stream( iterable.spliterator( ), true ).collect( Collectors.toSet( ) ); } - - public Collection getKeys() + @Override + public Collection getKeys( String prefix ) { - Iterable 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 iterable = ( ) -> configuration.getKeys( prefix ); + return StreamSupport.stream( iterable.spliterator( ), true ).collect( Collectors.toSet( ) ); } - public Collection getFullKeys() - { - Iterable 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 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 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 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 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 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 getConfigurationBuilder() + public ConfigurationBuilder getConfigurationBuilder( ) { return configurationBuilder; } - public void setConfigurationBuilder(ConfigurationBuilder 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; } diff --git a/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/java/org/apache/archiva/redback/common/config/acc2/AbstractRegistryTest.java b/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/java/org/apache/archiva/redback/common/config/acc2/AbstractRegistryTest.java index a51ff779..e08bdfb5 100644 --- a/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/java/org/apache/archiva/redback/common/config/acc2/AbstractRegistryTest.java +++ b/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/java/org/apache/archiva/redback/common/config/acc2/AbstractRegistryTest.java @@ -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 ) { diff --git a/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/java/org/apache/archiva/redback/common/config/acc2/CommonsConfigurationRegistryTest.java b/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/java/org/apache/archiva/redback/common/config/acc2/CommonsConfigurationRegistryTest.java index 778dc457..6dd854c0 100644 --- a/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/java/org/apache/archiva/redback/common/config/acc2/CommonsConfigurationRegistryTest.java +++ b/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/java/org/apache/archiva/redback/common/config/acc2/CommonsConfigurationRegistryTest.java @@ -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 keys = registry.getBaseKeys( ); + HashSet 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 keys = registry.getKeys( ); HashSet 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 properties = registry.getProperties( "properties" ); - assertEquals( 2, properties.size() ); + Map 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 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 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" ) ); } diff --git a/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/java/org/apache/archiva/redback/common/config/acc2/MockChangeListener.java b/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/java/org/apache/archiva/redback/common/config/acc2/MockChangeListener.java new file mode 100644 index 00000000..f68491a6 --- /dev/null +++ b/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/java/org/apache/archiva/redback/common/config/acc2/MockChangeListener.java @@ -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 + */ +public class MockChangeListener implements RegistryListener +{ + @Override + public void handleConfigurationChangeEvent( ConfigRegistry registry, EventType eventType, String propertyName, Object propertyValue, Object oldValue ) + { + + } + +} diff --git a/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/resources/log4j2-test.xml b/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/resources/log4j2-test.xml index 7fe22144..72c85dbd 100644 --- a/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/resources/log4j2-test.xml +++ b/redback-common/redback-common-configuration/redback-common-configuration-acc2/src/test/resources/log4j2-test.xml @@ -26,13 +26,17 @@ + + + - - - + + + - + + diff --git a/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/AsyncListener.java b/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/AsyncListener.java new file mode 100644 index 00000000..21627ac6 --- /dev/null +++ b/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/AsyncListener.java @@ -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 + * @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 ""; +} diff --git a/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/ConfigRegistry.java b/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/ConfigRegistry.java index 1946cbe7..6955e7c0 100644 --- a/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/ConfigRegistry.java +++ b/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/ConfigRegistry.java @@ -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, null 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, null 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 getSubsetList( String key ); + List getSubsetList( String key ) throws RegistryException; /** * Get a configuration source part of the registry, identified by the given name. If it doesn't exist, null 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 getKeys( ); + Collection getBaseKeys( ); /** * Get all the keys in this registry. * @return the set of keys */ - Collection getFullKeys( ); + Collection getKeys( ); + + /** + * Return the keys that match the given prefix. + * + * @param prefix The prefix + * @return A collection of keys + */ + Collection getKeys( String prefix); /** * Remove a keyed element from the registry. diff --git a/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/EventType.java b/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/EventType.java new file mode 100644 index 00000000..e7c69f71 --- /dev/null +++ b/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/EventType.java @@ -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 + */ +public enum EventType +{ + PROPERTY_SET,PROPERTY_CLEARED,PROPERTY_ADDED,UNDEFINED +} diff --git a/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/RegistryListener.java b/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/RegistryListener.java index a76d6dfc..698aa05d 100644 --- a/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/RegistryListener.java +++ b/redback-common/redback-common-configuration/redback-common-configuration-api/src/main/java/org/apache/archiva/redback/common/config/api/RegistryListener.java @@ -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 ); + + + }