TAMAYA-145: Simplified syntax and MetaContext. Added tests.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/10d711e6 Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/10d711e6 Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/10d711e6 Branch: refs/heads/master Commit: 10d711e6a7e15996c54baad0edf0b38102d3afa7 Parents: 098c75f Author: anatole <anat...@apache.org> Authored: Tue Apr 18 00:14:42 2017 +0200 Committer: anatole <anat...@apache.org> Committed: Tue Apr 18 00:14:42 2017 +0200 ---------------------------------------------------------------------- .../apache/tamaya/metamodel/CachedFilter.java | 108 +++++++++++ .../org/apache/tamaya/metamodel/HideFilter.java | 67 +++++++ .../tamaya/metamodel/ImmutableFilter.java | 55 ++++++ .../org/apache/tamaya/metamodel/MapFilter.java | 101 ++++++++++ .../org/apache/tamaya/metamodel/MaskFilter.java | 121 ++++++++++++ .../apache/tamaya/metamodel/MetaContext.java | 112 +++-------- .../apache/tamaya/metamodel/SecuredFilter.java | 119 ++++++++++++ .../metamodel/ext/FilteredPropertySource.java | 25 ++- .../internal/CombinationPolicyReader.java | 2 +- .../internal/ComponentConfigurator.java | 19 +- .../metamodel/internal/ContextReader.java | 181 ------------------ .../metamodel/internal/MetaContextReader.java | 185 +++++++++++++++++++ .../internal/PropertyConverterReader.java | 55 +++--- .../internal/PropertyFilterReader.java | 47 +++-- .../internal/PropertySourceReader.java | 132 +++++++------ .../factories/FilePropertySourceFactory.java | 10 +- .../ResourcePropertySourceFactory.java | 8 +- .../ResourcePropertySourceProviderFactory.java | 8 +- .../factories/URLPropertySourceFactory.java | 6 +- .../internal/resolver/PropertiesResolver.java | 13 +- .../org.apache.tamaya.metamodel.spi.ItemFactory | 7 + ...tamaya.metamodel.spi.MetaConfigurationReader | 2 +- .../tamaya/metamodel/ext/IntegrationTest.java | 107 ++++++++++- .../tamaya/metamodel/ext/MyConverter.java | 33 ++++ .../apache/tamaya/metamodel/ext/MyFilter.java | 33 ++++ .../tamaya/metamodel/ext/MyPropertySource.java | 35 ++++ .../resources/IntegrationTests/context-test.xml | 29 +++ .../default-propertyconverters-test.xml | 31 ++++ .../default-propertyfilters-test.xml | 26 +++ .../default-propertysources-test.xml | 29 +++ .../propertyconverters-test.xml | 30 +++ .../IntegrationTests/propertyfilters-test.xml | 26 +++ .../IntegrationTests/propertysources-test.xml | 25 +++ .../org.apache.tamaya.spi.PropertyFilter | 19 ++ metamodel/src/test/resources/tamaya-config.xml | 96 ++++------ 35 files changed, 1419 insertions(+), 483 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/CachedFilter.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/CachedFilter.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/CachedFilter.java new file mode 100644 index 0000000..c07e11d --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/CachedFilter.java @@ -0,0 +1,108 @@ +package org.apache.tamaya.metamodel;/* + * (C) Copyright 2015-2017 Trivadis AG. All rights reserved. + */ + +import org.apache.tamaya.metamodel.spi.ItemFactory; +import org.apache.tamaya.spi.FilterContext; +import org.apache.tamaya.spi.PropertyFilter; +import org.apache.tamaya.spi.PropertyValue; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +/** + * Simple filter that never changes a key/value pair returned, regardless if a value + * is changing underneath, hereby different values for single and multi-property access + * are considered. + */ +public class CachedFilter implements PropertyFilter{ + + private String matches; + private Map<String, CachedEntry> cachedEntries = new ConcurrentHashMap<>(); + private int maxSize = -1; + private long timeout = TimeUnit.MINUTES.toMillis(5); + + /** + * Factory for configuring immutable property filter. + */ + public static final class CachedFilterFactory implements ItemFactory<PropertyFilter> { + @Override + public String getName() { + return "Cached"; + } + + @Override + public PropertyFilter create(Map<String,String> parameters) { + return new CachedFilter(); + } + + @Override + public Class<? extends PropertyFilter> getType() { + return PropertyFilter.class; + } + } + + public String getMatches() { + return matches; + } + + public CachedFilter setMatches(String matches) { + this.matches = matches; + return this; + } + + @Override + public PropertyValue filterProperty(PropertyValue value, FilterContext context) { + if(matches !=null){ + if(value.getKey().matches(matches)){ + return resolveCachedEntry(value); + } + } + return value; + } + + /** + * Method checks for a cached value. if present and valid the cached value is returned. + * If not valid the cached entry is removed/updated. + * @param value + * @return + */ + private PropertyValue resolveCachedEntry(PropertyValue value) { + if(maxSize>0 && maxSize<=this.cachedEntries.size()){ + return value; + } + CachedEntry ce = cachedEntries.get(value.getKey()); + if(ce==null || !ce.isValid()){ + if(value!=null) { + ce = new CachedEntry(value, System.currentTimeMillis() + timeout); + this.cachedEntries.put(value.getKey(), ce); + } + } + return value; + } + + @Override + public String toString() { + return "CachedFilter{" + + "matches='" + matches + '\'' + + ", cache-size=" + cachedEntries.size() + + ", max-size=" + maxSize + + ", timeout=" + timeout + + '}'; + } + + private static final class CachedEntry{ + long ttl; + PropertyValue value; + + public CachedEntry (PropertyValue value, long ttl){ + this.ttl = ttl; + this.value = value; + } + + public boolean isValid(){ + return System.currentTimeMillis() > ttl; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/HideFilter.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/HideFilter.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/HideFilter.java new file mode 100644 index 0000000..2bd701c --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/HideFilter.java @@ -0,0 +1,67 @@ +package org.apache.tamaya.metamodel;/* + * (C) Copyright 2015-2017 Trivadis AG. All rights reserved. + */ + +import org.apache.tamaya.metamodel.spi.ItemFactory; +import org.apache.tamaya.spi.FilterContext; +import org.apache.tamaya.spi.PropertyFilter; +import org.apache.tamaya.spi.PropertyValue; +import org.apache.tamaya.spi.PropertyValueBuilder; + +import java.util.Map; + +/** + * Simple filter that never changes a key/value pair returned, regardless if a value + * is changing underneath, hereby different values for single and multi-property access + * are considered. + */ +public class HideFilter implements PropertyFilter{ + + private String matches; + + /** + * Factory for configuring immutable property filter. + */ + public static final class HideFilterFactory implements ItemFactory<PropertyFilter> { + @Override + public String getName() { + return "Hide"; + } + + @Override + public PropertyFilter create(Map<String,String> parameters) { + return new HideFilter(); + } + + @Override + public Class<? extends PropertyFilter> getType() { + return PropertyFilter.class; + } + } + + public String getMatches() { + return matches; + } + + public HideFilter setMatches(String matches) { + this.matches = matches; + return this; + } + + @Override + public PropertyValue filterProperty(PropertyValue value, FilterContext context) { + if(matches !=null){ + if(value.getKey().matches(matches)){ + return null; + } + } + return value; + } + + @Override + public String toString() { + return "HideFilter{" + + "matches='" + matches + '\'' + + '}'; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/ImmutableFilter.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/ImmutableFilter.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/ImmutableFilter.java new file mode 100644 index 0000000..90c65f5 --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/ImmutableFilter.java @@ -0,0 +1,55 @@ +package org.apache.tamaya.metamodel;/* + * (C) Copyright 2015-2017 Trivadis AG. All rights reserved. + */ + +import org.apache.tamaya.metamodel.spi.ItemFactory; +import org.apache.tamaya.spi.FilterContext; +import org.apache.tamaya.spi.PropertyFilter; +import org.apache.tamaya.spi.PropertyValue; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Simple filter that never changes a key/value pair returned, regardless if a value + * is changing underneath, hereby different values for single and multi-property access + * are considered. + */ +public class ImmutableFilter implements PropertyFilter{ + + /** + * Factory for configuring immutable property filter. + */ + public static final class ImmutableFilterFactory implements ItemFactory<PropertyFilter> { + @Override + public String getName() { + return "Immutable"; + } + + @Override + public PropertyFilter create(Map<String,String> parameters) { + return new ImmutableFilter(); + } + + @Override + public Class<? extends PropertyFilter> getType() { + return PropertyFilter.class; + } + } + + private Map<String,PropertyValue> map = new ConcurrentHashMap<>(); + + @Override + public PropertyValue filterProperty(PropertyValue value, FilterContext context) { + String key = value.getKey(); + if(!context.isSinglePropertyScoped()) { + key = value.getKey() + "_all"; + } + PropertyValue val = map.get(key); + if(val==null){ + map.put(key, value); + val = value; + } + return val; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/MapFilter.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/MapFilter.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/MapFilter.java new file mode 100644 index 0000000..ab521dd --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/MapFilter.java @@ -0,0 +1,101 @@ +package org.apache.tamaya.metamodel;/* + * (C) Copyright 2015-2017 Trivadis AG. All rights reserved. + */ + +import org.apache.tamaya.metamodel.spi.ItemFactory; +import org.apache.tamaya.spi.FilterContext; +import org.apache.tamaya.spi.PropertyFilter; +import org.apache.tamaya.spi.PropertyValue; +import org.apache.tamaya.spi.PropertyValueBuilder; + +import java.util.Map; + +/** + * Simple filter that never changes a key/value pair returned, regardless if a value + * is changing underneath, hereby different values for single and multi-property access + * are considered. + */ +public class MapFilter implements PropertyFilter{ + + private String target; + private String cutoff; + private String matches; + + /** + * Factory for configuring immutable property filter. + */ + public static final class MapFilterFactory implements ItemFactory<PropertyFilter> { + @Override + public String getName() { + return "Map"; + } + + @Override + public PropertyFilter create(Map<String,String> parameters) { + return new MapFilter(); + } + + @Override + public Class<? extends PropertyFilter> getType() { + return PropertyFilter.class; + } + } + + public String getTarget() { + return target; + } + + public MapFilter setTarget(String target) { + this.target = target; + return this; + } + + public String getCutoff() { + return cutoff; + } + + public MapFilter setCutoff(String cutoff) { + this.cutoff = cutoff; + return this; + } + + public String getMatches() { + return matches; + } + + public MapFilter setMatches(String matches) { + this.matches = matches; + return this; + } + + @Override + public PropertyValue filterProperty(PropertyValue value, FilterContext context) { + PropertyValueBuilder b = value.toBuilder(); + String key = value.getKey(); + if(matches !=null){ + if(!value.getKey().matches(matches)){ + return value; + } + } + if(cutoff !=null){ + if(value.getKey().startsWith(cutoff)){ + key = key.substring(cutoff.length()); + b.setKey(key); + } + } + if(target!=null){ + key = target+key; + b.setKey(key); + } + return b.build(); + } + + @Override + public String toString() { + return "MapFilter{" + + "target='" + target + '\'' + + ", cutoff='" + cutoff + '\'' + + ", matches='" + matches + '\'' + + '}'; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/MaskFilter.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/MaskFilter.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/MaskFilter.java new file mode 100644 index 0000000..d374dc4 --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/MaskFilter.java @@ -0,0 +1,121 @@ +package org.apache.tamaya.metamodel;/* + * (C) Copyright 2015-2017 Trivadis AG. All rights reserved. + */ + +import org.apache.tamaya.metamodel.spi.ItemFactory; +import org.apache.tamaya.spi.FilterContext; +import org.apache.tamaya.spi.PropertyFilter; +import org.apache.tamaya.spi.PropertyValue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * Simple filter that never changes a key/value pair returned, regardless if a value + * is changing underneath, hereby different values for single and multi-property access + * are considered. + */ +public class MaskFilter implements PropertyFilter{ + + private String matches; + private List<String> roles = new ArrayList<>(); + private String mask = "*****"; + private TargetPolicy policy = TargetPolicy.ALL; + + /** + * Factory for configuring immutable property filter. + */ + public static final class MaskFilterFactory implements ItemFactory<PropertyFilter> { + @Override + public String getName() { + return "Mask"; + } + + @Override + public PropertyFilter create(Map<String,String> parameters) { + return new MaskFilter(); + } + + @Override + public Class<? extends PropertyFilter> getType() { + return PropertyFilter.class; + } + } + + public String getMatches() { + return matches; + } + + public MaskFilter setMatches(String matches) { + this.matches = matches; + return this; + } + + public List<String> getRoles() { + return roles; + } + + public MaskFilter setRoles(List<String> roles) { + this.roles.clear(); + for(String role:roles) { + this.roles.add(role.trim()); + } + return this; + } + + public MaskFilter setRoles(String... roles) { + return setRoles(Arrays.asList(roles)); + } + + public MaskFilter setRoles(String roles){ + setRoles(roles.split(",")); + return this; + } + + public String getMask() { + return mask; + } + + public MaskFilter setMask(String mask) { + this.mask = mask; + return this; + } + + public TargetPolicy getPolicy() { + return policy; + } + + public MaskFilter setPolicy(TargetPolicy policy) { + this.policy = policy; + return this; + } + + public MaskFilter setPolicy(String policy) { + return setPolicy(TargetPolicy.valueOf(policy)); + } + + @Override + public PropertyValue filterProperty(PropertyValue value, FilterContext context) { + if(matches !=null){ + if(value.getKey().matches(matches)){ + return null; + } + } + return value; + } + + @Override + public String toString() { + return "HideFilter{" + + "matches='" + matches + '\'' + + '}'; + } + + private enum TargetPolicy { + ALL, + SINGLEVALUE, + MULTIVALUE + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaContext.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaContext.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaContext.java index 1952d8e..9082fc3 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaContext.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaContext.java @@ -18,31 +18,22 @@ */ package org.apache.tamaya.metamodel; -import org.apache.tamaya.functions.Supplier; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.WeakHashMap; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; /** - * Class managing the configuration system's shared context. This + * Class managing a configuration system's meta-context. This * context is used by the configuration system to evaluate the * right properties, e.g. by defining the current stage or labels - * that apply to the current configuration. Hereby context are + * that apply to the current configuration. Hereby contexts are * <ul> - * <li>identified by unique names</li> - * <li>stackable into a context hierarchy, see {@link #combineWith(MetaContext...)}</li> - * <li>optionally be valid only in some contexts or for a limited time, see {@link #isValid()}, - * {@link #getInstance(String, Supplier)}</li> + * <li>stackable into a context hierarchy, see {@link #combineWith(MetaContext, MetaContext...)}</li> * <li>providing key/values only valid for a certain time (assigned a TTL), see {@link #setProperty(String, String, int, TimeUnit)}, * {@link #setProperties(Map, long, TimeUnit)}</li> * </ul> - * Additionally there is special support for thread related contexts, see {@link #getThreadInstance(boolean)}. - * Finally there is also one special globally shared context instance, see {@link #getCurrentInstance(boolean)}. + * Additionally there is special support for thread related contexts, see {@link #getThreadInstance()}. + * Finally there is also one special globally shared context instance, see {@link #getInstance()}. */ public final class MetaContext { @@ -52,54 +43,32 @@ public final class MetaContext { return new MetaContext(); } }; - public static final String DEFAULT_CONTEXT_NAME = "<DEFAULT>"; - - private String id; - - private Supplier<Boolean> validSupplier; private final Map<String,Value> properties = new ConcurrentHashMap<>(); - private static final Map<String,MetaContext> CONTEXTS = new WeakHashMap<>(); + private static final MetaContext globalContext = new MetaContext(); - /** - * Access a context by name. Contexts are managed as weak references in this class. If no - * such context exists, a new instance is created. - * @param contextName the context name, not null. - * @return the context instance, never null. - */ - public static MetaContext getInstance(String contextName) { - return getInstance(contextName, null); + /** The unique id of this context. */ + private MetaContext(){ + setProperty("_id", UUID.randomUUID().toString()); } /** - * Access the default context. Contexts are managed as weak references in this class. If no - * such context exists, a new instance is created. - * @return the context instance, never null. + * Get the context's id. + * @return */ - public static MetaContext getDefaultInstance(){ - return getInstance(DEFAULT_CONTEXT_NAME); + public String getId() { + return getProperty("_id", "N/A"); } + /** - * Access a context by name. Contexts are managed as weak references in this class. If no - * such valid context exists, a new instance is created, using the given {@code validSupplier}. - * @param contextName the context name, not null. + * Access the global context. There might be other contexts used in the system, which also + * may delegate to the global context. * @return the context instance, never null. */ - public static MetaContext getInstance(String contextName, Supplier<Boolean> validSupplier){ - synchronized(CONTEXTS){ - MetaContext ctx = CONTEXTS.get(contextName); - if(ctx!=null && ctx.isValid()){ - return ctx; - } - ctx = new MetaContext(); - ctx.id = Objects.requireNonNull(contextName); - ctx.validSupplier = validSupplier; - CONTEXTS.put(contextName, ctx); - return ctx; - } - + public static MetaContext getInstance(){ + return globalContext; } /** @@ -109,7 +78,7 @@ public final class MetaContext { * @return the corresponding context, never null. */ public static MetaContext getThreadInstance(boolean reinit){ - MetaContext threadContext =THREAD_CONTEXT.get(); + MetaContext threadContext = THREAD_CONTEXT.get(); if(reinit){ threadContext.properties.clear(); } @@ -121,44 +90,21 @@ public final class MetaContext { * context (overriding). * @return the corresponding context, never null. */ - public MetaContext getCurrentInstance(){ - return getCurrentInstance(false); + public MetaContext getThreadInstance(){ + return getThreadInstance(false); } - /** - * Access the current context, which actually is the current context, combined with the thread based - * context (overriding). - * @param reinit if true, clear's the thread's meta context. - * @return the corresponding context, never null. - */ - public MetaContext getCurrentInstance(boolean reinit){ - return this.combineWith(getThreadInstance(reinit)); - } /** - * Method to evaluate if a context is valid. This basically depends on the - * {@code validSupplier}, if any is set. If no supplier is present the context is valid. - * - * @return true, if this context is valid. - */ - public boolean isValid(){ - return this.validSupplier == null || validSupplier.get(); - } - - - /** - * Combine this context with the other contexts given, hereby only contexts are included - * which are {@code valid}, see {@link #isValid()}. + * Combine this context with the other contexts given. * @param contexts the context to merge with this context. * @return the newly created Context. */ - public MetaContext combineWith(MetaContext... contexts) { + public static MetaContext combineWith(MetaContext baseContext, MetaContext... contexts) { MetaContext newContext = new MetaContext(); - newContext.properties.putAll(this.properties); + newContext.properties.putAll(baseContext.properties); for(MetaContext ctx:contexts) { - if(ctx.isValid()) { - newContext.properties.putAll(ctx.properties); - } + newContext.properties.putAll(ctx.properties); } return newContext; } @@ -311,8 +257,10 @@ public final class MetaContext { @Override public String toString() { - return "Context{" + - properties + + return "MetaContext{" + + "id=" + getId() + + ", properties=" + properties + + ", global=" + (this == MetaContext.globalContext) + '}'; } http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/SecuredFilter.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/SecuredFilter.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/SecuredFilter.java new file mode 100644 index 0000000..5878106 --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/SecuredFilter.java @@ -0,0 +1,119 @@ +package org.apache.tamaya.metamodel;/* + * (C) Copyright 2015-2017 Trivadis AG. All rights reserved. + */ + +import org.apache.tamaya.ConfigException; +import org.apache.tamaya.metamodel.spi.ItemFactory; +import org.apache.tamaya.spi.FilterContext; +import org.apache.tamaya.spi.PropertyFilter; +import org.apache.tamaya.spi.PropertyValue; + +import javax.security.auth.Subject; +import java.security.*; +import java.util.Map; +import java.util.logging.Logger; + +/** + * Simple filter that never changes a key/value pair returned, regardless if a value + * is changing underneath, hereby different values for single and multi-property access + * are considered. + */ +public class SecuredFilter implements PropertyFilter{ + + private static final Logger LOG = Logger.getLogger(SecuredFilter.class.getName()); + + private String matches; + private String roles; + private String[]rolesArray; + private SecurePolicy policy = SecurePolicy.HIDE; + + /** + * Factory for configuring immutable property filter. + */ + public static final class SecuredFilterFactory implements ItemFactory<PropertyFilter> { + @Override + public String getName() { + return "Secured"; + } + + @Override + public PropertyFilter create(Map<String,String> parameters) { + return new SecuredFilter(); + } + + @Override + public Class<? extends PropertyFilter> getType() { + return PropertyFilter.class; + } + } + + public String getMatches() { + return matches; + } + + public SecuredFilter setMatches(String matches) { + this.matches = matches; + return this; + } + + public String getRoles() { + return roles; + } + + public SecuredFilter setRoles(String roles) { + this.roles = roles; + this.rolesArray = roles.split(","); + return this; + } + + public SecurePolicy getPolicy() { + return policy; + } + + public SecuredFilter setPolicy(SecurePolicy policy) { + this.policy = policy; + return this; + } + + @Override + public PropertyValue filterProperty(PropertyValue value, FilterContext context) { + if(matches !=null){ + if(!value.getKey().matches(matches)) { + return value; + } + } + Subject s = javax.security.auth.Subject.getSubject(AccessController.getContext()); + for(Principal principal:s.getPrincipals()){ + for(String role:rolesArray) { + if(principal.getName().equals(role)){ + return value; + } + } + } + switch(policy){ + case THROW_EXCPETION: + throw new ConfigException("Unauthorized access to '"+value.getKey()+"', not in " + roles); + case WARN_ONLY: + LOG.warning("Unauthorized access to '"+value.getKey()+"', not in " + roles); + return value; + case HIDE: + default: + return null; + } + } + + @Override + public String toString() { + return "SecuredFilter{" + + "matches='" + matches + '\'' + + ", roles='" + roles + '\'' + + ", policy='" + policy + '\'' + + '}'; + } + + public enum SecurePolicy{ + HIDE, + WARN_ONLY, + THROW_EXCPETION + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredPropertySource.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredPropertySource.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredPropertySource.java index 43d1836..fec8777 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredPropertySource.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredPropertySource.java @@ -142,6 +142,21 @@ public final class FilteredPropertySource extends BasePropertySource { } /** + * Removes the (first) given filter, if present. + * @param filterClass the class of the filter to remove, not null. + */ + public void removePropertyFilter(Class<? extends PropertyFilter> filterClass){ + synchronized(filters){ + for(PropertyFilter f:filters){ + if(f.getClass().equals(filterClass)){ + filters.remove(f); + break; + } + } + } + } + + /** * Access the current filters present. * @return a copy of the current filter list. */ @@ -152,13 +167,11 @@ public final class FilteredPropertySource extends BasePropertySource { } @Override - public String toString() { + protected String toStringValues() { synchronized (filters) { - return "FilteredPropertySource{" + - "\n wrapped=" + wrapped + - "\n filters=" + this.filters + - "\n base=" + super.toString() + - "\n}"; + return super.toStringValues() + + " wrapped=" + wrapped + '\n' + + " filters=" + this.filters + '\n'; } } } http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/CombinationPolicyReader.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/CombinationPolicyReader.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/CombinationPolicyReader.java index 4c9217d..9e31add 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/CombinationPolicyReader.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/CombinationPolicyReader.java @@ -49,7 +49,7 @@ public class CombinationPolicyReader implements MetaConfigurationReader{ throw new ConfigException("Only one combination policy can be applied."); } Node node = nodeList.item(0); - String type = node.getAttributes().getNamedItem("type").getNodeValue(); + String type = node.getAttributes().getNamedItem("class").getNodeValue(); LOG.finest("Loading combination policy configured: " + type); ItemFactory<PropertyValueCombinationPolicy> policyFactory = ItemFactoryManager.getInstance().getFactory(PropertyValueCombinationPolicy.class, type); PropertyValueCombinationPolicy policy = policyFactory.create(ComponentConfigurator.extractParameters(node)); http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java index 93c50da..8832d98 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java @@ -18,6 +18,7 @@ */ package org.apache.tamaya.metamodel.internal; +import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -41,8 +42,17 @@ public final class ComponentConfigurator<T> { public static void configure(Object instance, Node node) { NodeList entryNodes = node.getChildNodes(); Map<String,String> params = new HashMap<>(); + for(int c=0;c<node.getAttributes().getLength();c++){ + Node attr = node.getAttributes().item(c); + String key = attr.getNodeName(); + String value = attr.getNodeValue(); + params.put(key, value); + } for(int c=0;c<entryNodes.getLength();c++) { Node filterNode = entryNodes.item(c); + if(filterNode.getNodeType()!=Node.ELEMENT_NODE){ + continue; + } if ("param".equals(filterNode.getNodeName())) { String key = filterNode.getAttributes().getNamedItem("name").getNodeValue(); String value = filterNode.getTextContent(); @@ -71,8 +81,15 @@ public final class ComponentConfigurator<T> { } public static Map<String, String> extractParameters(Node node) { - NodeList entryNodes = node.getChildNodes(); Map<String,String> params = new HashMap<>(); + NamedNodeMap attributes = node.getAttributes(); + for(int c=0;c<attributes.getLength();c++) { + Node pn = attributes.item(c); + String key = pn.getNodeName(); + String value = pn.getNodeValue(); + params.put(key, value); + } + NodeList entryNodes = node.getChildNodes(); for(int c=0;c<entryNodes.getLength();c++) { Node filterNode = entryNodes.item(c); if ("param".equals(filterNode.getNodeName())) { http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ContextReader.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ContextReader.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ContextReader.java deleted file mode 100644 index 5e74f75..0000000 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ContextReader.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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. - */ -package org.apache.tamaya.metamodel.internal; - -import org.apache.tamaya.metamodel.MetaContext; -import org.apache.tamaya.metamodel.spi.MetaConfigurationReader; -import org.apache.tamaya.metamodel.spi.SimpleResolver; -import org.apache.tamaya.spi.ConfigurationContextBuilder; -import org.apache.tamaya.spi.ServiceContextManager; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import javax.annotation.Priority; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Logger; - - -/** - * Meta-configuration reader that reads the shared context data. - */ -@Priority(-1) -public class ContextReader implements MetaConfigurationReader { - - private static final Logger LOG = Logger.getLogger(ContextReader.class.getName()); - - private Map<String,SimpleResolver> resolvers = new ConcurrentHashMap<>(); - - public ContextReader(){ - for(SimpleResolver resolver: ServiceContextManager.getServiceContext() - .getServices(SimpleResolver.class)){ - this.resolvers.put(resolver.getResolverId(), resolver); - } - } - - public void addResolver(SimpleResolver resolver){ - if(!this.resolvers.containsKey(resolver.getResolverId())) { - this.resolvers.put(resolver.getResolverId(), resolver); - } - } - - public void removeResolver(SimpleResolver resolver){ - this.resolvers.remove(resolver.getResolverId()); - } - - public Set<String> getResolverIds(){ - return this.resolvers.keySet(); - } - - public SimpleResolver getResolver(String resolverKey){ - return this.resolvers.get(resolverKey); - } - - @Override - public void read(Document document, ConfigurationContextBuilder contextBuilder) { - NodeList nodeList = document.getDocumentElement().getElementsByTagName("context"); - String contextName = null; - LOG.finer("Reading " + nodeList.getLength() + " meta context entries..."); - for(int i=0;i<nodeList.getLength();i++){ - Node node = nodeList.item(i); - if(node.getNodeName().equals("context")){ - Node nameNode = node.getAttributes().getNamedItem("name"); - if(nameNode!=null){ - contextName = nameNode.getTextContent(); - } - MetaContext context = contextName!=null?MetaContext.getInstance(contextName):MetaContext.getDefaultInstance(); - NodeList entryNodes = node.getChildNodes(); - for(int c=0;c<entryNodes.getLength();c++){ - Node entryNode = entryNodes.item(c); - if("context-entry".equals(entryNode.getNodeName())){ - String key = entryNode.getAttributes().getNamedItem("name").getNodeValue(); - String value = entryNode.getTextContent(); - resolvePlaceholders(value); - LOG.finest("Applying context entry: " + key + '=' + value + " on " + contextName); - context.setProperty(key, value); - } - } - } - } - } - - private String resolvePlaceholders(String value) { - StringBuilder result = new StringBuilder(); - StringBuilder exp = new StringBuilder(); - final int INVALUE = 0; - final int BEFORE_EXP = 1; - final int INEXP = 2; - int state = INVALUE; - StringTokenizer tokenizer = new StringTokenizer(value, "${}", true); - while(tokenizer.hasMoreTokens()){ - String token = tokenizer.nextToken(); - switch(token){ - case "$": - switch(state){ - case INVALUE: - default: - state = BEFORE_EXP; - break; - case BEFORE_EXP: // escaped - result.append(token); - state = INVALUE; - break; - case INEXP: - exp.append(token); - break; - } - break; - case "{": - switch(state){ - case BEFORE_EXP: - state = INEXP; - break; - case INVALUE: - case INEXP: - default: - result.append(token); - break; - } - case "}": - switch(state){ - case INVALUE: - result.append(token); - break; - case INEXP: - result.append(evaluateExpression(exp.toString())); - exp.setLength(0); - state = INVALUE; - break; - case BEFORE_EXP: - result.append("$").append(token); - state = INVALUE; - break; - } - break; - default: - result.append(token); - } - } - return result.toString(); - } - - private String evaluateExpression(String exp) { - String[] parts = exp.split(":", 2); - if(parts.length<2){ - return "--{MISSING RESOLVER ID in "+exp+"}"; - } - SimpleResolver resolver = this.resolvers.get(parts[0]); - if(resolver==null){ - return "--{NO RESOLVER FOUND for "+exp+"}"; - } - try{ - String resolved = resolver.evaluate(parts[1]); - if(resolved==null) { - return "--{NOT RESOLVABLE:" + exp + "}"; - }else{ - return resolved; - } - }catch(Exception e){ - return "--{ERROR:"+exp+":"+e+"}"; - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/MetaContextReader.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/MetaContextReader.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/MetaContextReader.java new file mode 100644 index 0000000..8ec1c76 --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/MetaContextReader.java @@ -0,0 +1,185 @@ +/* + * 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. + */ +package org.apache.tamaya.metamodel.internal; + +import org.apache.tamaya.metamodel.MetaContext; +import org.apache.tamaya.metamodel.spi.MetaConfigurationReader; +import org.apache.tamaya.metamodel.spi.SimpleResolver; +import org.apache.tamaya.spi.ConfigurationContextBuilder; +import org.apache.tamaya.spi.ServiceContextManager; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.annotation.Priority; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + + +/** + * Meta-configuration reader that reads the shared context data. + */ +@Priority(-1) +public class MetaContextReader implements MetaConfigurationReader { + + private static final Logger LOG = Logger.getLogger(MetaContextReader.class.getName()); + + private Map<String,SimpleResolver> resolvers = new ConcurrentHashMap<>(); + + public MetaContextReader(){ + for(SimpleResolver resolver: ServiceContextManager.getServiceContext() + .getServices(SimpleResolver.class)){ + this.resolvers.put(resolver.getResolverId(), resolver); + } + } + + public void addResolver(SimpleResolver resolver){ + if(!this.resolvers.containsKey(resolver.getResolverId())) { + this.resolvers.put(resolver.getResolverId(), resolver); + } + } + + public void removeResolver(SimpleResolver resolver){ + this.resolvers.remove(resolver.getResolverId()); + } + + public Set<String> getResolverIds(){ + return this.resolvers.keySet(); + } + + public SimpleResolver getResolver(String resolverKey){ + return this.resolvers.get(resolverKey); + } + + @Override + public void read(Document document, ConfigurationContextBuilder contextBuilder) { + NodeList nodeList = document.getDocumentElement().getElementsByTagName("context"); + LOG.finer("Reading " + nodeList.getLength() + " meta context entries..."); + for(int i=0;i<nodeList.getLength();i++){ + Node node = nodeList.item(i); + if(node.getNodeName().equals("context")){ + MetaContext context = MetaContext.getInstance(); + NodeList entryNodes = node.getChildNodes(); + for(int c=0;c<entryNodes.getLength();c++){ + Node entryNode = entryNodes.item(c); + if(entryNode.getNodeType()==Node.ELEMENT_NODE) { + String key = entryNode.getNodeName(); + String value = entryNode.getTextContent(); + value = resolvePlaceholders(value); + LOG.finest("MetaContext: " + key + '=' + value); + context.setProperty(key, value); + } + } + } + } + } + + private String resolvePlaceholders(String value) { + StringBuilder result = new StringBuilder(); + StringBuilder exp = new StringBuilder(); + final int INVALUE = 0; + final int BEFORE_EXP = 1; + final int INEXP = 2; + int state = INVALUE; + StringTokenizer tokenizer = new StringTokenizer(value, "${}", true); + while(tokenizer.hasMoreTokens()){ + String token = tokenizer.nextToken(); + switch(token){ + case "$": + switch(state){ + case INVALUE: + default: + state = BEFORE_EXP; + break; + case BEFORE_EXP: // escaped + result.append(token); + state = INVALUE; + break; + case INEXP: + exp.append(token); + break; + } + break; + case "{": + switch(state){ + case BEFORE_EXP: + state = INEXP; + break; + case INVALUE: + case INEXP: + default: + result.append(token); + break; + } + break; + case "}": + switch(state){ + case INVALUE: + result.append(token); + break; + case INEXP: + result.append(evaluateExpression(exp.toString())); + exp.setLength(0); + state = INVALUE; + break; + case BEFORE_EXP: + result.append("$").append(token); + state = INVALUE; + break; + } + break; + default: + switch(state){ + case INEXP: + exp.append(token); + break; + default: + result.append(token); + break; + } + + } + } + return result.toString(); + } + + private String evaluateExpression(String exp) { + String[] parts = exp.split(":", 2); + if(parts.length<2){ + return "--{MISSING RESOLVER ID in "+exp+"}"; + } + SimpleResolver resolver = this.resolvers.get(parts[0]); + if(resolver==null){ + return "--{NO RESOLVER FOUND for "+exp+"}"; + } + try{ + String resolved = resolver.evaluate(parts[1]); + if(resolved==null) { + return "--{NOT RESOLVABLE:" + exp + "}"; + }else{ + return resolved; + } + }catch(Exception e){ + return "--{ERROR:"+exp+":"+e+"}"; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyConverterReader.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyConverterReader.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyConverterReader.java index f82e92d..9490a78 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyConverterReader.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyConverterReader.java @@ -18,14 +18,13 @@ */ package org.apache.tamaya.metamodel.internal; +import org.apache.tamaya.ConfigException; import org.apache.tamaya.TypeLiteral; import org.apache.tamaya.metamodel.spi.ItemFactory; import org.apache.tamaya.metamodel.spi.ItemFactoryManager; import org.apache.tamaya.metamodel.spi.MetaConfigurationReader; import org.apache.tamaya.spi.ConfigurationContextBuilder; import org.apache.tamaya.spi.PropertyConverter; -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertySourceProvider; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -49,38 +48,36 @@ public class PropertyConverterReader implements MetaConfigurationReader{ return; } if(nodeList.getLength()>1){ - LOG.warning("Multiple property-converters sections configured, onyl reading first..."); - return; + throw new ConfigException("Only one single property-converters section allowed."); } nodeList = nodeList.item(0).getChildNodes(); for(int i=0;i<nodeList.getLength();i++){ Node node = nodeList.item(i); - try{ - if(node.getNodeName().equals("converter")){ - String type = node.getAttributes().getNamedItem("type").getNodeValue(); - try { - ItemFactory<PropertyConverter> converterFactory = ItemFactoryManager.getInstance().getFactory(PropertyConverter.class, type); - if(converterFactory==null){ - LOG.severe("No such property converter: " + type); - continue; - } - Map<String,String> params = ComponentConfigurator.extractParameters(node); - PropertyConverter converter = converterFactory.create(params); - if(converter!=null) { - ComponentConfigurator.configure(converter, node); - Class targetType = Class.forName(params.get("targetType")); - LOG.finer("Adding converter for type " + targetType.getName() + ": " + converter.getClass()); - contextBuilder.addPropertyConverters(TypeLiteral.of(targetType), converter); - } - } catch (Exception e) { - LOG.log(Level.SEVERE, "Failed to configure PropertyConverter: " + type, e); - } - }else if(node.getNodeName().equals("default-converters")){ - LOG.finer("Adding default property converters..."); - contextBuilder.addDefaultPropertyConverters(); + if(node.getNodeType()!=Node.ELEMENT_NODE) { + continue; + } + String type = node.getNodeName(); + if("defaults".equals(type)){ + LOG.finer("Adding default property converters..."); + contextBuilder.addDefaultPropertyConverters(); + continue; + } + try { + ItemFactory<PropertyConverter> converterFactory = ItemFactoryManager.getInstance().getFactory(PropertyConverter.class, type); + if(converterFactory==null){ + LOG.severe("No such property converter: " + type); + continue; + } + Map<String,String> params = ComponentConfigurator.extractParameters(node); + PropertyConverter converter = converterFactory.create(params); + if(converter!=null) { + ComponentConfigurator.configure(converter, node); + Class targetType = Class.forName(params.get("targetType")); + LOG.finer("Adding converter for type " + targetType.getName() + ": " + converter.getClass()); + contextBuilder.addPropertyConverters(TypeLiteral.of(targetType), converter); } - }catch(Exception e){ - LOG.log(Level.SEVERE, "Failed to read property converter configuration: " + node, e); + } catch (Exception e) { + LOG.log(Level.SEVERE, "Failed to configure PropertyConverter: " + type, e); } } } http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyFilterReader.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyFilterReader.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyFilterReader.java index 94bb6ec..be6fa2b 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyFilterReader.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyFilterReader.java @@ -18,18 +18,17 @@ */ package org.apache.tamaya.metamodel.internal; +import org.apache.tamaya.ConfigException; import org.apache.tamaya.metamodel.spi.ItemFactory; import org.apache.tamaya.metamodel.spi.ItemFactoryManager; import org.apache.tamaya.metamodel.spi.MetaConfigurationReader; import org.apache.tamaya.spi.ConfigurationContextBuilder; import org.apache.tamaya.spi.PropertyFilter; -import org.apache.tamaya.spi.PropertySourceProvider; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.util.Map; -import java.util.logging.Level; import java.util.logging.Logger; @@ -48,33 +47,31 @@ public class PropertyFilterReader implements MetaConfigurationReader{ return; } if(nodeList.getLength()>1){ - LOG.warning("Multiple property-filters sections configured, onyl reading first..."); - return; + throw new ConfigException("Only one single property-filters section allowed."); } nodeList = nodeList.item(0).getChildNodes(); for(int i=0;i<nodeList.getLength();i++){ Node node = nodeList.item(i); - try { - if ("filter".equals(node.getNodeName())) { - String type = node.getAttributes().getNamedItem("type").getNodeValue(); - ItemFactory<PropertyFilter> filterFactory = ItemFactoryManager.getInstance().getFactory(PropertyFilter.class, type); - if(filterFactory==null){ - LOG.severe("No such property filter: " + type); - continue; - } - Map<String,String> params = ComponentConfigurator.extractParameters(node); - PropertyFilter filter = filterFactory.create(params); - if(filter!=null) { - ComponentConfigurator.configure(filter, params); - LOG.finer("Adding configured property filter: " + filter.getClass().getName()); - contextBuilder.addPropertyFilters(filter); - } - } else if ("default-filters".equals(node.getNodeName())) { - LOG.finer("Adding default property filters..."); - contextBuilder.addDefaultPropertyFilters(); - } - }catch(Exception e){ - LOG.log(Level.SEVERE, "Failed to read property filter configuration: " + node, e); + if(node.getNodeType()!=Node.ELEMENT_NODE) { + continue; + } + String type = node.getNodeName(); + if ("defaults".equals(type)) { + LOG.finer("Adding default property filters..."); + contextBuilder.addDefaultPropertyFilters(); + continue; + } + ItemFactory<PropertyFilter> filterFactory = ItemFactoryManager.getInstance().getFactory(PropertyFilter.class, type); + if(filterFactory==null){ + LOG.severe("No such property filter: " + type); + continue; + } + Map<String,String> params = ComponentConfigurator.extractParameters(node); + PropertyFilter filter = filterFactory.create(params); + if(filter!=null) { + ComponentConfigurator.configure(filter, params); + LOG.finer("Adding configured property filter: " + filter.getClass().getName()); + contextBuilder.addPropertyFilters(filter); } } } http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java index ebcd8e0..a465146 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java @@ -18,7 +18,9 @@ */ package org.apache.tamaya.metamodel.internal; -import org.apache.tamaya.metamodel.*; +import org.apache.tamaya.ConfigException; +import org.apache.tamaya.metamodel.EnabledPropertySource; +import org.apache.tamaya.metamodel.MetaContext; import org.apache.tamaya.metamodel.ext.EnabledPropertySourceProvider; import org.apache.tamaya.metamodel.ext.FilteredPropertySource; import org.apache.tamaya.metamodel.ext.RefreshablePropertySource; @@ -53,57 +55,53 @@ public class PropertySourceReader implements MetaConfigurationReader{ return; } if(nodeList.getLength()>1){ - LOG.warning("Multiple property-sources sections configured, onyl reading first..."); - return; + throw new ConfigException("Only one single property-source section allowed."); } nodeList = nodeList.item(0).getChildNodes(); for(int i=0;i<nodeList.getLength();i++){ Node node = nodeList.item(i); - try{ - if(node.getNodeName().equals("source")){ - String type = node.getAttributes().getNamedItem("type").getNodeValue(); - try { - ItemFactory<PropertySource> sourceFactory = ItemFactoryManager.getInstance().getFactory(PropertySource.class, type); - if(sourceFactory==null){ - LOG.severe("No such property source: " + type); - continue; - } - Map<String,String> params = ComponentConfigurator.extractParameters(node); - PropertySource ps = sourceFactory.create(params); - if(ps!=null) { - ComponentConfigurator.configure(ps, params); - ps = decoratePropertySource(ps, contextBuilder, node, params); - LOG.finer("Adding configured property source: " + ps.getName()); - contextBuilder.addPropertySources(ps); - } - } catch (Exception e) { - LOG.log(Level.SEVERE, "Failed to configure PropertySource: " + type, e); - } - }else if(node.getNodeName().equals("source-provider")){ - String type = node.getAttributes().getNamedItem("type").getNodeValue(); - try { - ItemFactory<PropertySourceProvider> providerFactory = ItemFactoryManager.getInstance().getFactory(PropertySourceProvider.class, type); - if(providerFactory==null){ - LOG.severe("No such property source provider: " + type); - continue; - } - Map<String,String> params = ComponentConfigurator.extractParameters(node); - PropertySourceProvider prov = providerFactory.create(params); - if(prov!=null) { - ComponentConfigurator.configure(prov, node); - prov = decoratePropertySourceProvider(prov, contextBuilder, node, params); - LOG.finer("Adding configured property source provider: " + prov.getClass().getName()); - contextBuilder.addPropertySources(prov.getPropertySources()); - } - } catch (Exception e) { - LOG.log(Level.SEVERE, "Failed to configure PropertySourceProvider: " + type, e); + if(node.getNodeType()!=Node.ELEMENT_NODE) { + continue; + } + String type = node.getNodeName(); + if("defaults".equals(type)){ + LOG.fine("Adding default property sources."); + contextBuilder.addDefaultPropertySources(); + continue; + } + try { + ItemFactory<PropertySource> sourceFactory = ItemFactoryManager.getInstance().getFactory(PropertySource.class, type); + if (sourceFactory != null) { + LOG.fine("Property source found: " + type); + Map<String, String> params = ComponentConfigurator.extractParameters(node); + PropertySource ps = sourceFactory.create(params); + if (ps != null) { + ComponentConfigurator.configure(ps, params); + ps = decoratePropertySource(ps, node, params); + LOG.finer("Adding configured property source: " + ps.getName()); + contextBuilder.addPropertySources(ps); } - }else if(node.getNodeName().equals("default-sources")){ - LOG.finer("Adding default property sources."); - contextBuilder.addDefaultPropertySources(); } - }catch(Exception e){ - LOG.log(Level.SEVERE, "Failed to read property source configuration: " + node, e); + } catch (Exception e) { + LOG.log(Level.SEVERE, "Failed to configure PropertySource: " + type, e); + continue; + } + try { + ItemFactory<PropertySourceProvider> providerFactory = ItemFactoryManager.getInstance().getFactory(PropertySourceProvider.class, type); + if(providerFactory==null){ + LOG.fine("No such property source provider: " + type); + continue; + } + Map<String,String> params = ComponentConfigurator.extractParameters(node); + PropertySourceProvider prov = providerFactory.create(params); + if(prov!=null) { + ComponentConfigurator.configure(prov, node); + prov = decoratePropertySourceProvider(prov, node, params); + LOG.finer("Adding configured property source provider: " + prov.getClass().getName()); + contextBuilder.addPropertySources(prov.getPropertySources()); + } + } catch (Exception e) { + LOG.log(Level.SEVERE, "Failed to configure PropertySourceProvider: " + type, e); } } } @@ -111,37 +109,38 @@ public class PropertySourceReader implements MetaConfigurationReader{ /** * Decorates a property source to be refreshable or filtered. * @param ps the wrapped property source - * @param contextBuilder *@param configNode the XML config node * @param params the extracted parameter list @return the property source to be added to the context. */ - private PropertySource decoratePropertySource(PropertySource ps, ConfigurationContextBuilder contextBuilder, Node configNode, Map<String, String> params){ + private PropertySource decoratePropertySource(PropertySource ps, Node configNode, Map<String, String> params){ Node refreshableVal = configNode.getAttributes().getNamedItem("refreshable"); if(refreshableVal!=null && Boolean.parseBoolean(refreshableVal.getNodeValue())){ - if(!(ps instanceof Refreshable)){ - ps = RefreshablePropertySource.of(params, ps); - } + ps = RefreshablePropertySource.of(params, ps); + } + Node enabledVal = configNode.getAttributes().getNamedItem("enabled"); + if(enabledVal!=null){ + ps = new EnabledPropertySource(ps, + MetaContext.getInstance().getProperties(), + enabledVal.getNodeValue()); } NodeList childNodes = configNode.getChildNodes(); for(int i=0;i<childNodes.getLength();i++){ Node node = childNodes.item(i); - if("filter".equals(node.getNodeName())) { + if("filters".equals(node.getNodeName())){ ps = FilteredPropertySource.of(ps); - configureFilter((FilteredPropertySource) ps, node); + NodeList filterNodes = node.getChildNodes(); + for(int f=0;f<filterNodes.getLength();f++) { + Node filterNode = filterNodes.item(f); + configureFilter((FilteredPropertySource) ps, filterNode); + } } } - Node enabledVal = configNode.getAttributes().getNamedItem("enabled"); - if(enabledVal!=null){ - ps = new EnabledPropertySource(ps, - MetaContext.getDefaultInstance().getProperties(), - enabledVal.getNodeValue()); - } return ps; } private void configureFilter(FilteredPropertySource ps, Node filterNode) { try { - String type = filterNode.getAttributes().getNamedItem("type").getNodeValue(); + String type = filterNode.getNodeName(); ItemFactory<PropertyFilter> filterFactory = ItemFactoryManager.getInstance().getFactory(PropertyFilter.class, type); if(filterFactory==null){ LOG.severe("No such property filter: " + type); @@ -162,21 +161,20 @@ public class PropertySourceReader implements MetaConfigurationReader{ /** * Decorates a property source provider to be refreshable or filtered. * @param prov the property source provider to be wrapped. - * @param contextBuilder - *@param configNode the XML config node + * @param configNode the XML config node * @param params the extracted parameter list @return the property source provider to be added to the context. */ - private PropertySourceProvider decoratePropertySourceProvider(PropertySourceProvider prov, ConfigurationContextBuilder contextBuilder, Node configNode, Map<String, String> params){ + private PropertySourceProvider decoratePropertySourceProvider(PropertySourceProvider prov, Node configNode, Map<String, String> params){ Node refreshableVal = configNode.getAttributes().getNamedItem("refreshable"); + // Refreshable if(refreshableVal!=null && Boolean.parseBoolean(refreshableVal.getNodeValue())){ - if(!(prov instanceof Refreshable)){ - prov = RefreshablePropertySourceProvider.of(params, prov); - } + prov = RefreshablePropertySourceProvider.of(params, prov); } + // Enabled Node enabledVal = configNode.getAttributes().getNamedItem("enabled"); if(enabledVal!=null){ prov = new EnabledPropertySourceProvider(prov, - MetaContext.getDefaultInstance().getProperties(), + MetaContext.getInstance().getProperties(), enabledVal.getNodeValue()); } return prov; http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/FilePropertySourceFactory.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/FilePropertySourceFactory.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/FilePropertySourceFactory.java index d3961d4..5acfefd 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/FilePropertySourceFactory.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/FilePropertySourceFactory.java @@ -52,10 +52,8 @@ public final class FilePropertySourceFactory extends ResourcePropertySourceFacto @Override protected String example() { - return "<source type=\""+getName()+"\">\n" + - " <param name=\"location\">c:/temp/config.xml</param>\n" + - " <param name=\"formats\">xml-properties</param>\n" + - "</source>\n"; + return "<file location=\"c:/temp/config.xml\"\n" + + " formats=\"xml-properties\")>\n"; } @Override @@ -63,9 +61,9 @@ public final class FilePropertySourceFactory extends ResourcePropertySourceFacto try { Path path = Paths.get(location); if(!path.toFile().exists()){ - LOG.info("Cannot read resource '" + location + "': no such file."); + LOG.info("Cannot read file '" + location + "': no such file."); }else if(!path.toFile().canRead()){ - LOG.info("Cannot read resource '" + location + "': not readable."); + LOG.info("Cannot read file '" + location + "': not readable."); } return path.toUri().toURL(); } catch (MalformedURLException e) { http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceFactory.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceFactory.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceFactory.java index a36fd7f..0248100 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceFactory.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceFactory.java @@ -41,15 +41,13 @@ public class ResourcePropertySourceFactory extends URLPropertySourceFactory{ @Override public String getName() { - return "classpath"; + return "resource"; } protected String example() { - return "<source type=\""+getName()+"\">\n" + - " <param name=\"location\">/META-INF/config.xml</param>\n" + - " <param name=\"formats\">xml-properties</param>\n" + - "</source>\n"; + return "<resource location=\"META-INF/config.xml\"\n" + + " formats=\"xml-properties\")>\n"; } protected URL createResource(String location) { http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceProviderFactory.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceProviderFactory.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceProviderFactory.java index 77f22d4..db5c9b9 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceProviderFactory.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceProviderFactory.java @@ -41,7 +41,7 @@ public class ResourcePropertySourceProviderFactory implements ItemFactory<Proper @Override public String getName() { - return "resource"; + return "resources"; } @Override @@ -97,10 +97,8 @@ public class ResourcePropertySourceProviderFactory implements ItemFactory<Proper } protected String example() { - return "<source-provider type=\""+getName()+"\">\n" + - " <param name=\"location\">/META-INF/**/config.xml</param>\n" + - " <param name=\"formats\">xml-properties</param>\n" + - "</source-provider>\n"; + return "<resources location\"/META-INF/**/config.xml\"\n" + + " formats=\"xml-properties\"\n/>"; } protected Collection<URL> createResources(String location) { http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/URLPropertySourceFactory.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/URLPropertySourceFactory.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/URLPropertySourceFactory.java index 342eebb..7cf6ab6 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/URLPropertySourceFactory.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/URLPropertySourceFactory.java @@ -68,10 +68,8 @@ public class URLPropertySourceFactory implements ItemFactory<PropertySource>{ } protected String example() { - return "<source type=\""+getName()+"\">\n" + - " <param name=\"location\">http://127.0.0.1:1110/config.xml</param>\n" + - " <param name=\"formats\">xml-properties</param>\n" + - "</source>\n"; + return "<url location=\"http://127.0.0.1:1110/config.xml\"\n" + + " formats=\"xml-properties\"\n/>"; } protected URL createResource(String location) { http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/resolver/PropertiesResolver.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/resolver/PropertiesResolver.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/resolver/PropertiesResolver.java index 4edbe3e..4e70e03 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/resolver/PropertiesResolver.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/resolver/PropertiesResolver.java @@ -48,7 +48,7 @@ public final class PropertiesResolver implements SimpleResolver{ if(mainParts.length==1){ return evaluate(expression, null); }else{ - return evaluate(expression, mainParts[1].trim().substring("default=".length())); + return evaluate(mainParts[0], mainParts[1].trim().substring("default=".length())); } } @@ -59,7 +59,7 @@ public final class PropertiesResolver implements SimpleResolver{ return null; } switch(parts[0]){ - case "sys": + case "system": return System.getProperty(parts[1],defaultValue); case "env": String val = System.getenv(parts[1]); @@ -68,13 +68,8 @@ public final class PropertiesResolver implements SimpleResolver{ } return val; case "ctx": - if(parts.length==3){ - return MetaContext.getInstance(parts[1]) - .getProperty(parts[2], defaultValue); - }else{ - return MetaContext.getDefaultInstance() - .getProperty(parts[1], defaultValue); - } + return MetaContext.getInstance() + .getProperty(parts[1], defaultValue); default: return null; } http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.ItemFactory ---------------------------------------------------------------------- diff --git a/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.ItemFactory b/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.ItemFactory index 7b73763..951f4b8 100644 --- a/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.ItemFactory +++ b/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.ItemFactory @@ -24,3 +24,10 @@ org.apache.tamaya.metamodel.internal.factories.SysPropertiesFactory org.apache.tamaya.metamodel.internal.factories.URLPropertySourceFactory org.apache.tamaya.metamodel.internal.factories.ResourcePropertySourceProviderFactory + +org.apache.tamaya.metamodel.ImmutableFilter$ImmutableFilterFactory +org.apache.tamaya.metamodel.MapFilter$MapFilterFactory +org.apache.tamaya.metamodel.HideFilter$HideFilterFactory +org.apache.tamaya.metamodel.CachedFilter$CachedFilterFactory +org.apache.tamaya.metamodel.MaskFilter$MaskFilterFactory +org.apache.tamaya.metamodel.SecuredFilter$SecuredFilterFactory http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.MetaConfigurationReader ---------------------------------------------------------------------- diff --git a/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.MetaConfigurationReader b/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.MetaConfigurationReader index cd2af30..79b9249 100644 --- a/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.MetaConfigurationReader +++ b/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.MetaConfigurationReader @@ -20,7 +20,7 @@ org.apache.tamaya.metamodel.internal.PropertyFilterReader org.apache.tamaya.metamodel.internal.PropertyConverterReader org.apache.tamaya.metamodel.internal.PropertySourceReader -org.apache.tamaya.metamodel.internal.ContextReader +org.apache.tamaya.metamodel.internal.MetaContextReader org.apache.tamaya.metamodel.internal.CombinationPolicyReader org.apache.tamaya.metamodel.internal.PropertyFilterOrderingReader org.apache.tamaya.metamodel.internal.PropertySourceOrderingReader \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/test/java/org/apache/tamaya/metamodel/ext/IntegrationTest.java ---------------------------------------------------------------------- diff --git a/metamodel/src/test/java/org/apache/tamaya/metamodel/ext/IntegrationTest.java b/metamodel/src/test/java/org/apache/tamaya/metamodel/ext/IntegrationTest.java index 4462520..b461603 100644 --- a/metamodel/src/test/java/org/apache/tamaya/metamodel/ext/IntegrationTest.java +++ b/metamodel/src/test/java/org/apache/tamaya/metamodel/ext/IntegrationTest.java @@ -16,16 +16,23 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.tamaya.metamodel.ext; import org.apache.tamaya.Configuration; import org.apache.tamaya.ConfigurationProvider; +import org.apache.tamaya.TypeLiteral; +import org.apache.tamaya.metamodel.CachedFilter; +import org.apache.tamaya.metamodel.MapFilter; import org.apache.tamaya.metamodel.MetaConfiguration; +import org.apache.tamaya.metamodel.MetaContext; +import org.apache.tamaya.spi.PropertyConverter; import org.junit.Test; import java.net.URL; +import java.util.List; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.assertTrue; @@ -50,6 +57,104 @@ public class IntegrationTest { assertTrue(config.getContext().getPropertyFilters().isEmpty()); } + @Test + public void testMetaContextConfig(){ + Configuration config = MetaConfiguration.createConfiguration(getConfig("IntegrationTests/context-test.xml")); + assertNotNull(config); + assertTrue(config.getProperties().isEmpty()); + assertTrue(config.getContext().getPropertyConverters().isEmpty()); + assertTrue(config.getContext().getPropertyFilters().isEmpty()); + MetaContext ctx = MetaContext.getInstance(); + assertFalse(ctx.getProperties().isEmpty()); + assertEquals(ctx.getId(), ctx.getProperty("_id")); + assertEquals("NONE", ctx.getProperty("app")); + assertEquals("DEV", ctx.getProperty("stage")); + assertEquals(".", ctx.getProperty("configdir")); + + } + + @Test + public void testDefaultConvertersConfig(){ + Configuration config = MetaConfiguration.createConfiguration(getConfig("IntegrationTests/default-propertyconverters-test.xml")); + assertNotNull(config); + assertTrue(config.getContext().getPropertySources().isEmpty()); + assertTrue(config.getProperties().isEmpty()); + assertFalse(config.getContext().getPropertyConverters().isEmpty()); + assertTrue(config.getContext().getPropertyFilters().isEmpty()); + assertEquals(config.getContext(), + ConfigurationProvider.getConfigurationContextBuilder() + .addDefaultPropertyConverters() + .build()); + + } + + @Test + public void testDefaultPropertySourcesConfig(){ + Configuration config = MetaConfiguration.createConfiguration(getConfig("IntegrationTests/default-propertysources-test.xml")); + assertNotNull(config); + assertFalse(config.getProperties().isEmpty()); + assertFalse(config.getContext().getPropertySources().isEmpty()); + assertTrue(config.getContext().getPropertyConverters().isEmpty()); + assertTrue(config.getContext().getPropertyFilters().isEmpty()); + assertEquals(config.getContext(), + ConfigurationProvider.getConfigurationContextBuilder() + .addDefaultPropertySources() + .build()); + + } + + @Test + public void testDefaultPropertyFiltersConfig(){ + Configuration config = MetaConfiguration.createConfiguration(getConfig("IntegrationTests/default-propertyfilters-test.xml")); + assertNotNull(config); + assertTrue(config.getProperties().isEmpty()); + assertTrue(config.getContext().getPropertySources().isEmpty()); + assertTrue(config.getContext().getPropertyConverters().isEmpty()); + assertFalse(config.getContext().getPropertyFilters().isEmpty()); + assertEquals(config.getContext(), + ConfigurationProvider.getConfigurationContextBuilder() + .addDefaultPropertyFilters() + .build()); + + } + + @Test + public void testPropertyFiltersConfig(){ + Configuration config = MetaConfiguration.createConfiguration(getConfig("IntegrationTests/propertyfilters-test.xml")); + assertNotNull(config); + assertTrue(config.getProperties().isEmpty()); + assertTrue(config.getContext().getPropertySources().isEmpty()); + assertTrue(config.getContext().getPropertyConverters().isEmpty()); + assertFalse(config.getContext().getPropertyFilters().isEmpty()); + assertEquals(1, config.getContext().getPropertyFilters().size()); + assertTrue(config.getContext().getPropertyFilters().get(0) instanceof CachedFilter); + } + + @Test + public void testPropertyConvertersConfig(){ + Configuration config = MetaConfiguration.createConfiguration(getConfig("IntegrationTests/propertyconverters-test.xml")); + assertNotNull(config); + assertTrue(config.getProperties().isEmpty()); + assertTrue(config.getContext().getPropertySources().isEmpty()); + assertFalse(config.getContext().getPropertyConverters().isEmpty()); + assertTrue(config.getContext().getPropertyFilters().isEmpty()); + assertEquals(1, config.getContext().getPropertyConverters().size()); + List<PropertyConverter<Object>> converters = config.getContext().getPropertyConverters(TypeLiteral.of(String.class)); + assertTrue(converters.get(0).getClass().equals(MyConverter.class)); + } + + @Test + public void testPropertySourcesConfig(){ + Configuration config = MetaConfiguration.createConfiguration(getConfig("IntegrationTests/propertysources-test.xml")); + assertNotNull(config); + assertFalse(config.getProperties().isEmpty()); + assertFalse(config.getContext().getPropertySources().isEmpty()); + assertTrue(config.getContext().getPropertyConverters().isEmpty()); + assertTrue(config.getContext().getPropertyFilters().isEmpty()); + assertEquals(2, config.getContext().getPropertySources().size()); + assertTrue(config.getContext().getPropertySources().get(0) instanceof MyPropertySource); + } + private URL getConfig(String resource) { return getClass().getClassLoader().getResource(resource); }