http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/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 index a252f96..70b219e 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/MaskFilter.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/MaskFilter.java @@ -19,6 +19,7 @@ package org.apache.tamaya.metamodel; import org.apache.tamaya.metamodel.spi.ItemFactory; +import org.apache.tamaya.spi.Filter; import org.apache.tamaya.spi.FilterContext; import org.apache.tamaya.spi.PropertyFilter; import org.apache.tamaya.spi.PropertyValue; @@ -33,7 +34,7 @@ import java.util.Map; * is changing underneath, hereby different values for single and multi-property access * are considered. */ -public class MaskFilter implements PropertyFilter{ +public class MaskFilter implements Filter{ private String matches; private List<String> roles = new ArrayList<>(); @@ -43,20 +44,20 @@ public class MaskFilter implements PropertyFilter{ /** * Factory for configuring immutable property filter. */ - public static final class MaskFilterFactory implements ItemFactory<PropertyFilter> { + public static final class MaskFilterFactory implements ItemFactory<Filter> { @Override public String getName() { return "Mask"; } @Override - public PropertyFilter create(Map<String,String> parameters) { + public Filter create(Map<String,String> parameters) { return new MaskFilter(); } @Override - public Class<? extends PropertyFilter> getType() { - return PropertyFilter.class; + public Class<? extends Filter> getType() { + return Filter.class; } } @@ -113,9 +114,9 @@ public class MaskFilter implements PropertyFilter{ } @Override - public PropertyValue filterProperty(PropertyValue value, FilterContext context) { + public String filterProperty(String key, String value) { if(matches !=null){ - if(value.getKey().matches(matches)){ + if(key.matches(matches)){ return null; } }
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaConfiguration.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaConfiguration.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaConfiguration.java index 76172a6..8c1e14f 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaConfiguration.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaConfiguration.java @@ -18,16 +18,14 @@ */ package org.apache.tamaya.metamodel; -import org.apache.tamaya.ConfigException; -import org.apache.tamaya.Configuration; -import org.apache.tamaya.ConfigurationProvider; import org.apache.tamaya.metamodel.spi.MetaConfigurationReader; -import org.apache.tamaya.spi.ConfigurationContext; -import org.apache.tamaya.spi.ConfigurationContextBuilder; import org.apache.tamaya.spi.ServiceContextManager; import org.w3c.dom.Document; import org.xml.sax.SAXException; +import javax.config.Config; +import javax.config.spi.ConfigBuilder; +import javax.config.spi.ConfigProviderResolver; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.File; @@ -53,28 +51,28 @@ public final class MetaConfiguration { private MetaConfiguration(){} /** - * Creates a new {@link Configuration} using {@link #createConfiguration(URL)} - * and applies it as default configuration using {@link ConfigurationProvider#setConfiguration(Configuration)}. + * Creates a new {@link Config} using {@link #createConfiguration(URL)} + * and applies it as default configuration using {@link ConfigProviderResolver#registerConfig(Config, ClassLoader)} . */ - public static void configure(){ + public static void configure(ClassLoader classLoader){ LOG.info("TAMAYA: Checking for meta-configuration..."); URL configFile = getDefaultMetaConfig(); if(configFile==null){ LOG.warning("TAMAYA: No " + CONFIG_RESOURCE + " found, using defaults."); } - configure(configFile); + configure(configFile, classLoader); } /** - * Creates a new {@link Configuration} using {@link #createConfiguration(URL)} - * and applies it as default configuration using {@link ConfigurationProvider#setConfiguration(Configuration)}. + * Creates a new {@link Config} using {@link #createConfiguration(URL)} + * and applies it as default configuration using {@link ConfigProviderResolver#registerConfig(Config, ClassLoader)} . * @param metaConfig URL for loading the {@code tamaya-config.xml} meta-configuration. */ - public static void configure(URL metaConfig){ + public static void configure(URL metaConfig, ClassLoader classloader){ try { // Let readers do their work - Configuration config = createConfiguration(metaConfig); - ConfigurationProvider.setConfiguration(config); + Config config = createConfiguration(metaConfig); + ConfigProviderResolver.instance().registerConfig(config, classloader); }catch(Exception e){ LOG.log(Level.SEVERE, "TAMAYA: Error loading configuration.", e); } @@ -105,16 +103,16 @@ public final class MetaConfiguration { * instance. * @param metaConfig URL for loading the {@code tamaya-config.xml} meta-configuration. * @return a new configuration context builder, never null. - * @throws ConfigException If the URL cannot be read. + * @throws IllegalStateException If the URL cannot be read. */ - public static ConfigurationContextBuilder createContextBuilder(URL metaConfig){ + public static ConfigBuilder createConfigBuilder(URL metaConfig){ URL configFile = Objects.requireNonNull(metaConfig); LOG.info("TAMAYA: Loading tamaya-config.xml..."); Document document = null; try { document = DocumentBuilderFactory.newInstance() .newDocumentBuilder().parse(configFile.openStream()); - ConfigurationContextBuilder builder = ConfigurationProvider.getConfigurationContextBuilder(); + ConfigBuilder builder = ConfigProviderResolver.instance().getBuilder(); for(MetaConfigurationReader reader: ServiceContextManager.getServiceContext().getServices( MetaConfigurationReader.class )){ @@ -123,7 +121,7 @@ public final class MetaConfiguration { } return builder; } catch (SAXException | IOException | ParserConfigurationException e) { - throw new ConfigException("Cannot read meta-config deom " + metaConfig, e); + throw new IllegalStateException("Cannot read meta-config from " + metaConfig, e); } } @@ -134,9 +132,8 @@ public final class MetaConfiguration { * @param metaConfig URL for loading the {@code tamaya-config.xml} meta-configuration. * @return the new configuration instance. */ - public static Configuration createConfiguration(URL metaConfig){ - ConfigurationContext context = createContextBuilder(metaConfig).build(); - return ConfigurationProvider.createConfiguration(context); + public static Config createConfiguration(URL metaConfig){ + return createConfigBuilder(metaConfig).build(); } } http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/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 index 57171c3..ada6ebd 100644 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/SecuredFilter.java +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/SecuredFilter.java @@ -20,6 +20,7 @@ package org.apache.tamaya.metamodel; import org.apache.tamaya.ConfigException; import org.apache.tamaya.metamodel.spi.ItemFactory; +import org.apache.tamaya.spi.Filter; import org.apache.tamaya.spi.FilterContext; import org.apache.tamaya.spi.PropertyFilter; import org.apache.tamaya.spi.PropertyValue; @@ -34,7 +35,7 @@ import java.util.logging.Logger; * is changing underneath, hereby different values for single and multi-property access * are considered. */ -public class SecuredFilter implements PropertyFilter{ +public class SecuredFilter implements Filter{ private static final Logger LOG = Logger.getLogger(SecuredFilter.class.getName()); @@ -46,20 +47,20 @@ public class SecuredFilter implements PropertyFilter{ /** * Factory for configuring immutable property filter. */ - public static final class SecuredFilterFactory implements ItemFactory<PropertyFilter> { + public static final class SecuredFilterFactory implements ItemFactory<Filter> { @Override public String getName() { return "Secured"; } @Override - public PropertyFilter create(Map<String,String> parameters) { + public Filter create(Map<String,String> parameters) { return new SecuredFilter(); } @Override - public Class<? extends PropertyFilter> getType() { - return PropertyFilter.class; + public Class<? extends Filter> getType() { + return Filter.class; } } @@ -92,9 +93,9 @@ public class SecuredFilter implements PropertyFilter{ } @Override - public PropertyValue filterProperty(PropertyValue value, FilterContext context) { + public String filterProperty(String key, String value) { if(matches !=null){ - if(!value.getKey().matches(matches)) { + if(!key.matches(matches)) { return value; } } @@ -108,9 +109,9 @@ public class SecuredFilter implements PropertyFilter{ } switch(policy){ case THROW_EXCPETION: - throw new ConfigException("Unauthorized access to '"+value.getKey()+"', not in " + roles); + throw new IllegalStateException("Unauthorized access to '"+key+"', not in " + roles); case WARN_ONLY: - LOG.warning("Unauthorized access to '"+value.getKey()+"', not in " + roles); + LOG.warning("Unauthorized access to '"+key+"', not in " + roles); return value; case HIDE: default: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/EnabledConfigSourceProvider.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/EnabledConfigSourceProvider.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/EnabledConfigSourceProvider.java new file mode 100644 index 0000000..ba03ec2 --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/EnabledConfigSourceProvider.java @@ -0,0 +1,112 @@ +/* + * 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.ext; + +import org.apache.tamaya.metamodel.Enabled; + +import javax.config.spi.ConfigSource; +import javax.config.spi.ConfigSourceProvider; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import java.util.Collections; +import java.util.Map; +import java.util.Objects; +import java.util.logging.Logger; + +/** + * Wrapped property source provider that allows enabling a property source using an + * {@code enabled} expression. + */ +public final class EnabledConfigSourceProvider + implements ConfigSourceProvider, Enabled { + + private static final Logger LOG = Logger.getLogger(EnabledConfigSourceProvider.class.getName()); + private String enabledExpression; + private ConfigSourceProvider wrapped; + private boolean enabled; + + public EnabledConfigSourceProvider(ConfigSourceProvider wrapped, Map<String,String> context, String expression) { + this.enabledExpression = Objects.requireNonNull(expression); + this.wrapped = Objects.requireNonNull(wrapped); + this.enabled = calculateEnabled(context); + } + + protected boolean calculateEnabled(Map<String, String> context) { + try { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine engine = manager.getEngineByName("nashorn"); + if(engine==null){ + engine = manager.getEngineByName("rhino"); + } + // init script engine + for(Map.Entry<String,String> entry: context.entrySet()) { + engine.put(entry.getKey(), entry.getValue()); + } + Object o = engine.eval(enabledExpression); + if(!(o instanceof Boolean)){ + LOG.severe("Enabled expression must evaluate to Boolean: '" + +enabledExpression+"', but was " + o + + ", property source provider will be disabled: " + + wrapped.getClass().getName()); + return false; + } + return (Boolean)o; + } catch (ScriptException e) { + LOG.severe("Invalid Boolean expression: '" + +enabledExpression+"': " + e + ", property source provider will be disabled: " + + wrapped.getClass().getName()); + } + return false; + } + + /** + * Returns the enabled property. + * @return the enabled value. + */ + @Override + public boolean isEnabled(){ + return enabled; + } + + /** + * Enables/disables this property source. + * @param enabled the enabled value. + */ + @Override + public void setEnabled(boolean enabled){ + this.enabled = enabled; + } + + @Override + public Iterable<ConfigSource> getConfigSources(ClassLoader classLoader) { + if(!isEnabled()){ + return Collections.emptySet(); + } + return this.wrapped.getConfigSources(classLoader); + } + + @Override + public String toString() { + return "DynamicConfigSourceProvider{" + + "\n enabled=" + enabledExpression + + "\n wrapped=" + wrapped + + '}'; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/EnabledPropertySourceProvider.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/EnabledPropertySourceProvider.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/EnabledPropertySourceProvider.java deleted file mode 100644 index 88e0c78..0000000 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/EnabledPropertySourceProvider.java +++ /dev/null @@ -1,113 +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.ext; - -import org.apache.tamaya.metamodel.Enabled; -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertySourceProvider; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Objects; -import java.util.logging.Logger; - -/** - * Wrapped property source provider that allows enabling a property source using an - * {@code enabled} expression. - */ -public final class EnabledPropertySourceProvider - implements PropertySourceProvider, Enabled { - - private static final Logger LOG = Logger.getLogger(EnabledPropertySourceProvider.class.getName()); - private String enabledExpression; - private PropertySourceProvider wrapped; - private boolean enabled; - - public EnabledPropertySourceProvider(PropertySourceProvider wrapped, Map<String,String> context, String expression) { - this.enabledExpression = Objects.requireNonNull(expression); - this.wrapped = Objects.requireNonNull(wrapped); - this.enabled = calculateEnabled(context); - } - - protected boolean calculateEnabled(Map<String, String> context) { - try { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine engine = manager.getEngineByName("nashorn"); - if(engine==null){ - engine = manager.getEngineByName("rhino"); - } - // init script engine - for(Map.Entry<String,String> entry: context.entrySet()) { - engine.put(entry.getKey(), entry.getValue()); - } - Object o = engine.eval(enabledExpression); - if(!(o instanceof Boolean)){ - LOG.severe("Enabled expression must evaluate to Boolean: '" - +enabledExpression+"', but was " + o + - ", property source provider will be disabled: " + - wrapped.getClass().getName()); - return false; - } - return (Boolean)o; - } catch (ScriptException e) { - LOG.severe("Invalid Boolean expression: '" - +enabledExpression+"': " + e + ", property source provider will be disabled: " + - wrapped.getClass().getName()); - } - return false; - } - - /** - * Returns the enabled property. - * @return the enabled value. - */ - @Override - public boolean isEnabled(){ - return enabled; - } - - /** - * Enables/disables this property source. - * @param enabled the enabled value. - */ - @Override - public void setEnabled(boolean enabled){ - this.enabled = enabled; - } - - @Override - public Collection<PropertySource> getPropertySources() { - if(!isEnabled()){ - return Collections.emptySet(); - } - return this.wrapped.getPropertySources(); - } - - @Override - public String toString() { - return "DynamicPropertySourceProvider{" + - "\n enabled=" + enabledExpression + - "\n wrapped=" + wrapped + - '}'; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredConfigSource.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredConfigSource.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredConfigSource.java new file mode 100644 index 0000000..5cacc33 --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredConfigSource.java @@ -0,0 +1,173 @@ +/* + * 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.ext; + +import org.apache.tamaya.base.DefaultConfigBuilder; +import org.apache.tamaya.base.configsource.BaseConfigSource; +import org.apache.tamaya.base.configsource.ConfigSourceComparator; +import org.apache.tamaya.spi.*; +import javax.config.Config; + +import javax.config.spi.ConfigSource; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Property source that allows filtering on property source level. This class is thread-safe, accesses using or + * changing the filter list are synchronized. + */ +public final class FilteredConfigSource extends BaseConfigSource { + + private ConfigSource wrapped; + private List<Filter> filters = new ArrayList<>(); + private Config dummyContext = new DefaultConfigBuilder() + .withSources(this).build(); + + /** + * Constructor used privately. Use {@link #of(ConfigSource)} for making a {@link PropertySource} filterable. + * @param propertySource the property source to be filtered. + */ + private FilteredConfigSource(ConfigSource propertySource){ + this.wrapped = Objects.requireNonNull(propertySource); + } + + + /** + * Wraps a given property source. + * @param configSource the property source to be wrapped. + * @return a wrapped property source. + */ + public static FilteredConfigSource of(ConfigSource configSource){ + if(configSource instanceof FilteredConfigSource){ + return (FilteredConfigSource)configSource; + } + return new FilteredConfigSource(configSource); + } + + @Override + public int getOrdinal() { + int ordinalSet = super.getOrdinal(); + if(ordinalSet == 0){ + return ConfigSourceComparator.getOrdinal(this.wrapped); + } + return ordinalSet; + } + + @Override + public String getName() { + return wrapped.getName(); + } + + @Override + public String getValue(String key) { + String value = wrapped.getValue(key); + if(value != null){ + if(filters!=null){ + String filteredValue = value; + for(Filter pf:filters){ + filteredValue = pf.filterProperty(key, filteredValue); + } + if(filteredValue!=null){ + return filteredValue; + } + } + } + return null; + } + + @Override + public Map<String, String> getProperties() { + Map<String, String> props = wrapped.getProperties(); + if(!props.isEmpty()){ + Map<String, String> result = new HashMap<>(); + synchronized (filters) { + for (Map.Entry<String,String> en : props.entrySet()) { + String filteredValue = en.getValue(); + for (Filter pf : filters) { + filteredValue = pf.filterProperty(en.getKey(), filteredValue); + } + if (filteredValue != null) { + result.put(en.getKey(), filteredValue); + } + } + } + return result; + } + return Collections.emptyMap(); + } + + /** + * Adds the given filters to this property source. + * @param filter the filters, not null. + */ + public void addFilter(Filter... filter){ + synchronized(filters){ + this.filters.addAll(Arrays.asList(filter)); + } + } + + /** + * Removes the given filter, if present. + * @param filter the filter to remove, not null. + */ + public void removeFilter(Filter filter){ + synchronized(filters){ + this.filters.remove(filter); + } + } + + /** + * Removes the (first) given filter, if present. + * @param filterClass the class of the filter to remove, not null. + */ + public void removeFilter(Class<? extends Filter> filterClass){ + synchronized(filters){ + for(Filter f:filters){ + if(f.getClass().equals(filterClass)){ + filters.remove(f); + break; + } + } + } + } + + /** + * Access the current filters present. + * @return a copy of the current filter list. + */ + public List<Filter> getFilter(){ + synchronized (filters){ + return new ArrayList<>(filters); + } + } + + @Override + protected String toStringValues() { + synchronized (filters) { + return super.toStringValues() + + " wrapped=" + wrapped + '\n' + + " filters=" + this.filters + '\n'; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/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 deleted file mode 100644 index b67924b..0000000 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredPropertySource.java +++ /dev/null @@ -1,177 +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.ext; - -import org.apache.tamaya.spi.*; -import org.apache.tamaya.spisupport.propertysource.BasePropertySource; -import org.apache.tamaya.spisupport.DefaultConfigurationContextBuilder; -import org.apache.tamaya.spisupport.PropertySourceComparator; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -/** - * Property source that allows filtering on property source level. This class is thread-safe, accesses using or - * changing the filter list are synchronized. - */ -public final class FilteredPropertySource extends BasePropertySource { - - private PropertySource wrapped; - private List<PropertyFilter> filters = new ArrayList<>(); - private ConfigurationContext dummyContext = new DefaultConfigurationContextBuilder() - .addPropertySources(this).build(); - - /** - * Constructor used privately. Use {@link #of(PropertySource)} for making a {@link PropertySource} filterable. - * @param propertySource the property source to be filtered. - */ - private FilteredPropertySource(PropertySource propertySource){ - this.wrapped = Objects.requireNonNull(propertySource); - } - - - /** - * Wraps a given property source. - * @param propertySource the property source to be wrapped. - * @return a wrapped property source. - */ - public static FilteredPropertySource of(PropertySource propertySource){ - if(propertySource instanceof FilteredPropertySource){ - return (FilteredPropertySource)propertySource; - } - return new FilteredPropertySource(propertySource); - } - - @Override - public int getOrdinal() { - int ordinalSet = super.getOrdinal(); - if(ordinalSet == 0){ - return PropertySourceComparator.getOrdinal(this.wrapped); - } - return ordinalSet; - } - - @Override - public String getName() { - return wrapped.getName(); - } - - @Override - public PropertyValue get(String key) { - PropertyValue value = wrapped.get(key); - if(value != null && value.getValue()!=null){ - if(filters!=null){ - PropertyValue filteredValue = value; - for(PropertyFilter pf:filters){ - filteredValue = pf.filterProperty(filteredValue, new FilterContext(value, dummyContext)); - } - if(filteredValue!=null){ - return filteredValue; - } - } - } - return null; - } - - @Override - public Map<String, PropertyValue> getProperties() { - Map<String, PropertyValue> props = wrapped.getProperties(); - if(!props.isEmpty()){ - Map<String, PropertyValue> result = new HashMap<>(); - synchronized (filters) { - for (PropertyValue value : props.values()) { - FilterContext filterContext = new FilterContext(value, props, dummyContext); - PropertyValue filteredValue = value; - for (PropertyFilter pf : filters) { - filteredValue = pf.filterProperty(filteredValue, filterContext); - } - if (filteredValue != null) { - result.put(filteredValue.getKey(), filteredValue); - } - } - } - return result; - } - return Collections.emptyMap(); - } - - @Override - public boolean isScannable() { - return wrapped.isScannable(); - } - - /** - * Adds the given filters to this property source. - * @param filter the filters, not null. - */ - public void addPropertyFilter(PropertyFilter... filter){ - synchronized(filters){ - this.filters.addAll(Arrays.asList(filter)); - } - } - - /** - * Removes the given filter, if present. - * @param filter the filter to remove, not null. - */ - public void removePropertyFilter(PropertyFilter filter){ - synchronized(filters){ - this.filters.remove(filter); - } - } - - /** - * 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. - */ - public List<PropertyFilter> getPropertyFilter(){ - synchronized (filters){ - return new ArrayList<>(filters); - } - } - - @Override - protected String toStringValues() { - synchronized (filters) { - return super.toStringValues() + - " wrapped=" + wrapped + '\n' + - " filters=" + this.filters + '\n'; - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshableConfigSource.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshableConfigSource.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshableConfigSource.java new file mode 100644 index 0000000..b066f78 --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshableConfigSource.java @@ -0,0 +1,146 @@ +/* + * 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.ext; + +import org.apache.tamaya.base.configsource.ConfigSourceComparator; +import org.apache.tamaya.metamodel.Refreshable; +import org.apache.tamaya.metamodel.internal.ComponentConfigurator; + +import javax.config.spi.ConfigSource; +import java.util.Collections; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Level; +import java.util.logging.Logger; + + +/** + * Wrapped property source that allows refreshing/reloading a property source. Hereby a property source must + * either + * <ul> + * <li>have a public parameterless constructor, used for reloading a new instance.</li> + * <li>implement itself {@link Refreshable}.</li> + * </ul> + */ +public final class RefreshableConfigSource + implements ConfigSource, Refreshable { + + private static final Logger LOG = Logger.getLogger(RefreshableConfigSource.class.getName()); + private Map<String,String> metaConfig; + private ConfigSource wrapped; + private AtomicLong nextRefresh = new AtomicLong(); + private AtomicLong refreshPeriod = new AtomicLong(); + + private RefreshableConfigSource(Map<String,String> metaConfig, ConfigSource wrapped) { + this.metaConfig = Objects.requireNonNull(metaConfig); + this.wrapped = Objects.requireNonNull(wrapped); + } + + /** + * Makes a property source refreshable. If the given property source is already an instance of + * RefreshablePropertySource, the property source is returned. + * @param metaConfig the configuration parameters to be applied when a new PropertySource is created, not null. + * @param propertySource the property source, not null. + * @return a new instance, not null. + */ + public static RefreshableConfigSource of(Map<String,String> metaConfig, ConfigSource propertySource) { + if(propertySource instanceof RefreshableConfigSource){ + return (RefreshableConfigSource)propertySource; + } + return new RefreshableConfigSource(metaConfig, propertySource); + } + + /** + * Makes a property source refreshable. If the given property source is already an instance of + * RefreshablePropertySource, the property source is returned. + * @param propertySource the property source, not null. + * @return a new instance, not null. + */ + public static RefreshableConfigSource of(ConfigSource propertySource) { + return of(Collections.<String, String>emptyMap(), propertySource); + } + + /** + * Checks if the property source should autorefresh, if so {@link #refresh()} is called. + */ + private void checkRefresh(){ + long next = nextRefresh.get(); + if(next > 0 && next<System.currentTimeMillis()){ + nextRefresh.set(next + refreshPeriod.get()); + refresh(); + } + } + + /** + * Set the refresh period. This will be immedately applied from now. No explicit + * refresh will be triggered now. + * @param units + * @param timeUnit + */ + public void setRefreshPeriod(long units, TimeUnit timeUnit){ + this.refreshPeriod.set(timeUnit.toMillis(units)); + this.nextRefresh.set(System.currentTimeMillis() + this.refreshPeriod.get()); + } + + + @Override + public void refresh() { + try { + if(this.wrapped instanceof Refreshable){ + ((Refreshable) this.wrapped).refresh(); + }else { + this.wrapped = this.wrapped.getClass().newInstance(); + ComponentConfigurator.configure(this.wrapped, metaConfig); + } + } catch (Exception e) { + LOG.log(Level.WARNING, "Failed to reload/refresh PropertySource: " + + wrapped.getClass().getName(), e); + } + } + + @Override + public int getOrdinal() { + return ConfigSourceComparator.getOrdinal(this.wrapped); + } + + @Override + public String getName() { + return this.wrapped.getName(); + } + + @Override + public String getValue(String key) { + return this.wrapped.getValue(key); + } + + @Override + public Map<String, String> getProperties() { + return this.wrapped.getProperties(); + } + + @Override + public String toString() { + return "RefreshablePropertySource{" + + "\n metaConfig=" + metaConfig + + "\n wrapped=" + wrapped + + '}'; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshableConfigSourceProvider.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshableConfigSourceProvider.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshableConfigSourceProvider.java new file mode 100644 index 0000000..ce3d5ac --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshableConfigSourceProvider.java @@ -0,0 +1,110 @@ +/* + * 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.ext; + +import org.apache.tamaya.metamodel.Refreshable; +import org.apache.tamaya.metamodel.internal.ComponentConfigurator; +import org.apache.tamaya.spi.ServiceContext; + +import javax.config.spi.ConfigSource; +import javax.config.spi.ConfigSourceProvider; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Wrapped property source provider that allows refreshing/reloading a property source provider. Hereby a provider must + * either + * <ul> + * <li>have a public parameterless constructor, used for reloading a new instance.</li> + * <li>implement itself {@link Refreshable}.</li> + * </ul> + */ +public final class RefreshableConfigSourceProvider + implements ConfigSourceProvider, Refreshable { + + private static final Logger LOG = Logger.getLogger(RefreshableConfigSourceProvider.class.getName()); + private Map<String,String> metaConfig; + private ConfigSourceProvider wrapped; + private List<ConfigSource> configSources = new ArrayList<>(); + + private RefreshableConfigSourceProvider(Map<String,String> metaConfig, ConfigSourceProvider wrapped) { + this.metaConfig = Objects.requireNonNull(metaConfig); + this.wrapped = Objects.requireNonNull(wrapped); + for(ConfigSource cs: Objects.requireNonNull(wrapped.getConfigSources(ServiceContext.defaultClassLoader()))){ + this.configSources.add(cs); + } + } + + /** + * Makes a property source provider refreshable. If the given property source provider is already an instance of + * RefreshablePropertySourceProvider, the property source provider is returned unchanged. + * @param metaConfig the configuration parameters to be applied when a new PropertySourceProvider is created, not null. + * @param provider the property source provider, not null. + * @return a new instance, not null. + */ + public static RefreshableConfigSourceProvider of(Map<String,String> metaConfig, ConfigSourceProvider provider) { + if(provider instanceof RefreshableConfigSourceProvider){ + return (RefreshableConfigSourceProvider)provider; + } + return new RefreshableConfigSourceProvider(metaConfig, provider); + } + + /** + * Makes a property source refreshable. If the given property source is already an instance of + * RefreshablePropertySource, the property source is returned. + * @param provider the property source provider, not null. + * @return a new instance, not null. + */ + public static RefreshableConfigSourceProvider of(ConfigSourceProvider provider) { + return of(Collections.<String, String>emptyMap(), provider); + } + + @Override + public Iterable<ConfigSource> getConfigSources(ClassLoader classloader) { + return this.configSources; + } + + @Override + public void refresh() { + try { + if(this.wrapped instanceof Refreshable){ + ((Refreshable) this.wrapped).refresh(); + }else { + this.wrapped = this.wrapped.getClass().newInstance(); + ComponentConfigurator.configure(this.wrapped, metaConfig); + } + } catch (Exception e) { + LOG.log(Level.WARNING, "Failed to refresh PropertySourceProvider: " + + wrapped.getClass().getName(), e); + } + this.configSources.clear(); + for(ConfigSource cs: Objects.requireNonNull(wrapped.getConfigSources(ServiceContext.defaultClassLoader()))){ + this.configSources.add(cs); + } + } + + @Override + public String toString() { + return "RefreshablePropertySourceProvider{" + + "\n metaConfig=" + metaConfig + + "\n wrapped=" + wrapped + + '}'; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshablePropertySource.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshablePropertySource.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshablePropertySource.java deleted file mode 100644 index b5152c7..0000000 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshablePropertySource.java +++ /dev/null @@ -1,152 +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.ext; - -import org.apache.tamaya.metamodel.Refreshable; -import org.apache.tamaya.metamodel.internal.ComponentConfigurator; -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertyValue; -import org.apache.tamaya.spisupport.PropertySourceComparator; - -import java.util.Collections; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; -import java.util.logging.Level; -import java.util.logging.Logger; - - -/** - * Wrapped property source that allows refreshing/reloading a property source. Hereby a property source must - * either - * <ul> - * <li>have a public parameterless constructor, used for reloading a new instance.</li> - * <li>implement itself {@link Refreshable}.</li> - * </ul> - */ -public final class RefreshablePropertySource - implements PropertySource, Refreshable { - - private static final Logger LOG = Logger.getLogger(RefreshablePropertySource.class.getName()); - private Map<String,String> metaConfig; - private PropertySource wrapped; - private AtomicLong nextRefresh = new AtomicLong(); - private AtomicLong refreshPeriod = new AtomicLong(); - - private RefreshablePropertySource(Map<String,String> metaConfig, PropertySource wrapped) { - this.metaConfig = Objects.requireNonNull(metaConfig); - this.wrapped = Objects.requireNonNull(wrapped); - } - - /** - * Makes a property source refreshable. If the given property source is already an instance of - * RefreshablePropertySource, the property source is returned. - * @param metaConfig the configuration parameters to be applied when a new PropertySource is created, not null. - * @param propertySource the property source, not null. - * @return a new instance, not null. - */ - public static RefreshablePropertySource of(Map<String,String> metaConfig, PropertySource propertySource) { - if(propertySource instanceof RefreshablePropertySource){ - return (RefreshablePropertySource)propertySource; - } - return new RefreshablePropertySource(metaConfig, propertySource); - } - - /** - * Makes a property source refreshable. If the given property source is already an instance of - * RefreshablePropertySource, the property source is returned. - * @param propertySource the property source, not null. - * @return a new instance, not null. - */ - public static RefreshablePropertySource of(PropertySource propertySource) { - return of(Collections.<String, String>emptyMap(), propertySource); - } - - /** - * Checks if the property source should autorefresh, if so {@link #refresh()} is called. - */ - private void checkRefresh(){ - long next = nextRefresh.get(); - if(next > 0 && next<System.currentTimeMillis()){ - nextRefresh.set(next + refreshPeriod.get()); - refresh(); - } - } - - /** - * Set the refresh period. This will be immedately applied from now. No explicit - * refresh will be triggered now. - * @param units - * @param timeUnit - */ - public void setRefreshPeriod(long units, TimeUnit timeUnit){ - this.refreshPeriod.set(timeUnit.toMillis(units)); - this.nextRefresh.set(System.currentTimeMillis() + this.refreshPeriod.get()); - } - - - @Override - public void refresh() { - try { - if(this.wrapped instanceof Refreshable){ - ((Refreshable) this.wrapped).refresh(); - }else { - this.wrapped = this.wrapped.getClass().newInstance(); - ComponentConfigurator.configure(this.wrapped, metaConfig); - } - } catch (Exception e) { - LOG.log(Level.WARNING, "Failed to reload/refresh PropertySource: " + - wrapped.getClass().getName(), e); - } - } - - @Override - public int getOrdinal() { - return PropertySourceComparator.getOrdinal(this.wrapped); - } - - @Override - public String getName() { - return this.wrapped.getName(); - } - - @Override - public PropertyValue get(String key) { - return this.wrapped.get(key); - } - - @Override - public Map<String, PropertyValue> getProperties() { - return this.wrapped.getProperties(); - } - - @Override - public boolean isScannable() { - return this.wrapped.isScannable(); - } - - @Override - public String toString() { - return "RefreshablePropertySource{" + - "\n metaConfig=" + metaConfig + - "\n wrapped=" + wrapped + - '}'; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshablePropertySourceProvider.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshablePropertySourceProvider.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshablePropertySourceProvider.java deleted file mode 100644 index e4e23cf..0000000 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/RefreshablePropertySourceProvider.java +++ /dev/null @@ -1,107 +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.ext; - -import org.apache.tamaya.metamodel.Refreshable; -import org.apache.tamaya.metamodel.internal.ComponentConfigurator; -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertySourceProvider; - -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Wrapped property source provider that allows refreshing/reloading a property source provider. Hereby a provider must - * either - * <ul> - * <li>have a public parameterless constructor, used for reloading a new instance.</li> - * <li>implement itself {@link Refreshable}.</li> - * </ul> - */ -public final class RefreshablePropertySourceProvider - implements PropertySourceProvider, Refreshable { - - private static final Logger LOG = Logger.getLogger(RefreshablePropertySourceProvider.class.getName()); - private Map<String,String> metaConfig; - private PropertySourceProvider wrapped; - private Collection<PropertySource> propertSources; - - private RefreshablePropertySourceProvider(Map<String,String> metaConfig, PropertySourceProvider wrapped) { - this.metaConfig = Objects.requireNonNull(metaConfig); - this.wrapped = Objects.requireNonNull(wrapped); - this.propertSources = Objects.requireNonNull(wrapped.getPropertySources()); - } - - /** - * Makes a property source provider refreshable. If the given property source provider is already an instance of - * RefreshablePropertySourceProvider, the property source provider is returned unchanged. - * @param metaConfig the configuration parameters to be applied when a new PropertySourceProvider is created, not null. - * @param provider the property source provider, not null. - * @return a new instance, not null. - */ - public static RefreshablePropertySourceProvider of(Map<String,String> metaConfig, PropertySourceProvider provider) { - if(provider instanceof RefreshablePropertySourceProvider){ - return (RefreshablePropertySourceProvider)provider; - } - return new RefreshablePropertySourceProvider(metaConfig, provider); - } - - /** - * Makes a property source refreshable. If the given property source is already an instance of - * RefreshablePropertySource, the property source is returned. - * @param provider the property source provider, not null. - * @return a new instance, not null. - */ - public static RefreshablePropertySourceProvider of(PropertySourceProvider provider) { - return of(Collections.<String, String>emptyMap(), provider); - } - - @Override - public Collection<PropertySource> getPropertySources() { - return this.propertSources; - } - - @Override - public void refresh() { - try { - if(this.wrapped instanceof Refreshable){ - ((Refreshable) this.wrapped).refresh(); - }else { - this.wrapped = this.wrapped.getClass().newInstance(); - ComponentConfigurator.configure(this.wrapped, metaConfig); - } - } catch (Exception e) { - LOG.log(Level.WARNING, "Failed to refresh PropertySourceProvider: " + - wrapped.getClass().getName(), e); - } - this.propertSources = Objects.requireNonNull(wrapped.getPropertySources()); - } - - @Override - public String toString() { - return "RefreshablePropertySourceProvider{" + - "\n metaConfig=" + metaConfig + - "\n wrapped=" + wrapped + - '}'; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/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 48af79f..249990c 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 @@ -22,13 +22,14 @@ 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.PropertyValueCombinationPolicy; +import org.apache.tamaya.spi.ConfigValueCombinationPolicy; +import org.apache.tamaya.spi.TamayaConfigBuilder; import org.osgi.service.component.annotations.Component; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import javax.config.spi.ConfigBuilder; import java.util.logging.Logger; @@ -41,7 +42,7 @@ public class CombinationPolicyReader implements MetaConfigurationReader{ private static final Logger LOG = Logger.getLogger(CombinationPolicyReader.class.getName()); @Override - public void read(Document document, ConfigurationContextBuilder contextBuilder) { + public void read(Document document, ConfigBuilder configBuilder) { NodeList nodeList = document.getDocumentElement().getElementsByTagName("combination-policy"); if(nodeList.getLength()==0){ LOG.finest("No explicit combination policy configured, using default."); @@ -53,10 +54,10 @@ public class CombinationPolicyReader implements MetaConfigurationReader{ Node node = nodeList.item(0); 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)); + ItemFactory<ConfigValueCombinationPolicy> policyFactory = ItemFactoryManager.getInstance().getFactory(ConfigValueCombinationPolicy.class, type); + ConfigValueCombinationPolicy policy = policyFactory.create(ComponentConfigurator.extractParameters(node)); ComponentConfigurator.configure(policy, node); - contextBuilder.setPropertyValueCombinationPolicy(policy); + TamayaConfigBuilder.from(configBuilder).withPropertyValueCombinationPolicy(policy); } http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ConfigSourceOrderingReader.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ConfigSourceOrderingReader.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ConfigSourceOrderingReader.java new file mode 100644 index 0000000..4c18951 --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ConfigSourceOrderingReader.java @@ -0,0 +1,65 @@ +/* + * 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.spi.ItemFactory; +import org.apache.tamaya.metamodel.spi.ItemFactoryManager; +import org.apache.tamaya.metamodel.spi.MetaConfigurationReader; +import org.apache.tamaya.spi.TamayaConfigBuilder; +import org.osgi.service.component.annotations.Component; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.annotation.Priority; +import javax.config.spi.ConfigBuilder; +import java.util.Comparator; +import java.util.logging.Logger; + + +/** + * Metaconfiguration reader that reads the configuration combination policy to be used. + */ +@Component +@Priority(Integer.MAX_VALUE) +public class ConfigSourceOrderingReader implements MetaConfigurationReader{ + + private static final Logger LOG = Logger.getLogger(ConfigSourceOrderingReader.class.getName()); + + @Override + public void read(Document document, ConfigBuilder configBuilder) { + NodeList nodeList = document.getDocumentElement().getElementsByTagName("source-order"); + if(nodeList.getLength()==0){ + LOG.finer("No config source ordering defined."); + return; + } + if(nodeList.getLength()>1){ + throw new IllegalArgumentException("Only one source order can be applied."); + } + Node node = nodeList.item(0); + String type = node.getAttributes().getNamedItem("type").getNodeValue(); + ItemFactory<Comparator> comparatorFactory = ItemFactoryManager.getInstance().getFactory(Comparator.class, type); + Comparator comparator = comparatorFactory.create(ComponentConfigurator.extractParameters(node)); + ComponentConfigurator.configure(comparator, node); + LOG.finer("Sorting config sources using comparator: " + comparator.getClass().getName()); + TamayaConfigBuilder.from(configBuilder).sortSources(comparator); + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ConfigSourceReader.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ConfigSourceReader.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ConfigSourceReader.java new file mode 100644 index 0000000..9dc9c7e --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ConfigSourceReader.java @@ -0,0 +1,194 @@ +/* + * 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.EnabledConfigSource; +import org.apache.tamaya.metamodel.MetaContext; +import org.apache.tamaya.metamodel.ext.EnabledConfigSourceProvider; +import org.apache.tamaya.metamodel.ext.FilteredConfigSource; +import org.apache.tamaya.metamodel.ext.RefreshableConfigSource; +import org.apache.tamaya.metamodel.ext.RefreshableConfigSourceProvider; +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.Filter; +import org.apache.tamaya.spi.PropertyFilter; +import org.apache.tamaya.spi.ServiceContext; +import org.osgi.service.component.annotations.Component; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.config.spi.ConfigBuilder; +import javax.config.spi.ConfigSource; +import javax.config.spi.ConfigSourceProvider; +import java.util.Collections; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Metaconfiguration reader to read property sources and property source providers. + */ +@Component +public class ConfigSourceReader implements MetaConfigurationReader{ + + private static final Logger LOG = Logger.getLogger(ConfigSourceReader.class.getName()); + + @Override + public void read(Document document, ConfigBuilder configBuilder) { + NodeList nodeList = document.getDocumentElement().getElementsByTagName("sources"); + if(nodeList.getLength()==0){ + LOG.finer("No config sources configured."); + return; + } + if(nodeList.getLength()>1){ + throw new IllegalArgumentException("Only one single sources section allowed."); + } + nodeList = nodeList.item(0).getChildNodes(); + for(int i=0;i<nodeList.getLength();i++){ + Node node = nodeList.item(i); + if(node.getNodeType()!=Node.ELEMENT_NODE) { + continue; + } + String type = node.getNodeName(); + if("defaults".equals(type)){ + LOG.fine("Adding default config sources."); + configBuilder.addDefaultSources(); + continue; + }else if("discovered".equals(type)){ + LOG.fine("Adding default config sources."); + configBuilder.addDiscoveredSources(); + continue; + } + try { + ItemFactory<ConfigSource> sourceFactory = ItemFactoryManager.getInstance().getFactory(ConfigSource.class, type); + if (sourceFactory != null) { + LOG.fine("Config source found: " + type); + Map<String, String> params = ComponentConfigurator.extractParameters(node); + ConfigSource ps = sourceFactory.create(params); + if (ps != null) { + ComponentConfigurator.configure(ps, params); + ps = decorateConfigSource(ps, node, params); + LOG.finer("Adding configured config source: " + ps.getName()); + configBuilder.withSources(ps); + continue; + } + } + } catch (Exception e) { + LOG.log(Level.SEVERE, "Failed to configure config source: " + type, e); + continue; + } + try { + ItemFactory<ConfigSourceProvider> providerFactory = ItemFactoryManager.getInstance().getFactory(ConfigSourceProvider.class, type); + if(providerFactory==null){ + LOG.fine("No such config source provider: " + type); + continue; + } + Map<String,String> params = ComponentConfigurator.extractParameters(node); + ConfigSourceProvider prov = providerFactory.create(params); + if(prov!=null) { + ComponentConfigurator.configure(prov, node); + prov = decorateConfigSourceProvider(prov, node, params); + LOG.finer("Adding configured config source provider: " + prov.getClass().getName()); + for(ConfigSource cs:prov.getConfigSources(ServiceContext.defaultClassLoader())){ + configBuilder.withSources(cs); + } + } + } catch (Exception e) { + LOG.log(Level.SEVERE, "Failed to configure ConfigSourceProvider: " + type, e); + } + } + } + + /** + * Decorates a property source to be refreshable or filtered. + * @param ps the wrapped property source + *@param configNode the XML config node + * @param params the extracted parameter list @return the property source to be added to the context. + */ + private ConfigSource decorateConfigSource(ConfigSource ps, Node configNode, Map<String, String> params){ + Node refreshableVal = configNode.getAttributes().getNamedItem("refreshable"); + if(refreshableVal!=null && Boolean.parseBoolean(refreshableVal.getNodeValue())){ + ps = RefreshableConfigSource.of(params, ps); + } + Node enabledVal = configNode.getAttributes().getNamedItem("enabled"); + if(enabledVal!=null){ + ps = new EnabledConfigSource(ps, + MetaContext.getInstance().getProperties(), + enabledVal.getNodeValue()); + } + NodeList childNodes = configNode.getChildNodes(); + for(int i=0;i<childNodes.getLength();i++){ + Node node = childNodes.item(i); + if("filters".equals(node.getNodeName())){ + ps = FilteredConfigSource.of(ps); + NodeList filterNodes = node.getChildNodes(); + for(int f=0;f<filterNodes.getLength();f++) { + Node filterNode = filterNodes.item(f); + configureFilter((FilteredConfigSource) ps, filterNode); + } + } + } + return ps; + } + + private void configureFilter(FilteredConfigSource ps, Node filterNode) { + try { + String type = filterNode.getNodeName(); + ItemFactory<Filter> filterFactory = ItemFactoryManager.getInstance().getFactory(Filter.class, type); + if(filterFactory==null){ + LOG.severe("No such filter: " + type); + return; + } + Map<String,String> params = ComponentConfigurator.extractParameters(filterNode); + Filter filter = filterFactory.create(params); + if(filter!=null) { + ComponentConfigurator.configure(filter, params); + LOG.finer("Adding configured filter: " + filter.getClass().getName()); + ps.addFilter(filter); + } + }catch(Exception e){ + LOG.log(Level.SEVERE, "Failed to read filter configuration: " + filterNode, e); + } + } + + /** + * Decorates a property source provider to be refreshable or filtered. + * @param prov the property source provider to be wrapped. + * @param configNode the XML config node + * @param params the extracted parameter list @return the property source provider to be added to the context. + */ + private ConfigSourceProvider decorateConfigSourceProvider(ConfigSourceProvider prov, Node configNode, Map<String, String> params){ + Node refreshableVal = configNode.getAttributes().getNamedItem("refreshable"); + // Refreshable + if(refreshableVal!=null && Boolean.parseBoolean(refreshableVal.getNodeValue())){ + prov = RefreshableConfigSourceProvider.of(params, prov); + } + // Enabled + Node enabledVal = configNode.getAttributes().getNamedItem("enabled"); + if(enabledVal!=null){ + prov = new EnabledConfigSourceProvider(prov, + MetaContext.getInstance().getProperties(), + enabledVal.getNodeValue()); + } + return prov; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ConverterReader.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ConverterReader.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ConverterReader.java new file mode 100644 index 0000000..77b85af --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ConverterReader.java @@ -0,0 +1,85 @@ +/* + * 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.spi.ItemFactory; +import org.apache.tamaya.metamodel.spi.ItemFactoryManager; +import org.apache.tamaya.metamodel.spi.MetaConfigurationReader; +import org.osgi.service.component.annotations.Component; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.config.spi.ConfigBuilder; +import javax.config.spi.Converter; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Metaconfiguration reader to read property sources and property source providers. + */ +@Component +public class ConverterReader implements MetaConfigurationReader{ + + private static final Logger LOG = Logger.getLogger(ConverterReader.class.getName()); + + @Override + public void read(Document document, ConfigBuilder configBuilder) { + NodeList nodeList = document.getDocumentElement().getElementsByTagName("converters"); + if(nodeList.getLength()==0){ + LOG.finer("No converters configured"); + return; + } + if(nodeList.getLength()>1){ + throw new IllegalArgumentException("Only one single converters section allowed."); + } + nodeList = nodeList.item(0).getChildNodes(); + for(int i=0;i<nodeList.getLength();i++){ + Node node = nodeList.item(i); + if(node.getNodeType()!=Node.ELEMENT_NODE) { + continue; + } + String type = node.getNodeName(); + if("defaults".equals(type)){ + LOG.finer("Adding default converters..."); + configBuilder.addDiscoveredConverters(); + continue; + } + try { + ItemFactory<Converter> converterFactory = ItemFactoryManager.getInstance().getFactory(Converter.class, type); + if(converterFactory==null){ + LOG.severe("No such property converter: " + type); + continue; + } + Map<String,String> params = ComponentConfigurator.extractParameters(node); + Converter 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()); + configBuilder.withConverters(converter); + } + } 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/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/DSLBasedConfigFactory.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/DSLBasedConfigFactory.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/DSLBasedConfigFactory.java new file mode 100644 index 0000000..52ed876 --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/DSLBasedConfigFactory.java @@ -0,0 +1,54 @@ +/* + * 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.base.DefaultConfigBuilder; +import org.apache.tamaya.base.configsource.ConfigSourceComparator; +import org.apache.tamaya.base.filter.FilterComparator; +import org.apache.tamaya.core.TamayaConfigProviderResolver; +import org.apache.tamaya.metamodel.MetaConfiguration; +import org.osgi.service.component.annotations.Component; + +import javax.annotation.Priority; +import javax.config.Config; + + +/** + * ConfigFactory that uses {@link MetaConfiguration} to create new Config instances for + * the Tamaya Configuration System. This class is not usable when an alternate + * Configuration implementation is active. Instead use the methods in {@link MetaConfiguration} + * to configure/setup your configuration system. + */ +@Priority(1) +@Component +public class DSLBasedConfigFactory implements TamayaConfigProviderResolver.ConfigFactory{ + + @Override + public Config createConfig(ClassLoader classLoader) { + MetaConfiguration.configure(classLoader); + return new DefaultConfigBuilder() + .addDiscoveredConverters() + .addDiscoveredFilters() + .addDefaultSources() + .addDiscoveredSources() + .sortFilter(FilterComparator.getInstance()) + .sortSources(ConfigSourceComparator.getInstance()) + .build(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/DSLLoadingConfigurationProviderSpi.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/DSLLoadingConfigurationProviderSpi.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/DSLLoadingConfigurationProviderSpi.java deleted file mode 100644 index 5243796..0000000 --- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/DSLLoadingConfigurationProviderSpi.java +++ /dev/null @@ -1,110 +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.MetaConfiguration; -import org.apache.tamaya.Configuration; -import org.apache.tamaya.spi.ConfigurationContext; -import org.apache.tamaya.spi.ConfigurationContextBuilder; -import org.apache.tamaya.spi.ConfigurationProviderSpi; -import org.apache.tamaya.spi.ServiceContextManager; -import org.apache.tamaya.spisupport.DefaultConfiguration; -import org.apache.tamaya.spisupport.DefaultConfigurationContextBuilder; -import org.apache.tamaya.spisupport.PropertyFilterComparator; -import org.apache.tamaya.spisupport.PropertySourceComparator; -import org.osgi.service.component.annotations.Component; - -import javax.annotation.Priority; -import java.util.Objects; - -/** - * ConfigurationContext that uses {@link MetaConfiguration} to configure the - * Tamaya configuration context. - */ -@Priority(10) -@Component -public class DSLLoadingConfigurationProviderSpi implements ConfigurationProviderSpi{ - - private volatile Configuration config; - private final Object LOCK = new Object(); - - @Override - public ConfigurationContextBuilder getConfigurationContextBuilder() { - return ServiceContextManager.getServiceContext().create(ConfigurationContextBuilder.class); - } - - @Override - public void setConfiguration(Configuration config) { - this.config = Objects.requireNonNull(config); - } - - @Override - public boolean isConfigurationSettable() { - return true; - } - - @Override - public void setConfigurationContext(ConfigurationContext context){ - this.config = Objects.requireNonNull(createConfiguration(context)); - } - - @Override - public boolean isConfigurationContextSettable() { - return true; - } - - @Override - public Configuration getConfiguration() { - checkInitialized(); - return config; - } - - @Override - public Configuration createConfiguration(ConfigurationContext context) { - return new DefaultConfiguration(context); - } - - @Override - public ConfigurationContext getConfigurationContext() { - checkInitialized(); - return config.getContext(); - } - - private void checkInitialized() { - if(config==null){ - synchronized (LOCK) { - if(config==null){ - MetaConfiguration.configure(); - } - if(config==null){ - // load defaults - this.config = new DefaultConfiguration( - new DefaultConfigurationContextBuilder() - .addDefaultPropertyConverters() - .addDefaultPropertyFilters() - .addDefaultPropertySources() - .sortPropertyFilter(PropertyFilterComparator.getInstance()) - .sortPropertySources(PropertySourceComparator.getInstance()) - .build()); - } - } - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/db6b909a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/FilterOrderingReader.java ---------------------------------------------------------------------- diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/FilterOrderingReader.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/FilterOrderingReader.java new file mode 100644 index 0000000..24d6856 --- /dev/null +++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/FilterOrderingReader.java @@ -0,0 +1,65 @@ +/* + * 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.spi.ItemFactory; +import org.apache.tamaya.metamodel.spi.ItemFactoryManager; +import org.apache.tamaya.metamodel.spi.MetaConfigurationReader; +import org.apache.tamaya.spi.TamayaConfigBuilder; +import org.osgi.service.component.annotations.Component; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.annotation.Priority; +import javax.config.spi.ConfigBuilder; +import java.util.Comparator; +import java.util.logging.Logger; + + +/** + * Metaconfiguration reader that reads the configuration combination policy to be used. + */ +@Component +@Priority(Integer.MAX_VALUE) +public class FilterOrderingReader implements MetaConfigurationReader{ + + private static final Logger LOG = Logger.getLogger(FilterOrderingReader.class.getName()); + + @Override + public void read(Document document, ConfigBuilder configBuilder) { + NodeList nodeList = document.getDocumentElement().getElementsByTagName("filter-order"); + if(nodeList.getLength()==0){ + LOG.finer("No filter ordering configured."); + return; + } + if(nodeList.getLength()>1){ + throw new IllegalArgumentException("Only one filter order can be applied."); + } + Node node = nodeList.item(0); + String type = node.getAttributes().getNamedItem("type").getNodeValue(); + ItemFactory<Comparator> comparatorFactory = ItemFactoryManager.getInstance().getFactory(Comparator.class, type); + Comparator comparator = comparatorFactory.create(ComponentConfigurator.extractParameters(node)); + ComponentConfigurator.configure(comparator, node); + LOG.finer("Sorting filters using comparator: " + comparator.getClass().getName()); + TamayaConfigBuilder.from(configBuilder).sortFilter(comparator); + } + + +}
