http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContextBuilder.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContextBuilder.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContextBuilder.java deleted file mode 100644 index 079527f..0000000 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContextBuilder.java +++ /dev/null @@ -1,437 +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.spisupport; - -import org.apache.tamaya.TypeLiteral; -import org.apache.tamaya.spi.*; -import org.apache.tamaya.spisupport.propertysource.CLIPropertySource; -import org.apache.tamaya.spisupport.propertysource.EnvironmentPropertySource; -import org.apache.tamaya.spisupport.propertysource.JavaConfigurationPropertySource; -import org.apache.tamaya.spisupport.propertysource.SystemPropertySource; - -import java.io.File; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.URI; -import java.net.URL; -import java.nio.file.Path; -import java.util.*; -import java.util.logging.Logger; - -/** - * Default implementation of {@link ConfigurationContextBuilder}. - */ -public class DefaultConfigurationContextBuilder implements ConfigurationContextBuilder { - - private static final Logger LOG = Logger.getLogger(DefaultConfigurationContextBuilder.class.getName()); - - protected List<PropertyFilter> propertyFilters = new ArrayList<>(); - protected List<PropertySource> propertySources = new ArrayList<>(); - protected PropertyValueCombinationPolicy combinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_POLICY; - protected Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> propertyConverters = new HashMap<>(); - - /** - * Flag if the config has already been built. - * Configuration can be built only once - */ - private boolean built; - - - - /** - * Creates a new builder instance. - */ - public DefaultConfigurationContextBuilder() { - } - - /** - * Creates a new builder instance initializing it with the given context. - * @param context the context to be used, not null. - */ - public DefaultConfigurationContextBuilder(ConfigurationContext context) { - this.propertyConverters.putAll(context.getPropertyConverters()); - this.propertyFilters.addAll(context.getPropertyFilters()); - for(PropertySource ps:context.getPropertySources()) { - addPropertySources(ps); - } - this.combinationPolicy = context.getPropertyValueCombinationPolicy(); - } - - /** - * Allows to reset configuration context during unit tests. - */ - public final ConfigurationContextBuilder resetWithConfigurationContext(ConfigurationContext configurationContext) { - checkBuilderState(); - //noinspection deprecation - this.propertyFilters.clear(); - this.propertyFilters.addAll(configurationContext.getPropertyFilters()); - this.propertySources.clear(); - for(PropertySource ps:configurationContext.getPropertySources()) { - addPropertySources(ps); - } - this.propertyConverters.clear(); - this.propertyConverters.putAll(configurationContext.getPropertyConverters()); - this.combinationPolicy = configurationContext.getPropertyValueCombinationPolicy(); - return this; - } - - - @Override - public ConfigurationContextBuilder setContext(ConfigurationContext context) { - checkBuilderState(); - this.propertyConverters.putAll(context.getPropertyConverters()); - for(PropertySource ps:context.getPropertySources()){ - this.propertySources.add(ps); - } - this.propertyFilters.addAll(context.getPropertyFilters()); - this.combinationPolicy = context.getPropertyValueCombinationPolicy(); - return this; - } - - @Override - public final ConfigurationContextBuilder addPropertySources(PropertySource... sources){ - return addPropertySources(Arrays.asList(sources)); - } - - @Override - public ConfigurationContextBuilder addPropertySources(Collection<PropertySource> sources){ - checkBuilderState(); - for(PropertySource source:sources) { - if (!this.propertySources.contains(source)) { - this.propertySources.add(source); - } - } - return this; - } - - @Override - public ConfigurationContextBuilder addDefaultPropertySources() { - checkBuilderState(); - List<PropertySource> propertySources = new ArrayList<>(); - addCorePropertyResources(propertySources); - for(PropertySource ps: ServiceContextManager.getServiceContext().getServices(PropertySource.class)) { - if(!propertySources.contains(ps)){ - propertySources.add(ps); - } - } - for(PropertySourceProvider provider: - ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class)){ - propertySources.addAll(provider.getPropertySources()); - } - Collections.sort(propertySources, PropertySourceComparator.getInstance()); - return addPropertySources(propertySources); - } - - protected void addCorePropertyResources(List<PropertySource> propertySources) { - for(PropertySource ps: new PropertySource[]{ - new EnvironmentPropertySource(), - new JavaConfigurationPropertySource(), - new CLIPropertySource(), - new SystemPropertySource() - }){ - if(!propertySources.contains(ps)){ - propertySources.add(ps); - } - } - } - - @Override - public ConfigurationContextBuilder addDefaultPropertyFilters() { - checkBuilderState(); - for(PropertyFilter pf:ServiceContextManager.getServiceContext().getServices(PropertyFilter.class)){ - addPropertyFilters(pf); - } - return this; - } - - @Override - public DefaultConfigurationContextBuilder addDefaultPropertyConverters() { - checkBuilderState(); - addCorePropertyConverters(); - for(Map.Entry<TypeLiteral, Collection<PropertyConverter>> en:getDefaultPropertyConverters().entrySet()){ - for(PropertyConverter pc: en.getValue()) { - addPropertyConverters(en.getKey(), pc); - } - } - return this; - } - - @SuppressWarnings("unchecked") - protected void addCorePropertyConverters() { - // should be overridden by subclasses. - } - - @Override - public final ConfigurationContextBuilder removePropertySources(PropertySource... propertySources) { - return removePropertySources(Arrays.asList(propertySources)); - } - - @Override - public ConfigurationContextBuilder removePropertySources(Collection<PropertySource> propertySources) { - checkBuilderState(); - this.propertySources.removeAll(propertySources); - return this; - } - - protected PropertySource getPropertySource(String name) { - for(PropertySource ps:propertySources){ - if(ps.getName().equals(name)){ - return ps; - } - } - throw new IllegalArgumentException("No such PropertySource: "+name); - } - - @Override - public List<PropertySource> getPropertySources() { - return Collections.unmodifiableList(this.propertySources); - } - - @Override - public ConfigurationContextBuilder increasePriority(PropertySource propertySource) { - checkBuilderState(); - int index = propertySources.indexOf(propertySource); - if(index<0){ - throw new IllegalArgumentException("No such PropertySource: " + propertySource); - } - if(index<(propertySources.size()-1)){ - propertySources.remove(propertySource); - propertySources.add(index+1, propertySource); - } - return this; - } - - @Override - public ConfigurationContextBuilder decreasePriority(PropertySource propertySource) { - checkBuilderState(); - int index = propertySources.indexOf(propertySource); - if(index<0){ - throw new IllegalArgumentException("No such PropertySource: " + propertySource); - } - if(index>0){ - propertySources.remove(propertySource); - propertySources.add(index-1, propertySource); - } - return this; - } - - @Override - public ConfigurationContextBuilder highestPriority(PropertySource propertySource) { - checkBuilderState(); - int index = propertySources.indexOf(propertySource); - if(index<0){ - throw new IllegalArgumentException("No such PropertySource: " + propertySource); - } - if(index<(propertySources.size()-1)){ - propertySources.remove(propertySource); - propertySources.add(propertySource); - } - return this; - } - - @Override - public ConfigurationContextBuilder lowestPriority(PropertySource propertySource) { - checkBuilderState(); - int index = propertySources.indexOf(propertySource); - if(index<0){ - throw new IllegalArgumentException("No such PropertySource: " + propertySource); - } - if(index>0){ - propertySources.remove(propertySource); - propertySources.add(0, propertySource); - } - return this; - } - - @Override - public final ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters){ - return addPropertyFilters(Arrays.asList(filters)); - } - - @Override - public final ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters){ - checkBuilderState(); - for(PropertyFilter f:filters) { - if (!this.propertyFilters.contains(f)) { - this.propertyFilters.add(f); - } - } - return this; - } - - @Override - public final ConfigurationContextBuilder removePropertyFilters(PropertyFilter... filters) { - return removePropertyFilters(Arrays.asList(filters)); - } - - @Override - public final ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters) { - checkBuilderState(); - this.propertyFilters.removeAll(filters); - return this; - } - - - @Override - public final <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert, - @SuppressWarnings("unchecked") PropertyConverter<T>... converters) { - return removePropertyConverters(typeToConvert, Arrays.asList(converters)); - } - - @Override - public final <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert, - Collection<PropertyConverter<T>> converters) { - Collection<PropertyConverter<?>> subConverters = this.propertyConverters.get(typeToConvert); - if(subConverters!=null) { - subConverters.removeAll(converters); - } - return this; - } - - @Override - public final ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert) { - this.propertyConverters.remove(typeToConvert); - return this; - } - - - @Override - public final ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy combinationPolicy){ - checkBuilderState(); - this.combinationPolicy = Objects.requireNonNull(combinationPolicy); - return this; - } - - - @Override - public <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> type, PropertyConverter<T>... propertyConverters){ - checkBuilderState(); - Objects.requireNonNull(type); - Objects.requireNonNull(propertyConverters); - Collection<PropertyConverter<?>> converters = this.propertyConverters.get(type); - if(converters==null){ - converters = new ArrayList<>(); - this.propertyConverters.put(type, converters); - } - for(PropertyConverter<T> propertyConverter:propertyConverters) { - if (!converters.contains(propertyConverter)) { - converters.add(propertyConverter); - } else { - LOG.warning("Converter ignored, already registered: " + propertyConverter); - } - } - return this; - } - - @Override - public <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> type, Collection<PropertyConverter<T>> propertyConverters){ - checkBuilderState(); - Objects.requireNonNull(type); - Objects.requireNonNull(propertyConverters); - Collection<PropertyConverter<?>> converters = this.propertyConverters.get(type); - if(converters==null){ - converters = new ArrayList<>(); - this.propertyConverters.put(type, converters); - } - for(PropertyConverter<T> propertyConverter:propertyConverters) { - if (!converters.contains(propertyConverter)) { - converters.add(propertyConverter); - } else { - LOG.warning("Converter ignored, already registered: " + propertyConverter); - } - } - return this; - } - - protected ConfigurationContextBuilder loadDefaults() { - checkBuilderState(); - this.combinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR; - addDefaultPropertySources(); - addDefaultPropertyFilters(); - addDefaultPropertyConverters(); - return this; - } - - - protected Map<TypeLiteral, Collection<PropertyConverter>> getDefaultPropertyConverters() { - Map<TypeLiteral, Collection<PropertyConverter>> result = new HashMap<>(); - for (PropertyConverter conv : ServiceContextManager.getServiceContext().getServices( - PropertyConverter.class)) { - for(Type type:conv.getClass().getGenericInterfaces()){ - if(type instanceof ParameterizedType){ - ParameterizedType pt = (ParameterizedType)type; - if(PropertyConverter.class.equals(((ParameterizedType) type).getRawType())){ - TypeLiteral target = TypeLiteral.of(pt.getActualTypeArguments()[0]); - Collection<PropertyConverter> convList = result.get(target); - if (convList == null) { - convList = new ArrayList<>(); - result.put(target, convList); - } - convList.add(conv); - } - } - } - } - return result; - } - - - /** - * Builds a new configuration based on the configuration of this builder instance. - * - * @return a new {@link org.apache.tamaya.Configuration configuration instance}, - * never {@code null}. - */ - @Override - public ConfigurationContext build() { - checkBuilderState(); - built = true; - return new DefaultConfigurationContext(this); - } - - @Override - public ConfigurationContextBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator) { - Collections.sort(propertyFilters, comparator); - return this; - } - - @Override - public ConfigurationContextBuilder sortPropertySources(Comparator<PropertySource> comparator) { - Collections.sort(propertySources, comparator); - return this; - } - - private void checkBuilderState() { - if (built) { - throw new IllegalStateException("Configuration has already been build."); - } - } - - @Override - public List<PropertyFilter> getPropertyFilters() { - return propertyFilters; - } - - @Override - public Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> getPropertyConverter() { - return Collections.unmodifiableMap(this.propertyConverters); - } -}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java deleted file mode 100644 index 61819f9..0000000 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java +++ /dev/null @@ -1,204 +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.spisupport; - -import org.apache.tamaya.ConfigException; -import org.apache.tamaya.spi.ServiceContext; - -import javax.annotation.Priority; -import java.io.IOException; -import java.net.URL; -import java.text.MessageFormat; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class implements the (default) {@link ServiceContext} interface and hereby uses the JDK - * {@link ServiceLoader} to load the services required. - */ -public final class DefaultServiceContext implements ServiceContext { - private static final Logger LOG = Logger.getLogger(DefaultServiceContext.class.getName()); - /** - * List current services loaded, per class. - */ - private final ConcurrentHashMap<Class<?>, List<Object>> servicesLoaded = new ConcurrentHashMap<>(); - /** - * Singletons. - */ - private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>(); - @SuppressWarnings("rawtypes") - private Map<Class, Class> factoryTypes = new ConcurrentHashMap<>(); - - @Override - public <T> T getService(Class<T> serviceType) { - Object cached = singletons.get(serviceType); - if (cached == null) { - cached = create(serviceType); - if(cached!=null) { - singletons.put(serviceType, cached); - } - } - return serviceType.cast(cached); - } - - @Override - public <T> T create(Class<T> serviceType) { - @SuppressWarnings("unchecked") - Class<? extends T> implType = factoryTypes.get(serviceType); - if(implType==null) { - Collection<T> services = getServices(serviceType); - if (services.isEmpty()) { - return null; - } else { - return getServiceWithHighestPriority(services, serviceType); - } - } - try { - return implType.newInstance(); - } catch (Exception e) { - LOG.log(Level.SEVERE, "Failed to create instance of " + implType.getName(), e); - return null; - } - } - - /** - * Loads and registers services. - * - * @param <T> the concrete type. - * @param serviceType The service type. - * @return the items found, never {@code null}. - */ - @Override - public <T> List<T> getServices(final Class<T> serviceType) { - @SuppressWarnings("unchecked") - List<T> found = (List<T>) servicesLoaded.get(serviceType); - if (found != null) { - return found; - } - List<T> services = new ArrayList<>(); - try { - for (T t : ServiceLoader.load(serviceType)) { - services.add(t); - } - if(services.isEmpty()) { - for (T t : ServiceLoader.load(serviceType, serviceType.getClassLoader())) { - services.add(t); - } - } - Collections.sort(services, PriorityServiceComparator.getInstance()); - services = Collections.unmodifiableList(services); - } catch (ServiceConfigurationError e) { - LOG.log(Level.WARNING, - "Error loading services current type " + serviceType, e); - if(services==null){ - services = Collections.emptyList(); - } - } - @SuppressWarnings("unchecked") - final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services)); - return previousServices != null ? previousServices : services; - } - - /** - * Checks the given instance for a @Priority annotation. If present the annotation's value is evaluated. If no such - * annotation is present, a default priority of {@code 1} is returned. - * @param o the instance, not {@code null}. - * @return a priority, by default 1. - */ - public static int getPriority(Object o){ - int prio = 1; //X TODO discuss default priority - Priority priority = o.getClass().getAnnotation(Priority.class); - if (priority != null) { - prio = priority.value(); - } - return prio; - } - - /** - * @param services to scan - * @param <T> type of the service - * - * @return the service with the highest {@link Priority#value()} - * - * @throws ConfigException if there are multiple service implementations with the maximum priority - */ - private <T> T getServiceWithHighestPriority(Collection<T> services, Class<T> serviceType) { - T highestService = null; - // we do not need the priority stuff if the list contains only one element - if (services.size() == 1) { - highestService = services.iterator().next(); - this.factoryTypes.put(serviceType, highestService.getClass()); - return highestService; - } - - Integer highestPriority = null; - int highestPriorityServiceCount = 0; - - for (T service : services) { - int prio = getPriority(service); - if (highestPriority == null || highestPriority < prio) { - highestService = service; - highestPriorityServiceCount = 1; - highestPriority = prio; - } else if (highestPriority == prio) { - highestPriorityServiceCount++; - } - } - - if (highestPriorityServiceCount > 1) { - throw new ConfigException(MessageFormat.format("Found {0} implementations for Service {1} with Priority {2}: {3}", - highestPriorityServiceCount, - serviceType.getName(), - highestPriority, - services)); - } - this.factoryTypes.put(serviceType, highestService.getClass()); - return highestService; - } - - @Override - public int ordinal() { - return 1; - } - - @Override - public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException { - if(cl==null){ - cl = Thread.currentThread().getContextClassLoader(); - } - if(cl==null){ - cl = getClass().getClassLoader(); - } - return cl.getResources(resource); - } - - @Override - public URL getResource(String resource, ClassLoader cl) { - if(cl==null){ - cl = Thread.currentThread().getContextClassLoader(); - } - if(cl==null){ - cl = getClass().getClassLoader(); - } - return cl.getResource(resource); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java deleted file mode 100644 index ed5214a..0000000 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java +++ /dev/null @@ -1,83 +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.spisupport; - -import org.apache.tamaya.ConfigException; -import org.apache.tamaya.spi.ConversionContext; -import org.apache.tamaya.spi.PropertyConverter; -import org.osgi.service.component.annotations.Component; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Locale; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Converter, converting from String to tge given enum type. - */ -@Component(service = PropertyConverter.class) -public class EnumConverter<T> implements PropertyConverter<T> { - private final Logger LOG = Logger.getLogger(EnumConverter.class.getName()); - private Class<T> enumType; - private Method factory; - - public EnumConverter(Class<T> enumType) { - if (!Enum.class.isAssignableFrom(enumType)) { - throw new IllegalArgumentException("Not an Enum: " + enumType.getName()); - } - this.enumType = Objects.requireNonNull(enumType); - try { - this.factory = enumType.getMethod("valueOf", String.class); - } catch (NoSuchMethodException e) { - throw new ConfigException("Uncovertible enum type without valueOf method found, please provide a custom " + - "PropertyConverter for: " + enumType.getName()); - } - } - - @Override - public T convert(String value, ConversionContext context) { - context.addSupportedFormats(getClass(),"<enumValue>"); - try { - return (T) factory.invoke(null, value); - } catch (InvocationTargetException | IllegalAccessException e) { - LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e); - } - try { - return (T) factory.invoke(null, value.toUpperCase(Locale.ENGLISH)); - } catch (InvocationTargetException | IllegalAccessException e) { - LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e); - } - return null; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof EnumConverter)) return false; - EnumConverter<?> that = (EnumConverter<?>) o; - return Objects.equals(enumType, that.enumType); - } - - @Override - public int hashCode() { - return Objects.hash(enumType); - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java deleted file mode 100644 index dbef51f..0000000 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java +++ /dev/null @@ -1,84 +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.spisupport; - -import javax.annotation.Priority; -import java.io.Serializable; -import java.util.Comparator; - -/** - * Comparator implementation for odering services loaded based on their increasing priority values. - */ -public class PriorityServiceComparator implements Comparator<Object>, Serializable { - - private static final long serialVersionUID = 1L; - - private static final PriorityServiceComparator INSTANCE = new PriorityServiceComparator(); - - /** Singleton constructor. */ - private PriorityServiceComparator(){} - - /** - * Get the shared instance of the comparator. - * @return the shared instance, never null. - */ - public static PriorityServiceComparator getInstance(){ - return INSTANCE; - } - - @Override - public int compare(Object o1, Object o2) { - int prio = getPriority(o1) - getPriority(o2); - if (prio < 0) { - return 1; - } else if (prio > 0) { - return -1; - } else { - return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName()); - } - } - - /** - * Checks the given instance for a @Priority annotation. If present the annotation's value is evaluated. If no such - * annotation is present, a default priority {@code 1} is returned. - * - * @param o the instance, not {@code null}. - * @return a priority, by default 1. - */ - public static int getPriority(Object o) { - return getPriority(o.getClass()); - } - - /** - * Checks the given type optionally annotated with a @Priority. If present the annotation's value is evaluated. - * If no such annotation is present, a default priority {@code 1} is returned. - * - * @param type the type, not {@code null}. - * @return a priority, by default 1. - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public static int getPriority(Class type) { - int prio = 1; - Priority priority = (Priority)type.getAnnotation(Priority.class); - if (priority != null) { - prio = priority.value(); - } - return prio; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java deleted file mode 100644 index 921cac6..0000000 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java +++ /dev/null @@ -1,471 +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.spisupport; - -import org.apache.tamaya.ConfigException; -import org.apache.tamaya.TypeLiteral; -import org.apache.tamaya.spi.ConversionContext; -import org.apache.tamaya.spi.PropertyConverter; -import org.apache.tamaya.spi.ServiceContextManager; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Manager that deals with {@link PropertyConverter} instances. - * This class is thread-safe. - */ -public class PropertyConverterManager { - /** - * The logger used. - */ - private static final Logger LOG = Logger.getLogger(PropertyConverterManager.class.getName()); - /** - * The registered converters. - */ - private final Map<TypeLiteral<?>, List<PropertyConverter<?>>> converters = new ConcurrentHashMap<>(); - /** - * The transitive converters. - */ - private final Map<TypeLiteral<?>, List<PropertyConverter<?>>> transitiveConverters = new ConcurrentHashMap<>(); - /** - * The lock used. - */ - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - - private static final Comparator<Object> PRIORITY_COMPARATOR = new Comparator<Object>() { - - @Override - public int compare(Object o1, Object o2) { - int prio = PriorityServiceComparator.getPriority(o1) - PriorityServiceComparator.getPriority(o2); - if (prio < 0) { - return 1; - } else if (prio > 0) { - return -1; - } else { - return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName()); - } - } - }; - - /** - * Constructor. - */ - public PropertyConverterManager() { - this(false); - } - - public PropertyConverterManager(boolean init) { - if (init) { - initConverters(); - } - } - - /** - * Registers the default converters provided out of the box. - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected void initConverters() { - for (PropertyConverter conv : ServiceContextManager.getServiceContext().getServices(PropertyConverter.class)) { - Type type = TypeLiteral.getGenericInterfaceTypeParameters(conv.getClass(), PropertyConverter.class)[0]; - register(TypeLiteral.of(type), conv); - } - } - - /** - * Registers a new converters instance. - * - * @param targetType the target type, not {@code null}. - * @param converter the converters, not {@code null}. - * @param <T> the type. - */ - @SuppressWarnings("unchecked") - public <T> void register(TypeLiteral<T> targetType, PropertyConverter<T> converter) { - Objects.requireNonNull(converter); - Lock writeLock = lock.writeLock(); - try { - writeLock.lock(); - List<PropertyConverter<?>> converters = List.class.cast(this.converters.get(targetType)); - if(converters!=null && converters.contains(converter)){ - return; - } - List<PropertyConverter<?>> newConverters = new ArrayList<>(); - if (converters != null) { - newConverters.addAll(converters); - } - if(!newConverters.contains(converter)) { - newConverters.add(converter); - } - Collections.sort(newConverters, PRIORITY_COMPARATOR); - this.converters.put(targetType, Collections.unmodifiableList(newConverters)); - // evaluate transitive closure for all inherited supertypes and implemented interfaces - // direct implemented interfaces - for (Class<?> ifaceType : targetType.getRawType().getInterfaces()) { - converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(ifaceType))); - newConverters = new ArrayList<>(); - if (converters != null) { - newConverters.addAll(converters); - } - newConverters.add(converter); - Collections.sort(newConverters, PRIORITY_COMPARATOR); - this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters)); - } - Class<?> superClass = targetType.getRawType().getSuperclass(); - while (superClass != null && !superClass.equals(Object.class)) { - converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(superClass))); - newConverters = new ArrayList<>(); - if (converters != null) { - newConverters.addAll(converters); - } - newConverters.add(converter); - Collections.sort(newConverters, PRIORITY_COMPARATOR); - this.transitiveConverters.put(TypeLiteral.of(superClass), Collections.unmodifiableList(newConverters)); - for (Class<?> ifaceType : superClass.getInterfaces()) { - converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(ifaceType))); - newConverters = new ArrayList<>(); - if (converters != null) { - newConverters.addAll(converters); - } - newConverters.add(converter); - Collections.sort(newConverters, PRIORITY_COMPARATOR); - this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters)); - } - superClass = superClass.getSuperclass(); - } - } finally { - writeLock.unlock(); - } - } - - /** - * Allows to evaluate if a given target type is supported. - * - * @param targetType the target type, not {@code null}. - * @return true, if a converters for the given type is registered, or a default one can be created. - */ - public boolean isTargetTypeSupported(TypeLiteral<?> targetType) { - return converters.containsKey(targetType) || transitiveConverters.containsKey(targetType) || createDefaultPropertyConverter(targetType) != null; - } - - /** - * Get a map of all property converters currently registered. This will not contain the converters that - * may be created, when an instance is adapted, which provides a String constructor or compatible - * factory methods taking a single String instance. - * - * @return the current map of instantiated and registered converters. - * @see #createDefaultPropertyConverter(org.apache.tamaya.TypeLiteral) - */ - public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() { - Lock readLock = lock.readLock(); - try { - readLock.lock(); - return new HashMap<>(this.converters); - } finally { - readLock.unlock(); - } - } - - /** - * Get the list of all current registered converters for the given target type. - * If not converters are registered, they component tries to create and register a dynamic - * converters based on String constructor or static factory methods available. - * The converters provided are of the following type and returned in the following order: - * <ul> - * <li>Converters mapped explicitly to the required target type are returned first, ordered - * by decreasing priority. This means, if explicit converters are registered these are used - * primarily for converting a value.</li> - * <li>The target type of each explicitly registered converters also can be transitively mapped to - * 1) all directly implemented interfaces, 2) all its superclasses (except Object), 3) all the interfaces - * implemented by its superclasses. These groups of transitive converters is returned similarly in the - * order as mentioned, whereas also here a priority based decreasing ordering is applied.</li> - * <li>java.lang wrapper classes and native types are automatically mapped.</li> - * <li>If no explicit converters are registered, for Enum types a default implementation is provided that - * compares the configuration values with the different enum members defined (cases sensitive mapping).</li> - * </ul> - * <p> - * So given that list above directly registered mappings always are tried first, before any transitive mapping - * should be used. Also in all cases @Priority annotations are honored for ordering of the converters in place. - * Transitive conversion is supported for all directly implemented interfaces (including inherited ones) and - * the inheritance hierarchy (exception Object). Superinterfaces of implemented interfaces are ignored. - * - * @param targetType the target type, not {@code null}. - * @param <T> the type class - * @return the ordered list of converters (may be empty for not convertible types). - * @see #createDefaultPropertyConverter(org.apache.tamaya.TypeLiteral) - */ - public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) { - Lock readLock = lock.readLock(); - List<PropertyConverter<T>> converterList = new ArrayList<>(); - // direct mapped converters - try { - readLock.lock(); - addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList); - addConvertersToList(List.class.cast(this.transitiveConverters.get(targetType)), converterList); - } finally { - readLock.unlock(); - } - // handling of java.lang wrapper classes - TypeLiteral<T> boxedType = mapBoxedType(targetType); - if (boxedType != null) { - try { - readLock.lock(); - addConvertersToList(List.class.cast(this.converters.get(boxedType)), converterList); - } finally { - readLock.unlock(); - } - } - if (converterList.isEmpty() && !TypeLiteral.of(String.class).equals(targetType)) { - // adding any converters created on the fly, e.g. for enum types. - PropertyConverter<T> defaultConverter = createDefaultPropertyConverter(targetType); - if (defaultConverter != null) { - register(targetType, defaultConverter); - try { - readLock.lock(); - addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList); - } finally { - readLock.unlock(); - } - } - } - // check for parametrized types, ignoring param type - // direct mapped converters - if(targetType.getType()!=null) { - try { - readLock.lock(); - addConvertersToList(List.class.cast(this.converters.get( - TypeLiteral.of(targetType.getRawType()))), converterList); - } finally { - readLock.unlock(); - } - } - return converterList; - } - - private <T> void addConvertersToList(Collection<PropertyConverter<T>> converters, List<PropertyConverter<T>> converterList) { - if (converters != null) { - for(PropertyConverter<T> conv:converters) { - if(!converterList.contains(conv)) { - converterList.add(conv); - } - } - } - } - - /** - * Maps native types to the corresponding boxed types. - * - * @param targetType the native type. - * @param <T> the type - * @return the boxed type, or null. - */ - @SuppressWarnings("unchecked") - private <T> TypeLiteral<T> mapBoxedType(TypeLiteral<T> targetType) { - Type parameterType = targetType.getType(); - if (parameterType == int.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Integer.class)); - } - if (parameterType == short.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Short.class)); - } - if (parameterType == byte.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Byte.class)); - } - if (parameterType == long.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Long.class)); - } - if (parameterType == boolean.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class)); - } - if (parameterType == char.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Character.class)); - } - if (parameterType == float.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Float.class)); - } - if (parameterType == double.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Double.class)); - } - if (parameterType == int[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Integer[].class)); - } - if (parameterType == short[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Short[].class)); - } - if (parameterType == byte[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Byte[].class)); - } - if (parameterType == long[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Long[].class)); - } - if (parameterType == boolean.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class)); - } - if (parameterType == char[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Character[].class)); - } - if (parameterType == float[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Float[].class)); - } - if (parameterType == double[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Double[].class)); - } - return null; - } - - /** - * Creates a dynamic PropertyConverter for the given target type. - * - * @param targetType the target type - * @param <T> the type class - * @return a new converters, or null. - */ - protected <T> PropertyConverter<T> createDefaultPropertyConverter(final TypeLiteral<T> targetType) { - if (Enum.class.isAssignableFrom(targetType.getRawType())) { - return new EnumConverter<>(targetType.getRawType()); - } - PropertyConverter<T> converter = null; - final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "valueOf", "instanceOf", "getInstance", "from", "fromString", "parse"); - if (factoryMethod != null) { - converter = new DefaultPropertyConverter<>(factoryMethod, targetType.getRawType()); - } - if (converter == null) { - final Constructor<T> constr; - try { - constr = targetType.getRawType().getDeclaredConstructor(String.class); - } catch (NoSuchMethodException e) { - LOG.log(Level.FINEST, "No matching constrctor for " + targetType, e); - return null; - } - converter = new PropertyConverter<T>() { - @Override - public T convert(String value, ConversionContext context) { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @Override - public Object run() { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @Override - public Object run() { - constr.setAccessible(true); - return null; - } - }); - return null; - } - }); - try { - return constr.newInstance(value); - } catch (Exception e) { - LOG.log(Level.SEVERE, "Error creating new PropertyConverter instance " + targetType, e); - } - return null; - } - }; - } - return converter; - } - - /** - * Tries to evaluate a factory method that can be used to create an instance based on a String. - * - * @param type the target type - * @param methodNames the possible static method names - * @return the first method found, or null. - */ - private Method getFactoryMethod(Class<?> type, String... methodNames) { - Method m; - for (String name : methodNames) { - try { - m = type.getDeclaredMethod(name, String.class); - return m; - } catch (NoSuchMethodException | RuntimeException e) { - LOG.finest("No such factory method found on type: " + type.getName() + ", methodName: " + name); - } - } - return null; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof PropertyConverterManager)) { - return false; - } - PropertyConverterManager that = (PropertyConverterManager) o; - return converters.equals(that.converters); - - } - - @Override - public int hashCode() { - return converters.hashCode(); - } - - /** - * Default converters imüöementation perfoming several lookups for String converion - * option. - * @param <T> - */ - private static class DefaultPropertyConverter<T> implements PropertyConverter<T> { - - private final Method factoryMethod; - private final Class<T> targetType; - - DefaultPropertyConverter(Method factoryMethod, Class<T> targetType){ - this.factoryMethod = Objects.requireNonNull(factoryMethod); - this.targetType = Objects.requireNonNull(targetType); - } - - @Override - public T convert(String value, ConversionContext context) { - context.addSupportedFormats(getClass(), "<String -> "+factoryMethod.toGenericString()); - - if (!Modifier.isStatic(factoryMethod.getModifiers())) { - throw new ConfigException(factoryMethod.toGenericString() + - " is not a static method. Only static " + - "methods can be used as factory methods."); - } - try { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @Override - public Object run() { - factoryMethod.setAccessible(true); - return null; - } - }); - Object invoke = factoryMethod.invoke(null, value); - return targetType.cast(invoke); - } catch (Exception e) { - throw new ConfigException("Failed to decode '" + value + "'", e); - } - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java deleted file mode 100644 index 20eef63..0000000 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java +++ /dev/null @@ -1,72 +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.spisupport; - -import org.apache.tamaya.spi.PropertyFilter; - -import javax.annotation.Priority; -import java.io.Serializable; -import java.util.Comparator; - -/** - * Comparator for PropertyFilters based on their priority annotations. - */ -public final class PropertyFilterComparator implements Comparator<PropertyFilter>, Serializable { - - private static final long serialVersionUID = 1L; - - private static final PropertyFilterComparator INSTANCE = new PropertyFilterComparator(); - - /** - * Get the shared instance of the comparator. - * @return the shared instance, never null. - */ - public static PropertyFilterComparator getInstance(){ - return INSTANCE; - } - - private PropertyFilterComparator(){} - - /** - * Compare 2 filters for ordering the filter chain. - * - * @param filter1 the first filter - * @param filter2 the second filter - * @return the comparison result - */ - private int comparePropertyFilters(PropertyFilter filter1, PropertyFilter filter2) { - Priority prio1 = filter1.getClass().getAnnotation(Priority.class); - Priority prio2 = filter2.getClass().getAnnotation(Priority.class); - int ord1 = prio1 != null ? prio1.value() : 0; - int ord2 = prio2 != null ? prio2.value() : 0; - - if (ord1 < ord2) { - return -1; - } else if (ord1 > ord2) { - return 1; - } else { - return filter1.getClass().getName().compareTo(filter2.getClass().getName()); - } - } - - @Override - public int compare(PropertyFilter filter1, PropertyFilter filter2) { - return comparePropertyFilters(filter1, filter2); - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java deleted file mode 100644 index 20f1aaf..0000000 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java +++ /dev/null @@ -1,124 +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.spisupport; - -import org.apache.tamaya.spi.ConfigurationContext; -import org.apache.tamaya.spi.FilterContext; -import org.apache.tamaya.spi.PropertyFilter; -import org.apache.tamaya.spi.PropertyValue; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the - * chain of {@link org.apache.tamaya.spi.PropertySource} and {@link PropertyFilter} - * instance to evaluate the current Configuration. - */ -public final class PropertyFiltering{ - /** - * The logger. - */ - private static final Logger LOG = Logger.getLogger(PropertyFiltering.class.getName()); - /** - * The maximal number of filter cycles performed before aborting. - */ - private static final int MAX_FILTER_LOOPS = 10; - - /** - * Private singleton constructor. - */ - private PropertyFiltering(){} - - /** - * Filters a single value. - * @param value the raw value, not {@code null}. - * @param context the context - * @return the filtered value, including {@code null}. - */ - public static PropertyValue applyFilter(PropertyValue value, ConfigurationContext context) { - FilterContext filterContext = new FilterContext(value, context); - return filterValue(filterContext); - } - - /** - * Filters all properties. - * @param rawProperties the unfiltered properties, not {@code null}. - * @param context the context - * @return the filtered value, inclusing null. - */ - public static Map<String, PropertyValue> applyFilters(Map<String, PropertyValue> rawProperties, ConfigurationContext context) { - Map<String, PropertyValue> result = new HashMap<>(); - // Apply filters to values, prevent values filtered to null! - for (Map.Entry<String, PropertyValue> entry : rawProperties.entrySet()) { - FilterContext filterContext = new FilterContext(entry.getValue(), rawProperties, context); - PropertyValue filtered = filterValue(filterContext); - if(filtered!=null){ - result.put(filtered.getKey(), filtered); - } - } - return result; - } - - /** - * Basic filter logic. - * @param context the filter context, not {@code null}. - * @return the filtered value. - */ - private static PropertyValue filterValue(FilterContext context) { - PropertyValue inputValue = context.getProperty(); - PropertyValue filteredValue = inputValue; - - for (int i = 0; i < MAX_FILTER_LOOPS; i++) { - int changes = 0; - for (PropertyFilter filter : context.getContext().getPropertyFilters()) { - filteredValue = filter.filterProperty(inputValue, context); - if (filteredValue != null && !filteredValue.equals(inputValue)) { - changes++; - LOG.finest("Filter - " + inputValue + " -> " + filteredValue + " by " + filter); - } - if(filteredValue==null){ - LOG.finest("Filter removed entry - " + inputValue + ": " + filter); - break; - }else{ - inputValue = filteredValue; - } - } - if (changes == 0) { - LOG.finest("Finishing filter loop, no changes detected."); - break; - } else if (filteredValue == null) { - break; - } else { - if (i == (MAX_FILTER_LOOPS - 1)) { - if (LOG.isLoggable(Level.WARNING)) { - LOG.warning("Maximal filter loop count reached, aborting filter evaluation after cycles: " + i); - } - } else { - LOG.finest("Repeating filter loop, changes detected: " + changes); - } - } - } - return filteredValue; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java deleted file mode 100644 index d572335..0000000 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java +++ /dev/null @@ -1,122 +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.spisupport; - -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertyValue; - -import javax.annotation.Priority; -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.Comparator; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Comparator for ordering of PropertySources based on their ordinal method and class name. - */ -public class PropertySourceComparator implements Comparator<PropertySource>, Serializable { - /** serial version UID. */ - private static final long serialVersionUID = 1L; - - private static final Logger LOG = Logger.getLogger(PropertySourceComparator.class.getName()); - - private static final PropertySourceComparator INSTANCE = new PropertySourceComparator(); - - private String alternativeOrdinalKey; - - /** Singleton constructor. */ - private PropertySourceComparator(){} - - /** - * Get the shared instance of the comparator. - * @return the shared instance, never null. - */ - public static PropertySourceComparator getInstance(){ - return INSTANCE; - } - - - /** - * Order property source reversely, the most important comes first. - * - * @param source1 the first PropertySource - * @param source2 the second PropertySource - * @return the comparison result. - */ - private int comparePropertySources(PropertySource source1, PropertySource source2) { - if (getOrdinal(source1) < getOrdinal(source2)) { - return -1; - } else if (getOrdinal(source1) > getOrdinal(source2)) { - return 1; - } else { - return source1.getClass().getName().compareTo(source2.getClass().getName()); - } - } - - /** - * Evaluates an ordinal value from a {@link PropertySource}, Hereby the ordinal of type {@code int} - * is evaluated as follows: - * <ol> - * <li>It evaluates the {@code String} value for {@link PropertySource#TAMAYA_ORDINAL} and tries - * to convert it to an {@code int} value, using {@link Integer#parseInt(String)}.</li> - * <li>It tries to find and evaluate a method {@code int getOrdinal()}.</li> - * <li>It tries to find and evaluate a static field {@code int ORDINAL}.</li> - * <li>It tries to find and evaluate a class level {@link Priority} annotation.</li> - * <li>It uses the default priority ({@code 0}.</li> - * </ol> - * @param propertySource the property source, not {@code null}. - * @return the ordinal value to compare the property source. - */ - public static int getOrdinal(PropertySource propertySource) { - return getOrdinal(propertySource, null); - } - - public static int getOrdinal(PropertySource propertySource, String alternativeOrdinalKey) { - if(alternativeOrdinalKey!=null) { - PropertyValue ordinalValue = propertySource.get(alternativeOrdinalKey); - if (ordinalValue != null) { - try { - return Integer.parseInt(ordinalValue.getValue().trim()); - } catch (Exception e) { - LOG.finest("Failed to parse ordinal from " + alternativeOrdinalKey + - " in " + propertySource.getName() + ": " + ordinalValue.getValue()); - } - } - } - return propertySource.getOrdinal(); - } - - /** - * Overrides/adds the key to evaluate/override a property sources ordinal. - * @param ordinalKey sets the alternative ordinal key, if null default - * behaviour will be active. - * @return the instance for chaining. - */ - public PropertySourceComparator setOrdinalKey(String ordinalKey) { - this.alternativeOrdinalKey = ordinalKey; - return this; - } - - @Override - public int compare(PropertySource source1, PropertySource source2) { - return comparePropertySources(source1, source2); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/spi-support/src/main/java/org/apache/tamaya/spisupport/ReflectionUtil.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/ReflectionUtil.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/ReflectionUtil.java deleted file mode 100644 index 390c8d8..0000000 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/ReflectionUtil.java +++ /dev/null @@ -1,42 +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.spisupport; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; - - -/** - * Small utility class used by other parts. - */ -public final class ReflectionUtil { - - private ReflectionUtil(){} - - public static ParameterizedType getParametrizedType(Class<?> clazz) { - Type[] genericTypes = clazz.getGenericInterfaces(); - for (Type type : genericTypes) { - if (type instanceof ParameterizedType) { - return (ParameterizedType) type; - } - - } - return null; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/spi-support/src/main/java/org/apache/tamaya/spisupport/RegexPropertyFilter.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/RegexPropertyFilter.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/RegexPropertyFilter.java deleted file mode 100644 index 1f8cce9..0000000 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/RegexPropertyFilter.java +++ /dev/null @@ -1,84 +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.spisupport; - -import org.apache.tamaya.spi.FilterContext; -import org.apache.tamaya.spi.PropertyFilter; -import org.apache.tamaya.spi.PropertyValue; - -import java.util.Arrays; -import java.util.List; - -/** - * Predicate filtering using a regex expression operating on the key. It allows either - * to define the target keys to be selected (includes), or to be excluded (excludes). - */ -public final class RegexPropertyFilter implements PropertyFilter{ - /** The expression used to include entries that match. */ - private List<String> includes; - /** The expression used to exclude entries that match. */ - private List<String> excludes; - - /** - * Sets the regex expression to be applied on the key to filter the corresponding entry - * if matching. - * @param expressions the regular expression for inclusion, not null. - */ - public void setIncludes(String... expressions){ - this.includes = Arrays.asList(expressions); - } - - /** - * Sets the regex expression to be applied on the key to remove the corresponding entries - * if matching. - * @param expressions the regular expressions for exclusion, not null. - */ - public void setExcludes(String... expressions){ - this.excludes= Arrays.asList(expressions); - } - - @Override - public PropertyValue filterProperty(PropertyValue valueToBeFiltered, FilterContext context) { - if(includes!=null){ - for(String expression:includes){ - if(context.getProperty().getKey().matches(expression)){ - return valueToBeFiltered; - } - } - return null; - } - if(excludes!=null){ - for(String expression:excludes){ - if(context.getProperty().getKey().matches(expression)){ - return null; - } - } - } - return valueToBeFiltered; - } - - @Override - public String toString() { - return "RegexPropertyFilter{" + - "includes='" + includes + '\'' + - "excludes='" + excludes + '\'' + - '}'; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java deleted file mode 100644 index 54481ac..0000000 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java +++ /dev/null @@ -1,173 +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.spisupport.propertysource; - -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertyValue; -import org.apache.tamaya.spi.PropertyValueBuilder; - -import java.util.Map; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Abstract {@link org.apache.tamaya.spi.PropertySource} that allows to set a default ordinal that will be used, if no - * ordinal is provided with the config. - */ -public abstract class BasePropertySource implements PropertySource{ - /** default ordinal that will be used, if no ordinal is provided with the config. */ - private int defaultOrdinal; - /** Used if the ordinal has been set explicitly. */ - private volatile Integer ordinal; - /** The name of the property source. */ - private String name; - - /** - * Constructor. - * @param name the (unique) property source name, not {@code null}. - */ - protected BasePropertySource(String name){ - this.name = Objects.requireNonNull(name); - this.defaultOrdinal = 0; - } - - /** - * Constructor. - * @param defaultOrdinal default ordinal that will be used, if no ordinal is provided with the config. - */ - protected BasePropertySource(int defaultOrdinal){ - this.name = getClass().getSimpleName(); - this.defaultOrdinal = defaultOrdinal; - } - - /** - * Constructor. - * @param name the (unique) property source name, not {@code null}. - * @param defaultOrdinal default ordinal that will be used, if no ordinal is provided with the config. - */ - protected BasePropertySource(String name, int defaultOrdinal){ - this.name = Objects.requireNonNull(name); - this.defaultOrdinal = defaultOrdinal; - } - - - /** - * Constructor, using a default ordinal of 0. - */ - protected BasePropertySource(){ - this(0); - } - - @Override - public String getName() { - return name; - } - - /** - * Sets the property source's (unique) name. - * @param name the name, not {@code null}. - */ - public void setName(String name){ - this.name = Objects.requireNonNull(name); - } - - /** - * Allows to set the ordinal of this property source explcitly. This will override any evaluated - * ordinal, or default ordinal. To reset an explcit ordinal call {@code setOrdinal(null);}. - * @param ordinal the explicit ordinal, or {@code null}. - */ - public void setOrdinal(Integer ordinal){ - this.ordinal = ordinal; - } - - /** - * Allows to set the ordinal of this property source explcitly. This will override any evaluated - * ordinal, or default ordinal. To reset an explcit ordinal call {@code setOrdinal(null);}. - * @param defaultOrdinal the default ordinal, or {@code null}. - */ - public void setDefaultOrdinal(Integer defaultOrdinal){ - this.defaultOrdinal = defaultOrdinal; - } - - public int getOrdinal() { - Integer ordinal = this.ordinal; - if(ordinal!=null){ - Logger.getLogger(getClass().getName()).finest( - "Using explicit ordinal '"+ordinal+"' for property source: " + getName()); - return ordinal; - } - PropertyValue configuredOrdinal = get(TAMAYA_ORDINAL); - if(configuredOrdinal!=null){ - try { - return Integer.parseInt(configuredOrdinal.getValue()); - } catch (Exception e) { - Logger.getLogger(getClass().getName()).log(Level.WARNING, - "Configured ordinal is not an int number: " + configuredOrdinal, e); - } - } - return getDefaultOrdinal(); - } - - /** - * Returns the default ordinal used, when no ordinal is set, or the ordinal was not parseable to an int value. - * @return the default ordinal used, by default 0. - */ - public int getDefaultOrdinal(){ - return defaultOrdinal; - } - - @Override - public PropertyValue get(String key) { - Map<String,PropertyValue> properties = getProperties(); - PropertyValue val = properties.get(key); - if(val==null){ - return null; - } - return val; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - BasePropertySource that = (BasePropertySource) o; - - return name.equals(that.name); - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public String toString() { - return getClass().getSimpleName() + "{" + - toStringValues() + - '}'; - } - - protected String toStringValues() { - return " defaultOrdinal=" + defaultOrdinal + '\n' + - " ordinal=" + ordinal + '\n' + - " name='" + name + '\'' + '\n'; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java deleted file mode 100644 index fbea188..0000000 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java +++ /dev/null @@ -1,231 +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.spisupport.propertysource; - -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertyValue; - -import java.util.*; - -/** - * A Buildable property source. - */ -public class BuildablePropertySource implements PropertySource{ - - private int ordinal; - private String name = "PropertySource-"+UUID.randomUUID().toString(); - private Map<String,PropertyValue> properties = new HashMap<>(); - - @Override - public int getOrdinal() { - return ordinal; - } - - @Override - public String getName() { - return name; - } - - @Override - public PropertyValue get(String key) { - return properties.get(key); - } - - @Override - public Map<String, PropertyValue> getProperties() { - return Collections.unmodifiableMap(properties); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - BuildablePropertySource that = (BuildablePropertySource) o; - - return name.equals(that.name); - } - - @Override - public boolean isScannable() { - return true; - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public String toString() { - return "BuildablePropertySource{" + - "ordinal=" + ordinal + - ", name='" + name + '\'' + - ", properties=" + properties + - '}'; - } - - /** - * Builder builder. - * - * @return the builder - */ - public static Builder builder() { - return new Builder(); - } - - - /** - * The type Builder. - */ - public static final class Builder { - private int ordinal; - private String source = "<on-the-fly-build>"; - private String name = "PropertySource-"+ UUID.randomUUID().toString(); - private Map<String,PropertyValue> properties = new HashMap<>(); - - private Builder() { - } - - /** - * With ordinal builder. - * - * @param ordinal the ordinal - * @return the builder - */ - public Builder withOrdinal(int ordinal) { - this.ordinal = ordinal; - return this; - } - - /** - * With source builder. - * - * @param source the source - * @return the builder - */ - public Builder withSource(String source) { - this.source = Objects.requireNonNull(source); - return this; - } - - /** - * With name builder. - * - * @param name the name - * @return the builder - */ - public Builder withName(String name) { - this.name = Objects.requireNonNull(name); - return this; - } - - /** - * With simple property builder. - * - * @param key the key - * @param value the value - * @return the builder - */ - public Builder withSimpleProperty(String key, String value) { - return withProperties(PropertyValue.of(key, value, this.source)); - } - - /** - * With simple property builder. - * - * @param key the key - * @param value the value - * @param source the source - * @return the builder - */ - public Builder withSimpleProperty(String key, String value, String source) { - return withProperties(PropertyValue.of(key, value, source)); - } - - /** - * With properties builder. - * - * @param values the values - * @return the builder - */ - public Builder withProperties(PropertyValue... values) { - for(PropertyValue val:values){ - this.properties.put(val.getKey(), val); - } - return this; - } - - /** - * With properties builder. - * - * @param properties the properties - * @return the builder - */ - public Builder withProperties(Map<String, PropertyValue> properties) { - this.properties = Objects.requireNonNull(properties); - return this; - } - - /** - * With properties builder. - * - * @param properties the properties - * @param source the source - * @return the builder - */ - public Builder withProperties(Map<String, String> properties, String source) { - this.properties.putAll(PropertyValue.map(properties, source)); - return this; - } - - /** - * With simple properties builder. - * - * @param properties the properties - * @return the builder - */ - public Builder withSimpleProperties(Map<String, String> properties) { - this.properties.putAll(PropertyValue.map(properties, this.source)); - return this; - } - - /** - * But builder. - * - * @return the builder - */ - public Builder but() { - return builder().withOrdinal(ordinal).withName(name).withProperties(properties); - } - - /** - * Build buildable property source. - * - * @return the buildable property source - */ - public BuildablePropertySource build() { - BuildablePropertySource buildablePropertySource = new BuildablePropertySource(); - buildablePropertySource.name = this.name; - buildablePropertySource.properties = this.properties; - buildablePropertySource.ordinal = this.ordinal; - return buildablePropertySource; - } - } -}