You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by pl...@apache.org on 2016/09/25 21:35:41 UTC
[01/23] incubator-tamaya-sandbox git commit: TAMAYA 111: Add
Classloader aware ServiceContext.
Repository: incubator-tamaya-sandbox
Updated Branches:
refs/heads/master 7acfa8070 -> 30633b6e6
TAMAYA 111: Add Classloader aware ServiceContext.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/9c922df1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/9c922df1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/9c922df1
Branch: refs/heads/master
Commit: 9c922df1e01f232848ede24e5cb448a9b3297f94
Parents:
Author: anatole <an...@apache.org>
Authored: Fri Sep 25 20:23:06 2015 +0200
Committer: anatole <an...@apache.org>
Committed: Fri Sep 25 20:23:06 2015 +0200
----------------------------------------------------------------------
pom.xml | 53 +++
.../AbstractClassloaderAwareItemLoader.java | 267 ++++++++++++
.../internal/CLAwareConfigurationContext.java | 106 +++++
.../internal/CLAwareServiceContext.java | 224 ++++++++++
.../clsupport/internal/ServiceContainer.java | 311 +++++++++++++
.../ctx/DefaultConfigurationContext.java | 256 +++++++++++
.../clsupport/internal/ctx/EnumConverter.java | 67 +++
.../internal/ctx/PropertyConverterManager.java | 434 +++++++++++++++++++
.../tamaya/clsupport/internal/package-info.java | 22 +
.../apache/tamaya/clsupport/package-info.java | 22 +
.../tamaya/clsupport/spi/package-info.java | 22 +
.../org.apache.tamaya.spi.ServiceContext | 19 +
...he.tamaya.environment.spi.ContextProviderSpi | 23 +
...org.apache.tamaya.environment.spi.ContextSpi | 19 +
14 files changed, 1845 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..4aef40b
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,53 @@
+<!--
+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 current 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-extensions</artifactId>
+ <version>0.2-incubating-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <artifactId>tamaya-classloader-support</artifactId>
+ <name>Apache Tamaya Modules -Classloader Support</name>
+ <description>Apache Tamaya Classloader Support registers a ConfigurationContext that leverages
+ classloader hierarchies. Also visibility of features and components is aligned with the
+ corresponding hierarchy of classloaders.</description>
+ <packaging>jar</packaging>
+
+ <properties>
+ <jdkVersion>1.7</jdkVersion>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-java7-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java b/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
new file mode 100644
index 0000000..0c90653
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
@@ -0,0 +1,267 @@
+/*
+ * 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.clsupport;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * This class implements an abstract base class, which basically provides a loading mechanism that supports
+ * loading and managing resources along the classloader hierarchies individually. It ensures resources are loaded
+ * and stored related to the each target classloader within the hierarchy individually. Additionally it enables
+ * mechanisms to ensure an item T is not loaded multiple times, when traversing up the classloader hierarchy.<p/>
+ * Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected.
+ * Instead this class uses the fully qualified class name of the loader and the corresponsing hashCode as returned
+ * by {@link Objects#hashCode(Object)}.
+ * @param <T> the managed item type.
+ */
+public abstract class AbstractClassloaderAwareItemLoader<T> {
+ /**
+ * The logger used.
+ */
+ private static final Logger LOG = Logger.getLogger(AbstractClassloaderAwareItemLoader.class.getName());
+ /**
+ * The items managed, related to their classloader.
+ */
+ private Map<String, T> items = new ConcurrentHashMap<>();
+
+ /**
+ * Creates a new instance, using the current Thread context classloader, or - if null - the classloader that
+ * loaded this class for initially initializing the loader instance.
+ */
+ public AbstractClassloaderAwareItemLoader() {
+ this(getDefaultClassLoader());
+ }
+
+ /**
+ * Creates a new instance, using the class loader given for initializing the resources loaded.
+ *
+ * @param classLoader the target top level classloader, not null.
+ */
+ public AbstractClassloaderAwareItemLoader(ClassLoader classLoader) {
+ loadItems(classLoader);
+ }
+
+ /**
+ * Loads the items for the given classloader and all its parent classloaders. This method will not update
+ * the items already found for any class loader involved.
+ *
+ * @param classLoader the target top level classloader, not null.
+ */
+ public void loadItems(ClassLoader classLoader) {
+ loadItems(classLoader, false);
+ }
+
+ /**
+ * Loads the items for the given classloader and all its parent classloaders.
+ *
+ * @param classLoader the target top level classloader, not null.
+ * @param update if set to true, resources not visible on former runs are added during this load.
+ */
+ public void loadItems(ClassLoader classLoader, boolean update) {
+ this.items.clear();
+ List<ClassLoader> cls = new ArrayList<>();
+ cls.add(classLoader);
+ ClassLoader cl = classLoader.getParent();
+ while (cl != null) {
+ cls.add(cl);
+ cl = cl.getParent();
+ }
+ // Start with the parent classloader and then go up...
+ for (int i = cls.size() - 1; i <= 0; i--) {
+ ClassLoader curCL = cls.get(i);
+ String clKey = getClassLoaderID(curCL);
+ T itemFound = items.get(clKey);
+ try {
+ if (itemFound != null) {
+ updateItem(itemFound, curCL);
+ } else {
+ items.put(clKey, createItem(curCL));
+ }
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE,
+ "Error loading from classloader: " + curCL, e);
+ }
+ }
+ }
+
+ /**
+ * Creates a new item for being stored linked with the given lassloader.
+ *
+ * @param classLoader the classloader, not null.
+ * @return
+ */
+ protected abstract T createItem(ClassLoader classLoader);
+
+ /**
+ * Creates a new item for being stored linked with the given lassloader.
+ *
+ * @param currentItemSet the current found ItemContainer instance to be updated.
+ * @param classLoader the classloader, not null.
+ * @return
+ */
+ protected abstract void updateItem(T currentItemSet, ClassLoader classLoader);
+
+ /**
+ * Evaluates a String key for identfying a classloader instance, based on the loader class and its hashCode.
+ * This prevents the storage of classloader references as keys and therefore enables classloaders not used anymore
+ * to be garbage collected.
+ *
+ * @param classLoader
+ * @return the unique key for the given classloader
+ */
+ public static String getClassLoaderID(ClassLoader classLoader) {
+ return classLoader.getClass().getName() + Objects.hash(classLoader);
+ }
+
+ /**
+ * Evaluates a String key for identfying a classloader instance, based on the loader class and its hashCode.
+ * This prevents the storage of classloader references as keys and therefore enables classloaders not used anymore
+ * to be garbage collected.
+ *
+ * @return the unique key for the current default classloader as returned by #getDefaultClassLoader.
+ */
+ public static String getClassLoaderID() {
+ return getClassLoaderID(getDefaultClassLoader());
+ }
+
+ /**
+ * Get all items valid for the current thread context class loader, or - if null - the classloader that loaded
+ * this class.
+ *
+ * @return the items found, never null.
+ */
+ public Set<T> getItems() {
+ return getItems(getDefaultClassLoader());
+ }
+
+ /**
+ * Get all items found for the given classloader and all its parent classloaders.
+ *
+ * @param classLoader the target top level classloader, not null.
+ * @return the items found, never null.
+ */
+ public Set<T> getItems(ClassLoader classLoader) {
+ Set<T> result = new HashSet<>();
+ ClassLoader cl = classLoader;
+ while (cl != null) {
+ T item = getItemNoParent(cl, true);
+ result.add(item);
+ cl = cl.getParent();
+ }
+ return result;
+ }
+
+ /**
+ * Get all items valid for the parent class loader of the current thread context class loader, or - if null - the
+ * parent of the classloader that loaded this class. This allows
+ * to build a delta list of instances only visible on the target classloader given.
+ *
+ * @return the items found, never null.
+ */
+ public Set<T> getParentItems() {
+ return getParentItems(getDefaultClassLoader());
+ }
+
+ /**
+ * Get all items found for the parent of the given classloader and all its parent classloaders. This allows
+ * to build a delta list of instances only visible on the target classloader given.
+ *
+ * @param classLoader the target top level classloader, not null.
+ * @return the items found, never null.
+ */
+ public Set<T> getParentItems(ClassLoader classLoader) {
+ Set<T> result = new HashSet<>();
+ ClassLoader cl = classLoader.getParent();
+ while (cl != null) {
+ T item = getItemNoParent(cl, true);
+ result.add(item);
+ cl = cl.getParent();
+ }
+ return result;
+ }
+
+ /**
+ * Return the item assigned to the current thread context class loader or - if null - the class that loaded
+ * this class. If not yet loaded this method will NOT trigger a load.
+ *
+ * @return the item attached, or null.
+ */
+ public T getItemNoParent() {
+ return getItemNoParent(getDefaultClassLoader(), false);
+ }
+
+ /**
+ * Return the item assigned to the current thread context class loader or - if null - the class that loaded
+ * this class.
+ *
+ * @param loadIfMissing Flag that allows to define if this method will trigger an item load, when no item is loaded
+ * for the current class loader.
+ * @return the item attached, or null.
+ */
+ public T getItemNoParent(boolean loadIfMissing) {
+ return getItemNoParent(getDefaultClassLoader(), loadIfMissing);
+ }
+
+ /**
+ * Return the item assigned to the current thread context class loader or - if null - the class that loaded
+ * this class.
+ *
+ * @param classLoader the target top level classloader, not null.
+ * @param loadIfMissing Flag that allows to define if this method will trigger an item load, when no item is loaded
+ * for the current class loader.
+ * @return the item attached, or null. If {@code loadIfMissing} is set to true, the result is normally not to be
+ * expected to be null.
+ */
+ public T getItemNoParent(ClassLoader classLoader, boolean loadIfMissing) {
+ String clKey = getClassLoaderID(classLoader);
+ T item = items.get(clKey);
+ if (item == null) {
+ if (loadIfMissing) {
+ item = createItem(classLoader);
+ this.items.put(clKey, item);
+ }
+ }
+ return item;
+ }
+
+
+ /**
+ * Utility method that either returns the current thread context classloader or
+ * - if not available - the classloader that loaded this class.
+ * @return the default classloader to be used, if no explicit classloader has been passed.
+ */
+ public static ClassLoader getDefaultClassLoader() {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if (cl == null) {
+ cl = AbstractClassloaderAwareItemLoader.class.getClassLoader();
+ }
+ return cl;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareConfigurationContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareConfigurationContext.java b/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareConfigurationContext.java
new file mode 100644
index 0000000..8575393
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareConfigurationContext.java
@@ -0,0 +1,106 @@
+/*
+ * 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.clsupport.internal;
+
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.clsupport.AbstractClassloaderAwareItemLoader;
+import org.apache.tamaya.clsupport.internal.ctx.DefaultConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+
+import javax.annotation.Priority;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * Default Implementation of a simple ConfigurationContext.
+ */
+@Priority(100)
+public class CLAwareConfigurationContext implements ConfigurationContext {
+
+ /** The logger used. */
+ private final static Logger LOG = Logger.getLogger(CLAwareConfigurationContext.class.getName());
+
+ private ContextManager contextManager = new ContextManager();
+
+
+ @Override
+ public void addPropertySources(PropertySource... propertySourcesToAdd) {
+ contextManager.getItemNoParent(true).addPropertySources(propertySourcesToAdd);
+ }
+
+ @Override
+ public List<PropertySource> getPropertySources() {
+ return contextManager.getItemNoParent(true).getPropertySources();
+ }
+
+ @Override
+ public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+ contextManager.getItemNoParent(true).addPropertyConverter(typeToConvert, propertyConverter);
+ }
+
+ @Override
+ public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+ return contextManager.getItemNoParent(true).getPropertyConverters();
+ }
+
+ @Override
+ public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+ return contextManager.getItemNoParent(true).getPropertyConverters(targetType);
+ }
+
+ @Override
+ public List<PropertyFilter> getPropertyFilters() {
+ return contextManager.getItemNoParent(true).getPropertyFilters();
+ }
+
+ @Override
+ public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(){
+ return contextManager.getItemNoParent(true).getPropertyValueCombinationPolicy();
+ }
+
+ @Override
+ public ConfigurationContextBuilder toBuilder() {
+ return contextManager.getItemNoParent(true).toBuilder();
+ }
+
+
+ /**
+ * Subcomponent managing {@link ConfigurationContext} instances, one per classloader.
+ */
+ private static final class ContextManager extends AbstractClassloaderAwareItemLoader<ConfigurationContext>{
+
+ @Override
+ protected ConfigurationContext createItem(ClassLoader classLoader) {
+ // Simply create a complete configuration manager for every classloader. Maybe we will optimize this at a
+ // later stage in the project but as for now it is the most simple working solution.
+ return new DefaultConfigurationContext();
+ }
+
+ @Override
+ protected void updateItem(ConfigurationContext currentItemSet, ClassLoader classLoader) {
+ // ignore, currently not supported.
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java b/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
new file mode 100644
index 0000000..c023cff
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
@@ -0,0 +1,224 @@
+/*
+ * 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.clsupport.internal;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.clsupport.AbstractClassloaderAwareItemLoader;
+import org.apache.tamaya.spi.ServiceContext;
+
+import javax.annotation.Priority;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+
+/**
+ * This class implements a {@link ServiceContext}, which basically provides a similar loading mechanism as used
+ * by the {@link java.util.ServiceLoader}. Whereas the {@link java.util.ServiceLoader} only loads configurations
+ * and instances from one classloader, this loader manages configs found and the related instances for each
+ * classloader along the classloader hierarchies individually. It ensures instances are loaded on the classloader
+ * level, where they first are visible. Additionally it ensures the same configuration resource (and its
+ * declared services) are loaded multiple times, when going up the classloader hierarchy.<p/>
+ * Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected.
+ * Refer also the inherited parent class for further details.<p/>
+ * This class uses an ordinal of {@code 10}, so it overrides any default {@link ServiceContext} implementations
+ * provided with the Tamaya core modules.
+ */
+@Priority(10)
+public class CLAwareServiceContext extends AbstractClassloaderAwareItemLoader<ServiceContainer>
+ implements ServiceContext{
+ /**
+ * Default location for service loader files.
+ */
+ private static final String PREFIX = "META-INF/services/";
+
+ /**
+ * Constructor, using the current default classloader as defined by
+ * {@link AbstractClassloaderAwareItemLoader#getDefaultClassLoader()}.
+ */
+ public CLAwareServiceContext(){
+ super();
+ }
+
+ /**
+ * Constructor, using the given classloader.
+ * @param classLoader the target classloader for initializing of services, not null.
+ */
+ public CLAwareServiceContext(ClassLoader classLoader) {
+ super(classLoader);
+ }
+
+
+ /**
+ * Implementation that creates a {@link ServiceContainer}, which manages all configs and instances loaded
+ * for a given classloader.
+ * @param classLoader the classloader, not null.
+ * @return a new empty, {@link ServiceContainer} instance.
+ */
+ @Override
+ protected ServiceContainer createItem(ClassLoader classLoader) {
+ return new ServiceContainer(classLoader);
+ }
+
+ @Override
+ protected void updateItem(ServiceContainer currentContainer, ClassLoader classLoader) {
+ // nothing to be done here, since we dont have a specific target type.
+ }
+
+ @Override
+ public int ordinal() {
+ return 10;
+ }
+
+ /**
+ * This method tries to evaluate the current singleton from the {@link ServiceContainer} attached to the
+ * current classloader. If not found the singleton instance is evaluated based on the priorities
+ * assigned for all known providers. The resulting instance is then cached and always returned as
+ * singleton instance fomr this loader, when the same current classloader instance is active.
+ * @param serviceType the service type.
+ * @param <T> the type
+ * @return the item found, or null.
+ */
+ @Override
+ public <T> T getService(Class<T> serviceType) {
+ return getService(serviceType, getDefaultClassLoader());
+ }
+
+ /**
+ * Evaluates the current singleton instance using the given classloader context.
+ * @param serviceType the service type.
+ * @param classLoader the classloader, not null.
+ * @param <T> the type
+ * @return the item found, or null.
+ */
+ public <T> T getService(Class<T> serviceType, ClassLoader classLoader) {
+ ServiceContainer container = getItemNoParent(classLoader, true);
+ T singleton = container.getSingleton(serviceType);
+ if(singleton!=null){
+ return singleton;
+ }
+ Collection<? extends T> services = getServices(serviceType, classLoader);
+ if (services.isEmpty()) {
+ singleton = null;
+ } else {
+ singleton = getServiceWithHighestPriority(services, serviceType);
+ }
+ if(singleton!=null) {
+ container.setSingleton(serviceType, singleton);
+ }
+ return singleton;
+ }
+
+ /**
+ * Gets the services visible.
+ * @param serviceType
+ * the service type.
+ * @param <T> the type param
+ * @return the services visible for the current classloader.
+ */
+ @Override
+ public <T> List<T> getServices(Class<T> serviceType) {
+ return getServices(serviceType, AbstractClassloaderAwareItemLoader.getDefaultClassLoader());
+ }
+
+ /**
+ * Gets the services visible.
+ * @param serviceType the service type.
+ * @param classLoader the classloader
+ * @param <T> the type param
+ * @return the services visible for the current classloader.
+ */
+ public <T> List<T> getServices(Class<T> serviceType, ClassLoader classLoader) {
+ List<T> services = new ArrayList<>();
+ ClassLoader cl = classLoader;
+ List<ServiceContainer> containers = new ArrayList<>();
+ while(cl!=null) {
+ ServiceContainer container = getItemNoParent(cl, true);
+ containers.add(container);
+ cl = cl.getParent();
+ }
+ List<ServiceContainer> prevContainers = new ArrayList<>();
+ Collections.reverse(containers);
+ for(ServiceContainer container: containers) {
+ if (!container.isTypeLoaded(serviceType)) {
+ container.loadServices(serviceType, prevContainers);
+ }
+ services.addAll(container.getServices(serviceType));
+ prevContainers.add(container);
+ }
+ return services;
+ }
+
+ /**
+ * @param services to scan
+ * @param <T> type of the service
+ *
+ * @return the service with the highest {@link javax.annotation.Priority#value()}
+ *
+ * @throws ConfigException if there are multiple service implementations with the maximum priority
+ */
+ private <T> T getServiceWithHighestPriority(Collection<? extends T> services, Class<T> serviceType) {
+
+ // we do not need the priority stuff if the list contains only one element
+ if (services.size() == 1) {
+ return services.iterator().next();
+ }
+
+ Integer highestPriority = null;
+ int highestPriorityServiceCount = 0;
+ T highestService = null;
+
+ 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));
+ }
+ return highestService;
+ }
+
+ /**
+ * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
+ * annotation is present, a default priority is returned (1);
+ * @param o the instance, not null.
+ * @return a priority, by default 1.
+ */
+ public static int getPriority(Object o){
+ int prio = 0;
+ Priority priority = o.getClass().getAnnotation(Priority.class);
+ if (priority != null) {
+ prio = priority.value();
+ }
+ return prio;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/ServiceContainer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/ServiceContainer.java b/src/main/java/org/apache/tamaya/clsupport/internal/ServiceContainer.java
new file mode 100644
index 0000000..713b292
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/ServiceContainer.java
@@ -0,0 +1,311 @@
+/*
+ * 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.clsupport.internal;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceConfigurationError;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Created by Anatole on 08.09.2015.
+ */
+class ServiceContainer {
+
+ private static final Logger LOG = Logger.getLogger(ServiceContainer.class.getName());
+
+ private static final String PREFIX = "META-INF/services/";
+
+ // The access control context taken when the ServiceLoader is created
+ private final AccessControlContext acc;
+
+ private WeakReference<ClassLoader> classLoaderRef;
+
+ /**
+ * List current services loaded using this classloader, per class.
+ */
+ private final Map<Class<?>, Map<String, Object>> servicesLoaded = new ConcurrentHashMap<>();
+ /**
+ * The cached singletons for the given classloader.
+ */
+ private final Map<Class, Object> singletons = new ConcurrentHashMap<>();
+
+ /**
+ * List current services loaded using this classloader, per class.
+ */
+ private final Map<Class, List<URL>> configsLoaded = new ConcurrentHashMap<>();
+
+ ServiceContainer(ClassLoader classLoader) {
+ acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;
+ this.classLoaderRef = new WeakReference<>(classLoader);
+ }
+
+ public ClassLoader getClassLoader() {
+ ClassLoader cl = classLoaderRef.get();
+ if (cl == null) {
+ throw new IllegalStateException("Classloader reference removed, not active anynire.");
+ }
+ return cl;
+ }
+
+
+ public <T> void loadServices(Class<?> type,
+ Collection<ServiceContainer> preceedingContainers) {
+ Map<String, Object> services = (Map<String, Object>) this.servicesLoaded.get(type);
+ if (services == null) {
+ services = new LinkedHashMap<>();
+ this.servicesLoaded.put(type, services);
+ }
+ loop:
+ for (URL config : getConfigs(type)) {
+ for (ServiceContainer cont : preceedingContainers) {
+ if (cont.getConfigs(type).contains(config)) {
+ LOG.finer("Ignoring already loaded config: " + config);
+ continue loop;
+ }
+ }
+ Collection<String> serviceNames = parse(type, config);
+ for (String s : serviceNames) {
+ for (ServiceContainer cont : preceedingContainers) {
+ if (cont.containsService(type, s)) {
+ LOG.finest("Ignoring duplicate service: " + s);
+ continue;
+ }
+ }
+ LOG.info("Loading component: " + s);
+ services.put(s, create(type, s));
+ }
+ }
+ }
+
+ private Collection<URL> getConfigs(Class<?> type) {
+ List<URL> result = this.configsLoaded.get(type);
+ if (result == null) {
+ ClassLoader cl = this.classLoaderRef.get();
+ if (cl == null) {
+ throw new IllegalStateException("CLassLoader dereferenced already.");
+ }
+ result = new ArrayList<>();
+ try {
+ Enumeration<URL> resources = cl.getResources(PREFIX + type.getName());
+ while (resources.hasMoreElements()) {
+ result.add(resources.nextElement());
+ }
+ } catch (Exception e) {
+ LOG.log(Level.WARNING, "Failed to read service config for " + type.getName() + " from " + cl, e);
+ }
+ this.configsLoaded.put(type, result);
+ LOG.log(Level.FINE, "Found service config for " + type.getName() + ": " + result);
+ }
+ return result;
+ }
+
+ private boolean containsService(Class<?> type, String serviceClassName) {
+ Map<String, Object> services = servicesLoaded.get(type);
+ if (services == null) {
+ return false;
+ }
+ return services.containsKey(serviceClassName);
+ }
+
+
+ private <S> S create(Class<S> serviceType, String className) {
+ Class<?> c = null;
+ ClassLoader classLoader = getClassLoader();
+ try {
+ c = Class.forName(className, false, classLoader);
+ } catch (ClassNotFoundException x) {
+ fail(serviceType,
+ "Provider " + className + " not found");
+ }
+ if (!serviceType.isAssignableFrom(c)) {
+ fail(serviceType,
+ "Provider " + className + " not a subtype");
+ }
+ try {
+ S p = serviceType.cast(c.newInstance());
+ return p;
+ } catch (Throwable x) {
+ fail(serviceType,
+ "Provider " + className + " could not be instantiated",
+ x);
+ }
+ throw new Error(); // This cannot happen
+ }
+
+ public <T> Collection<T> getServices(Class<T> serviceType) {
+ Map<String, Object> services = this.servicesLoaded.get(serviceType);
+ if (services != null) {
+ return (Collection<T>) services.values();
+ }
+ return Collections.emptySet();
+ }
+
+ public boolean isTypeLoaded(Class<?> serviceType) {
+ return this.servicesLoaded.containsKey(serviceType);
+ }
+
+ public Collection<URL> load(Class<?> serviceType) {
+ return load(serviceType, Collection.class.cast(Collections.emptySet()));
+ }
+
+ public Collection<URL> load(Class<?> serviceType, Collection<URL> configsLoaded) {
+ List<URL> result = new ArrayList<>();
+ try {
+ Enumeration<URL> resources = getClassLoader().getResources(PREFIX + serviceType.getName());
+ while (resources.hasMoreElements()) {
+ URL res = resources.nextElement();
+ if (!configsLoaded.contains(res)) {
+ result.add(res);
+ }
+ }
+ return result;
+ } catch (Exception e) {
+ fail(serviceType, "Failed to load service config: " + PREFIX + serviceType.getName(), e);
+ }
+ return result;
+ }
+
+
+ // Parse a single line from the given configuration file, adding the name
+ // on the line to the names list.
+ //
+ private int parseLine(Class<?> serviceType, URL u, BufferedReader r, int lc,
+ List<String> names)
+ throws IOException, ServiceConfigurationError {
+ String ln = r.readLine();
+ if (ln == null) {
+ return -1;
+ }
+ int ci = ln.indexOf('#');
+ if (ci >= 0) {
+ ln = ln.substring(0, ci);
+ }
+ ln = ln.trim();
+ int n = ln.length();
+ if (n != 0) {
+ if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) {
+ fail(serviceType, u, lc, "Illegal configuration-file syntax");
+ }
+ int cp = ln.codePointAt(0);
+ if (!Character.isJavaIdentifierStart(cp)) {
+ fail(serviceType, u, lc, "Illegal provider-class name: " + ln);
+ }
+ for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
+ cp = ln.codePointAt(i);
+ if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) {
+ fail(serviceType, u, lc, "Illegal provider-class name: " + ln);
+ }
+ }
+ Map<String, Object> services = this.servicesLoaded.get(serviceType);
+ if (services == null || !services.containsKey(ln) && !names.contains(ln)) {
+ names.add(ln);
+ }
+ }
+ return lc + 1;
+ }
+
+
+ // Parse the content of the given URL as a provider-configuration file.
+ //
+ // @param service
+ // The service type for which providers are being sought;
+ // used to construct error detail strings
+ //
+ // @param u
+ // The URL naming the configuration file to be parsed
+ //
+ // @return A (possibly empty) iterator that will yield the provider-class
+ // names in the given configuration file that are not yet members
+ // of the returned set
+ //
+ // @throws ServiceConfigurationError
+ // If an I/O error occurs while reading from the given URL, or
+ // if a configuration-file format error is detected
+ //
+ private Collection<String> parse(Class<?> service, URL u)
+ throws ServiceConfigurationError {
+ InputStream in = null;
+ BufferedReader r = null;
+ ArrayList<String> names = new ArrayList<>();
+ try {
+ in = u.openStream();
+ r = new BufferedReader(new InputStreamReader(in, "utf-8"));
+ int lc = 1;
+ while ((lc = parseLine(service, u, r, lc, names)) >= 0) {
+ // go ahead
+ }
+ } catch (IOException x) {
+ fail(service, "Error reading configuration file", x);
+ } finally {
+ try {
+ if (r != null) {
+ r.close();
+ }
+ if (in != null) {
+ in.close();
+ }
+ } catch (IOException y) {
+ fail(service, "Error closing configuration file", y);
+ }
+ }
+ return names;
+ }
+
+
+ private static void fail(Class<?> service, String msg, Throwable cause)
+ throws ServiceConfigurationError {
+ LOG.log(Level.SEVERE, "Failed to load: " + service.getName() + ": " + msg, cause);
+ }
+
+ private static void fail(Class<?> service, String msg)
+ throws ServiceConfigurationError {
+ LOG.log(Level.SEVERE, "Failed to load: " + service.getName() + ": " + msg);
+ }
+
+ private static void fail(Class<?> service, URL u, int line, String msg)
+ throws ServiceConfigurationError {
+ fail(service, u + ":" + line + ": " + msg);
+ }
+
+ public <T> T getSingleton(Class<T> serviceType) {
+ return (T) this.singletons.get(serviceType);
+ }
+
+ <T> void setSingleton(Class<T> type, T instance) {
+ LOG.info("Caching singleton for " + type.getName() + " and classloader: " +
+ getClassLoader().toString() + ": " + instance);
+ this.singletons.put(type, instance);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/ctx/DefaultConfigurationContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/ctx/DefaultConfigurationContext.java b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/DefaultConfigurationContext.java
new file mode 100644
index 0000000..978dbb7
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/DefaultConfigurationContext.java
@@ -0,0 +1,256 @@
+/*
+ * 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.clsupport.internal.ctx;
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.annotation.Priority;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Logger;
+
+/**
+ * Default Implementation of a simple ConfigurationContext.
+ */
+public class DefaultConfigurationContext implements ConfigurationContext {
+ /** The logger used. */
+ private final static Logger LOG = Logger.getLogger(DefaultConfigurationContext.class.getName());
+ /**
+ * Cubcomponent handling {@link PropertyConverter} instances.
+ */
+ private PropertyConverterManager propertyConverterManager = new PropertyConverterManager();
+
+ /**
+ * The current unmodifiable list of loaded {@link PropertySource} instances.
+ */
+ private List<PropertySource> immutablePropertySources;
+
+ /**
+ * The current unmodifiable list of loaded {@link PropertyFilter} instances.
+ */
+ private List<PropertyFilter> immutablePropertyFilters;
+
+ /**
+ * The overriding policy used when combining PropertySources registered to evalute the final configuration
+ * values.
+ */
+ private PropertyValueCombinationPolicy propertyValueCombinationPolicy;
+
+ /**
+ * Lock for internal synchronization.
+ */
+ private final ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock();
+
+ /** Comparator used for ordering property sources. */
+ private final PropertySourceComparator propertySourceComparator = new PropertySourceComparator();
+
+ /** Comparator used for ordering property filters. */
+ private final PropertyFilterComparator propertyFilterComparator = new PropertyFilterComparator();
+
+
+ /**
+ * The first time the Configuration system gets invoked we do initialize
+ * all our {@link PropertySource}s and
+ * {@link PropertyFilter}s which are known at startup.
+ */
+ public DefaultConfigurationContext() {
+ List<PropertySource> propertySources = new ArrayList<>();
+
+ // first we load all PropertySources which got registered via java.util.ServiceLoader
+ propertySources.addAll(ServiceContextManager.getServiceContext().getServices(PropertySource.class));
+
+ // after that we add all PropertySources which get dynamically registered via their PropertySourceProviders
+ propertySources.addAll(evaluatePropertySourcesFromProviders());
+
+ // now sort them according to their ordinal values
+ Collections.sort(propertySources, new PropertySourceComparator());
+
+ immutablePropertySources = Collections.unmodifiableList(propertySources);
+ LOG.info("Registered " + immutablePropertySources.size() + " property sources: " +
+ immutablePropertySources);
+
+ // as next step we pick up the PropertyFilters pretty much the same way
+ List<PropertyFilter> propertyFilters = new ArrayList<>();
+ propertyFilters.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
+ Collections.sort(propertyFilters, new PropertyFilterComparator());
+ immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+ LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+ immutablePropertyFilters);
+
+ immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+ LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+ immutablePropertyFilters);
+ propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class);
+ if(propertyValueCombinationPolicy==null) {
+ propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+ }
+ LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
+ }
+
+ /**
+ * Pick up all {@link PropertySourceProvider}s and return all the
+ * {@link PropertySource}s they like to register.
+ */
+ private Collection<? extends PropertySource> evaluatePropertySourcesFromProviders() {
+ List<PropertySource> propertySources = new ArrayList<>();
+ Collection<PropertySourceProvider> propertySourceProviders = ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class);
+ for (PropertySourceProvider propertySourceProvider : propertySourceProviders) {
+ Collection<PropertySource> sources = propertySourceProvider.getPropertySources();
+ LOG.finer("PropertySourceProvider " + propertySourceProvider.getClass().getName() +
+ " provided the following property sources: " + sources);
+ propertySources.addAll(sources);
+ }
+
+ return propertySources;
+ }
+
+ @Override
+ public void addPropertySources(PropertySource... propertySourcesToAdd) {
+ Lock writeLock = propertySourceLock.writeLock();
+ try {
+ writeLock.lock();
+ List<PropertySource> newPropertySources = new ArrayList<>(this.immutablePropertySources);
+ newPropertySources.addAll(Arrays.asList(propertySourcesToAdd));
+ Collections.sort(newPropertySources, new PropertySourceComparator());
+
+ this.immutablePropertySources = Collections.unmodifiableList(newPropertySources);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Comparator used for comparing PropertySources.
+ */
+ private static class PropertySourceComparator implements Comparator<PropertySource>, Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Order property source reversely, the most important come first.
+ *
+ * @param source1 the first PropertySource
+ * @param source2 the second PropertySource
+ * @return the comparison result.
+ */
+ private int comparePropertySources(PropertySource source1, PropertySource source2) {
+ if (source1.getOrdinal() < source2.getOrdinal()) {
+ return -1;
+ } else if (source1.getOrdinal() > source2.getOrdinal()) {
+ return 1;
+ } else {
+ return source1.getClass().getName().compareTo(source2.getClass().getName());
+ }
+ }
+
+ @Override
+ public int compare(PropertySource source1, PropertySource source2) {
+ return comparePropertySources(source1, source2);
+ }
+ }
+
+ /**
+ * Comparator used for comparing PropertyFilters.
+ */
+ private static class PropertyFilterComparator implements Comparator<PropertyFilter>, Serializable{
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 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);
+ }
+ }
+
+ @Override
+ public List<PropertySource> getPropertySources() {
+ return immutablePropertySources;
+ }
+
+ @Override
+ public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+ propertyConverterManager.register(typeToConvert, propertyConverter);
+ LOG.info("Added PropertyConverter: " + propertyConverter.getClass().getName());
+ }
+
+ @Override
+ public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+ return propertyConverterManager.getPropertyConverters();
+ }
+
+ @Override
+ public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+ return propertyConverterManager.getPropertyConverters(targetType);
+ }
+
+ @Override
+ public List<PropertyFilter> getPropertyFilters() {
+ return immutablePropertyFilters;
+ }
+
+ @Override
+ public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(){
+ return propertyValueCombinationPolicy;
+ }
+
+ @Override
+ public ConfigurationContextBuilder toBuilder() {
+ return ConfigurationProvider.getConfigurationContextBuilder().setContext(this);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/ctx/EnumConverter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/ctx/EnumConverter.java b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/EnumConverter.java
new file mode 100644
index 0000000..a75de75
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/EnumConverter.java
@@ -0,0 +1,67 @@
+/*
+ * 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.clsupport.internal.ctx;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertyConverter;
+
+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.
+ * @param <T> the enum type.
+ */
+class EnumConverter<T> implements PropertyConverter<T> {
+ private 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) {
+ 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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/ctx/PropertyConverterManager.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/ctx/PropertyConverterManager.java b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/PropertyConverterManager.java
new file mode 100644
index 0000000..848fe78
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/PropertyConverterManager.java
@@ -0,0 +1,434 @@
+/*
+ * 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.clsupport.internal.ctx;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.annotation.Priority;
+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.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+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.Logger;
+
+/**
+ * Manager that deals with {@link PropertyConverter} instances.
+ * This class is thread-safe.
+ */
+class PropertyConverterManager {
+ /**
+ * The logger used.
+ */
+ private static final Logger LOG = Logger.getLogger(PropertyConverterManager.class.getName());
+ /**
+ * The registered converters.
+ */
+ private Map<TypeLiteral<?>, List<PropertyConverter<?>>> converters = new ConcurrentHashMap<>();
+ /**
+ * The transitive converters.
+ */
+ private Map<TypeLiteral<?>, List<PropertyConverter<?>>> transitiveConverters = new ConcurrentHashMap<>();
+ /**
+ * The lock used.
+ */
+ private ReadWriteLock lock = new ReentrantReadWriteLock();
+
+ private static final Comparator<Object> PRIORITY_COMPARATOR = new Comparator<Object>() {
+
+ @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 s evaluated. If no such
+ * annotation is present, a default priority is returned (1);
+ * @param o the instance, not null.
+ * @return a priority, by default 1.
+ */
+ public static int getPriority(Object o){
+ int prio = 1;
+ Priority priority = o.getClass().getAnnotation(Priority.class);
+ if (priority != null) {
+ prio = priority.value();
+ }
+ return prio;
+ }
+
+ /**
+ * Constructor.
+ */
+ public PropertyConverterManager() {
+ this(true);
+ }
+
+ public PropertyConverterManager(boolean init) {
+ if (init) {
+ initConverters();
+ }
+ }
+
+ /**
+ * Registers the default converters provided out of the box.
+ */
+ 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 ew converter instance.
+ *
+ * @param targetType the target type, not null.
+ * @param converter the converter, not null.
+ * @param <T> the type.
+ */
+ public <T> void register(TypeLiteral<T> targetType, PropertyConverter<T> converter) {
+ Objects.requireNonNull(converter);
+ Lock writeLock = lock.writeLock();
+ try {
+ writeLock.lock();
+ List converters = List.class.cast(this.converters.get(targetType));
+ List<PropertyConverter<?>> newConverters = new ArrayList<>();
+ if (converters != null) {
+ newConverters.addAll(converters);
+ }
+ 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 null.
+ * @return true, if a converter for the given type is registered, or a default one can be created.
+ */
+ public boolean isTargetTypeSupported(TypeLiteral<?> targetType) {
+ if (converters.containsKey(targetType) || transitiveConverters.containsKey(targetType)) {
+ return true;
+ }
+ return 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(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
+ * converter based on String costructor or static factory methods available.<br/>
+ * 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
+ * primarly for converting a value.</li>
+ * <li>The target type of each explicitly registered converter 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>
+ *
+ * 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 null.
+ * @param <T> the type class
+ * @return the ordered list of converters (may be empty for not convertible types).
+ * @see #createDefaultPropertyConverter(TypeLiteral)
+ */
+ public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+ Lock readLock = lock.readLock();
+ List<PropertyConverter<T>> converterList = new ArrayList<>();
+ List<PropertyConverter<T>> converters;
+ // direct mapped converters
+ try {
+ readLock.lock();
+ converters = List.class.cast(this.converters.get(targetType));
+ } finally {
+ readLock.unlock();
+ }
+ if (converters != null) {
+ converterList.addAll(converters);
+ }
+ // transitive converter
+ try {
+ readLock.lock();
+ converters = List.class.cast(this.transitiveConverters.get(targetType));
+ } finally {
+ readLock.unlock();
+ }
+ if (converters != null) {
+ converterList.addAll(converters);
+ }
+ // handling of java.lang wrapper classes
+ TypeLiteral<T> boxedType = mapBoxedType(targetType);
+ if (boxedType != null) {
+ try {
+ readLock.lock();
+ converters = List.class.cast(this.converters.get(boxedType));
+ } finally {
+ readLock.unlock();
+ }
+ if (converters != null) {
+ converterList.addAll(converters);
+ }
+ }
+ if (converterList.isEmpty()) {
+ // 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();
+ converters = List.class.cast(this.converters.get(targetType));
+ } finally {
+ readLock.unlock();
+ }
+ }
+ if (converters != null) {
+ converterList.addAll(converters);
+ }
+ }
+ return converterList;
+ }
+
+ /**
+ * Maps native types to the corresponding boxed types.
+ *
+ * @param targetType the native type.
+ * @param <T> the type
+ * @return the boxed type, or null.
+ */
+ 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 converter, or null.
+ */
+ protected <T> PropertyConverter<T> createDefaultPropertyConverter(final TypeLiteral<T> targetType) {
+ if (Enum.class.isAssignableFrom(targetType.getRawType())) {
+ return new EnumConverter<T>(targetType.getRawType());
+ }
+ PropertyConverter<T> converter = null;
+ final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "valueOf", "instanceOf", "getInstance", "from", "fromString", "parse");
+ if (factoryMethod != null) {
+ converter = new PropertyConverter<T>() {
+ @Override
+ public T convert(String value) {
+ try {
+ if (!Modifier.isStatic(factoryMethod.getModifiers())) {
+ throw new ConfigException(factoryMethod.toGenericString() +
+ " is not a static method. Only static " +
+ "methods can be used as factory methods.");
+ }
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ factoryMethod.setAccessible(true);
+ return null;
+ }
+ });
+ Object invoke = factoryMethod.invoke(null, value);
+ return targetType.getRawType().cast(invoke);
+ } catch (Exception e) {
+ throw new ConfigException("Failed to decode '" + value + "'", e);
+ }
+ }
+ };
+ }
+ if (converter == null) {
+ try {
+ final Constructor<T> constr = targetType.getRawType().getDeclaredConstructor(String.class);
+ converter = new PropertyConverter<T>() {
+ @Override
+ public T convert(String value) {
+ try {
+ constr.setAccessible(true);
+ return constr.newInstance(value);
+ } catch (Exception e) {
+ throw new ConfigException("Failed to decode '" + value + "'", e);
+ }
+ }
+ };
+ } catch (Exception e) {
+ LOG.finest("Failed to construct instance of type: " + targetType.getRawType().getName() + ": " + e);
+ }
+ }
+ 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;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/package-info.java b/src/main/java/org/apache/tamaya/clsupport/internal/package-info.java
new file mode 100644
index 0000000..3949b74
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+/**
+ * Contains the provided implementation classes for the classloader support module.
+ */
+package org.apache.tamaya.clsupport.internal;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/package-info.java b/src/main/java/org/apache/tamaya/clsupport/package-info.java
new file mode 100644
index 0000000..d8e3953
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+/**
+ * Programmatic API of the classloader support.
+ */
+package org.apache.tamaya.clsupport;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/spi/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/spi/package-info.java b/src/main/java/org/apache/tamaya/clsupport/spi/package-info.java
new file mode 100644
index 0000000..6eb85d3
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/spi/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+/**
+ * Defines the SPI of the classloader support module.
+ */
+package org.apache.tamaya.clsupport.spi;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
----------------------------------------------------------------------
diff --git a/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext b/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
new file mode 100644
index 0000000..c3b6acd
--- /dev/null
+++ b/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.clsupport.internal.CLAwareServiceContext
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi
----------------------------------------------------------------------
diff --git a/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi b/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi
new file mode 100644
index 0000000..7f71c15
--- /dev/null
+++ b/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi
@@ -0,0 +1,23 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.environment.internal.ClassLoaderDependentAppEnvironmentProvider
+org.apache.tamaya.environment.internal.ClassLoaderDependentEarEnvironmentProvider
+org.apache.tamaya.environment.internal.InitialEnvironmentProviderSpi
+org.apache.tamaya.environment.internal.SystemClassLoaderEnvironmentProviderSpi
+org.apache.tamaya.metamodel.environment.TestEnvironmentProvider
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi
----------------------------------------------------------------------
diff --git a/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi b/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi
new file mode 100644
index 0000000..166dd67
--- /dev/null
+++ b/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.environment.internal.SingleEnvironmentManager
[15/23] incubator-tamaya-sandbox git commit: [maven-release-plugin]
prepare for next development iteration
Posted by pl...@apache.org.
[maven-release-plugin] prepare for next development iteration
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/1f6177fc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/1f6177fc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/1f6177fc
Branch: refs/heads/master
Commit: 1f6177fc324b15bf94ad99fc48969f725eb0f624
Parents: c775209
Author: anatole <an...@apache.org>
Authored: Tue Mar 8 20:39:16 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Tue Mar 8 20:39:16 2016 +0100
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/1f6177fc/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 82bbd15..1d27df4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-extensions</artifactId>
- <version>0.2-incubating</version>
+ <version>0.3-incubating-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
[06/23] incubator-tamaya-sandbox git commit: TAMAYA-114: Added
additional implementations shared by modules.
Posted by pl...@apache.org.
TAMAYA-114: Added additional implementations shared by modules.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/e441ee72
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/e441ee72
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/e441ee72
Branch: refs/heads/master
Commit: e441ee726f3d08757d7620f8dbe809bb4aa96420
Parents: 32235c4
Author: anatole <an...@apache.org>
Authored: Fri Oct 16 19:32:46 2015 +0200
Committer: anatole <an...@apache.org>
Committed: Fri Oct 16 19:32:46 2015 +0200
----------------------------------------------------------------------
.../ctx/DefaultConfigurationContext.java | 256 -----------
.../clsupport/internal/ctx/EnumConverter.java | 67 ---
.../internal/ctx/PropertyConverterManager.java | 434 -------------------
3 files changed, 757 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e441ee72/src/main/java/org/apache/tamaya/clsupport/internal/ctx/DefaultConfigurationContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/ctx/DefaultConfigurationContext.java b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/DefaultConfigurationContext.java
deleted file mode 100644
index 978dbb7..0000000
--- a/src/main/java/org/apache/tamaya/clsupport/internal/ctx/DefaultConfigurationContext.java
+++ /dev/null
@@ -1,256 +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.clsupport.internal.ctx;
-
-import org.apache.tamaya.ConfigurationProvider;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.spi.ConfigurationContext;
-import org.apache.tamaya.spi.ConfigurationContextBuilder;
-import org.apache.tamaya.spi.PropertyConverter;
-import org.apache.tamaya.spi.PropertyFilter;
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertySourceProvider;
-import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
-import org.apache.tamaya.spi.ServiceContextManager;
-
-import javax.annotation.Priority;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.logging.Logger;
-
-/**
- * Default Implementation of a simple ConfigurationContext.
- */
-public class DefaultConfigurationContext implements ConfigurationContext {
- /** The logger used. */
- private final static Logger LOG = Logger.getLogger(DefaultConfigurationContext.class.getName());
- /**
- * Cubcomponent handling {@link PropertyConverter} instances.
- */
- private PropertyConverterManager propertyConverterManager = new PropertyConverterManager();
-
- /**
- * The current unmodifiable list of loaded {@link PropertySource} instances.
- */
- private List<PropertySource> immutablePropertySources;
-
- /**
- * The current unmodifiable list of loaded {@link PropertyFilter} instances.
- */
- private List<PropertyFilter> immutablePropertyFilters;
-
- /**
- * The overriding policy used when combining PropertySources registered to evalute the final configuration
- * values.
- */
- private PropertyValueCombinationPolicy propertyValueCombinationPolicy;
-
- /**
- * Lock for internal synchronization.
- */
- private final ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock();
-
- /** Comparator used for ordering property sources. */
- private final PropertySourceComparator propertySourceComparator = new PropertySourceComparator();
-
- /** Comparator used for ordering property filters. */
- private final PropertyFilterComparator propertyFilterComparator = new PropertyFilterComparator();
-
-
- /**
- * The first time the Configuration system gets invoked we do initialize
- * all our {@link PropertySource}s and
- * {@link PropertyFilter}s which are known at startup.
- */
- public DefaultConfigurationContext() {
- List<PropertySource> propertySources = new ArrayList<>();
-
- // first we load all PropertySources which got registered via java.util.ServiceLoader
- propertySources.addAll(ServiceContextManager.getServiceContext().getServices(PropertySource.class));
-
- // after that we add all PropertySources which get dynamically registered via their PropertySourceProviders
- propertySources.addAll(evaluatePropertySourcesFromProviders());
-
- // now sort them according to their ordinal values
- Collections.sort(propertySources, new PropertySourceComparator());
-
- immutablePropertySources = Collections.unmodifiableList(propertySources);
- LOG.info("Registered " + immutablePropertySources.size() + " property sources: " +
- immutablePropertySources);
-
- // as next step we pick up the PropertyFilters pretty much the same way
- List<PropertyFilter> propertyFilters = new ArrayList<>();
- propertyFilters.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
- Collections.sort(propertyFilters, new PropertyFilterComparator());
- immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
- LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
- immutablePropertyFilters);
-
- immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
- LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
- immutablePropertyFilters);
- propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class);
- if(propertyValueCombinationPolicy==null) {
- propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
- }
- LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
- }
-
- /**
- * Pick up all {@link PropertySourceProvider}s and return all the
- * {@link PropertySource}s they like to register.
- */
- private Collection<? extends PropertySource> evaluatePropertySourcesFromProviders() {
- List<PropertySource> propertySources = new ArrayList<>();
- Collection<PropertySourceProvider> propertySourceProviders = ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class);
- for (PropertySourceProvider propertySourceProvider : propertySourceProviders) {
- Collection<PropertySource> sources = propertySourceProvider.getPropertySources();
- LOG.finer("PropertySourceProvider " + propertySourceProvider.getClass().getName() +
- " provided the following property sources: " + sources);
- propertySources.addAll(sources);
- }
-
- return propertySources;
- }
-
- @Override
- public void addPropertySources(PropertySource... propertySourcesToAdd) {
- Lock writeLock = propertySourceLock.writeLock();
- try {
- writeLock.lock();
- List<PropertySource> newPropertySources = new ArrayList<>(this.immutablePropertySources);
- newPropertySources.addAll(Arrays.asList(propertySourcesToAdd));
- Collections.sort(newPropertySources, new PropertySourceComparator());
-
- this.immutablePropertySources = Collections.unmodifiableList(newPropertySources);
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * Comparator used for comparing PropertySources.
- */
- private static class PropertySourceComparator implements Comparator<PropertySource>, Serializable {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Order property source reversely, the most important come first.
- *
- * @param source1 the first PropertySource
- * @param source2 the second PropertySource
- * @return the comparison result.
- */
- private int comparePropertySources(PropertySource source1, PropertySource source2) {
- if (source1.getOrdinal() < source2.getOrdinal()) {
- return -1;
- } else if (source1.getOrdinal() > source2.getOrdinal()) {
- return 1;
- } else {
- return source1.getClass().getName().compareTo(source2.getClass().getName());
- }
- }
-
- @Override
- public int compare(PropertySource source1, PropertySource source2) {
- return comparePropertySources(source1, source2);
- }
- }
-
- /**
- * Comparator used for comparing PropertyFilters.
- */
- private static class PropertyFilterComparator implements Comparator<PropertyFilter>, Serializable{
-
- private static final long serialVersionUID = 1L;
-
- /**
- * 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);
- }
- }
-
- @Override
- public List<PropertySource> getPropertySources() {
- return immutablePropertySources;
- }
-
- @Override
- public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
- propertyConverterManager.register(typeToConvert, propertyConverter);
- LOG.info("Added PropertyConverter: " + propertyConverter.getClass().getName());
- }
-
- @Override
- public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
- return propertyConverterManager.getPropertyConverters();
- }
-
- @Override
- public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
- return propertyConverterManager.getPropertyConverters(targetType);
- }
-
- @Override
- public List<PropertyFilter> getPropertyFilters() {
- return immutablePropertyFilters;
- }
-
- @Override
- public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(){
- return propertyValueCombinationPolicy;
- }
-
- @Override
- public ConfigurationContextBuilder toBuilder() {
- return ConfigurationProvider.getConfigurationContextBuilder().setContext(this);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e441ee72/src/main/java/org/apache/tamaya/clsupport/internal/ctx/EnumConverter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/ctx/EnumConverter.java b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/EnumConverter.java
deleted file mode 100644
index a75de75..0000000
--- a/src/main/java/org/apache/tamaya/clsupport/internal/ctx/EnumConverter.java
+++ /dev/null
@@ -1,67 +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.clsupport.internal.ctx;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.spi.PropertyConverter;
-
-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.
- * @param <T> the enum type.
- */
-class EnumConverter<T> implements PropertyConverter<T> {
- private 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) {
- 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;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e441ee72/src/main/java/org/apache/tamaya/clsupport/internal/ctx/PropertyConverterManager.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/ctx/PropertyConverterManager.java b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/PropertyConverterManager.java
deleted file mode 100644
index 848fe78..0000000
--- a/src/main/java/org/apache/tamaya/clsupport/internal/ctx/PropertyConverterManager.java
+++ /dev/null
@@ -1,434 +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.clsupport.internal.ctx;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.spi.PropertyConverter;
-import org.apache.tamaya.spi.ServiceContextManager;
-
-import javax.annotation.Priority;
-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.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-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.Logger;
-
-/**
- * Manager that deals with {@link PropertyConverter} instances.
- * This class is thread-safe.
- */
-class PropertyConverterManager {
- /**
- * The logger used.
- */
- private static final Logger LOG = Logger.getLogger(PropertyConverterManager.class.getName());
- /**
- * The registered converters.
- */
- private Map<TypeLiteral<?>, List<PropertyConverter<?>>> converters = new ConcurrentHashMap<>();
- /**
- * The transitive converters.
- */
- private Map<TypeLiteral<?>, List<PropertyConverter<?>>> transitiveConverters = new ConcurrentHashMap<>();
- /**
- * The lock used.
- */
- private ReadWriteLock lock = new ReentrantReadWriteLock();
-
- private static final Comparator<Object> PRIORITY_COMPARATOR = new Comparator<Object>() {
-
- @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 s evaluated. If no such
- * annotation is present, a default priority is returned (1);
- * @param o the instance, not null.
- * @return a priority, by default 1.
- */
- public static int getPriority(Object o){
- int prio = 1;
- Priority priority = o.getClass().getAnnotation(Priority.class);
- if (priority != null) {
- prio = priority.value();
- }
- return prio;
- }
-
- /**
- * Constructor.
- */
- public PropertyConverterManager() {
- this(true);
- }
-
- public PropertyConverterManager(boolean init) {
- if (init) {
- initConverters();
- }
- }
-
- /**
- * Registers the default converters provided out of the box.
- */
- 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 ew converter instance.
- *
- * @param targetType the target type, not null.
- * @param converter the converter, not null.
- * @param <T> the type.
- */
- public <T> void register(TypeLiteral<T> targetType, PropertyConverter<T> converter) {
- Objects.requireNonNull(converter);
- Lock writeLock = lock.writeLock();
- try {
- writeLock.lock();
- List converters = List.class.cast(this.converters.get(targetType));
- List<PropertyConverter<?>> newConverters = new ArrayList<>();
- if (converters != null) {
- newConverters.addAll(converters);
- }
- 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 null.
- * @return true, if a converter for the given type is registered, or a default one can be created.
- */
- public boolean isTargetTypeSupported(TypeLiteral<?> targetType) {
- if (converters.containsKey(targetType) || transitiveConverters.containsKey(targetType)) {
- return true;
- }
- return 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(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
- * converter based on String costructor or static factory methods available.<br/>
- * 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
- * primarly for converting a value.</li>
- * <li>The target type of each explicitly registered converter 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>
- *
- * 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 null.
- * @param <T> the type class
- * @return the ordered list of converters (may be empty for not convertible types).
- * @see #createDefaultPropertyConverter(TypeLiteral)
- */
- public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
- Lock readLock = lock.readLock();
- List<PropertyConverter<T>> converterList = new ArrayList<>();
- List<PropertyConverter<T>> converters;
- // direct mapped converters
- try {
- readLock.lock();
- converters = List.class.cast(this.converters.get(targetType));
- } finally {
- readLock.unlock();
- }
- if (converters != null) {
- converterList.addAll(converters);
- }
- // transitive converter
- try {
- readLock.lock();
- converters = List.class.cast(this.transitiveConverters.get(targetType));
- } finally {
- readLock.unlock();
- }
- if (converters != null) {
- converterList.addAll(converters);
- }
- // handling of java.lang wrapper classes
- TypeLiteral<T> boxedType = mapBoxedType(targetType);
- if (boxedType != null) {
- try {
- readLock.lock();
- converters = List.class.cast(this.converters.get(boxedType));
- } finally {
- readLock.unlock();
- }
- if (converters != null) {
- converterList.addAll(converters);
- }
- }
- if (converterList.isEmpty()) {
- // 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();
- converters = List.class.cast(this.converters.get(targetType));
- } finally {
- readLock.unlock();
- }
- }
- if (converters != null) {
- converterList.addAll(converters);
- }
- }
- return converterList;
- }
-
- /**
- * Maps native types to the corresponding boxed types.
- *
- * @param targetType the native type.
- * @param <T> the type
- * @return the boxed type, or null.
- */
- 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 converter, or null.
- */
- protected <T> PropertyConverter<T> createDefaultPropertyConverter(final TypeLiteral<T> targetType) {
- if (Enum.class.isAssignableFrom(targetType.getRawType())) {
- return new EnumConverter<T>(targetType.getRawType());
- }
- PropertyConverter<T> converter = null;
- final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "valueOf", "instanceOf", "getInstance", "from", "fromString", "parse");
- if (factoryMethod != null) {
- converter = new PropertyConverter<T>() {
- @Override
- public T convert(String value) {
- try {
- if (!Modifier.isStatic(factoryMethod.getModifiers())) {
- throw new ConfigException(factoryMethod.toGenericString() +
- " is not a static method. Only static " +
- "methods can be used as factory methods.");
- }
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- factoryMethod.setAccessible(true);
- return null;
- }
- });
- Object invoke = factoryMethod.invoke(null, value);
- return targetType.getRawType().cast(invoke);
- } catch (Exception e) {
- throw new ConfigException("Failed to decode '" + value + "'", e);
- }
- }
- };
- }
- if (converter == null) {
- try {
- final Constructor<T> constr = targetType.getRawType().getDeclaredConstructor(String.class);
- converter = new PropertyConverter<T>() {
- @Override
- public T convert(String value) {
- try {
- constr.setAccessible(true);
- return constr.newInstance(value);
- } catch (Exception e) {
- throw new ConfigException("Failed to decode '" + value + "'", e);
- }
- }
- };
- } catch (Exception e) {
- LOG.finest("Failed to construct instance of type: " + targetType.getRawType().getName() + ": " + e);
- }
- }
- 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;
- }
-
-}
[20/23] incubator-tamaya-sandbox git commit: [maven-release-plugin]
prepare release vote02-tamaya-0.2-incubating
Posted by pl...@apache.org.
[maven-release-plugin] prepare release vote02-tamaya-0.2-incubating
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/ecd3cdcf
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/ecd3cdcf
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/ecd3cdcf
Branch: refs/heads/master
Commit: ecd3cdcf9d5a4a2468dadd124fd1e724dc1edf9a
Parents: f84be47
Author: anatole <an...@apache.org>
Authored: Tue Apr 5 18:56:54 2016 +0200
Committer: anatole <an...@apache.org>
Committed: Tue Apr 5 18:56:54 2016 +0200
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/ecd3cdcf/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 24322dd..82bbd15 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-extensions</artifactId>
- <version>0.2-incubating-SNAPSHOT</version>
+ <version>0.2-incubating</version>
<relativePath>..</relativePath>
</parent>
[11/23] incubator-tamaya-sandbox git commit: Unified module name in
poms.
Posted by pl...@apache.org.
Unified module name in poms.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/f37fcb3d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/f37fcb3d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/f37fcb3d
Branch: refs/heads/master
Commit: f37fcb3da282411ab24fe20254c6149016d67ebf
Parents: 8c370a7
Author: anatole <an...@apache.org>
Authored: Sat Jan 16 07:40:08 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Sat Jan 16 07:40:08 2016 +0100
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/f37fcb3d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1b593d4..5f8eeb5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@ under the License.
</parent>
<artifactId>tamaya-classloader-support</artifactId>
- <name>Apache Tamaya Modules -Classloader Support</name>
+ <name>Apache Tamaya Modules - Classloader Support</name>
<description>Apache Tamaya Classloader Support registers a ConfigurationContext that leverages
classloader hierarchies. Also visibility of features and components is aligned with the
corresponding hierarchy of classloaders.</description>
[19/23] incubator-tamaya-sandbox git commit: Reset version,
integrated docs into site.
Posted by pl...@apache.org.
Reset version, integrated docs into site.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/f84be473
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/f84be473
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/f84be473
Branch: refs/heads/master
Commit: f84be473feb80e2a9fa7eef4c4d08970ed1c7cbd
Parents: 762d307
Author: anatole <an...@apache.org>
Authored: Wed Mar 16 21:54:18 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Wed Mar 16 21:54:18 2016 +0100
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/f84be473/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1d27df4..24322dd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-extensions</artifactId>
- <version>0.3-incubating-SNAPSHOT</version>
+ <version>0.2-incubating-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
[13/23] incubator-tamaya-sandbox git commit: [maven-release-plugin]
prepare for next development iteration
Posted by pl...@apache.org.
[maven-release-plugin] prepare for next development iteration
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/fcf04cf4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/fcf04cf4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/fcf04cf4
Branch: refs/heads/master
Commit: fcf04cf412090533e348fd007889dbe5c0b1b1c4
Parents: 3f36460
Author: anatole <an...@apache.org>
Authored: Tue Mar 8 17:40:05 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Tue Mar 8 17:40:05 2016 +0100
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/fcf04cf4/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 82bbd15..1d27df4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-extensions</artifactId>
- <version>0.2-incubating</version>
+ <version>0.3-incubating-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
[02/23] incubator-tamaya-sandbox git commit: Added logging support.
Posted by pl...@apache.org.
Added logging support.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/6e6419cb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/6e6419cb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/6e6419cb
Branch: refs/heads/master
Commit: 6e6419cb5f6f8c42cf984702e1110ed7bdf586e9
Parents: 9c922df
Author: anatole <an...@apache.org>
Authored: Sun Sep 27 23:52:56 2015 +0200
Committer: anatole <an...@apache.org>
Committed: Sun Sep 27 23:52:56 2015 +0200
----------------------------------------------------------------------
.../internal/CLAwareServiceContext.java | 23 ++++++++++++++++++++
1 file changed, 23 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/6e6419cb/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java b/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
index c023cff..02caed0 100644
--- a/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
@@ -28,6 +28,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
@@ -45,6 +47,9 @@ import java.util.List;
@Priority(10)
public class CLAwareServiceContext extends AbstractClassloaderAwareItemLoader<ServiceContainer>
implements ServiceContext{
+
+ private static final Logger LOG = Logger.getLogger(CLAwareServiceContext.class.getName());
+
/**
* Default location for service loader files.
*/
@@ -75,6 +80,9 @@ public class CLAwareServiceContext extends AbstractClassloaderAwareItemLoader<Se
*/
@Override
protected ServiceContainer createItem(ClassLoader classLoader) {
+ if(LOG.isLoggable(Level.INFO)) {
+ LOG.info("Loading services for classloader: " + classLoader);
+ }
return new ServiceContainer(classLoader);
}
@@ -110,9 +118,15 @@ public class CLAwareServiceContext extends AbstractClassloaderAwareItemLoader<Se
* @return the item found, or null.
*/
public <T> T getService(Class<T> serviceType, ClassLoader classLoader) {
+ if(LOG.isLoggable(Level.INFO)) {
+ LOG.info("Evaluating services for classloader: " + classLoader);
+ }
ServiceContainer container = getItemNoParent(classLoader, true);
T singleton = container.getSingleton(serviceType);
if(singleton!=null){
+ if(LOG.isLoggable(Level.FINEST)) {
+ LOG.finest("Evaluated singleton of type " + serviceType.getName() + " to " + singleton);
+ }
return singleton;
}
Collection<? extends T> services = getServices(serviceType, classLoader);
@@ -124,6 +138,9 @@ public class CLAwareServiceContext extends AbstractClassloaderAwareItemLoader<Se
if(singleton!=null) {
container.setSingleton(serviceType, singleton);
}
+ if(LOG.isLoggable(Level.FINEST)) {
+ LOG.finest("Evaluated singleton of type " + serviceType.getName() + " to " + singleton);
+ }
return singleton;
}
@@ -164,6 +181,9 @@ public class CLAwareServiceContext extends AbstractClassloaderAwareItemLoader<Se
services.addAll(container.getServices(serviceType));
prevContainers.add(container);
}
+ if(LOG.isLoggable(Level.FINEST)) {
+ LOG.finest("Evaluated services of type " + serviceType.getName() + " to " + services);
+ }
return services;
}
@@ -218,6 +238,9 @@ public class CLAwareServiceContext extends AbstractClassloaderAwareItemLoader<Se
if (priority != null) {
prio = priority.value();
}
+ if(LOG.isLoggable(Level.FINEST)) {
+ LOG.finest("Evaluated priority for " + o.getClass().getName() + " to " + prio);
+ }
return prio;
}
[07/23] incubator-tamaya-sandbox git commit: TAMAYA-123: Adding OSGI
Support: had to move some aspects out of (non-accessible) internal packages.
Posted by pl...@apache.org.
TAMAYA-123: Adding OSGI Support: had to move some aspects out of (non-accessible) internal packages.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/03a58b64
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/03a58b64
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/03a58b64
Branch: refs/heads/master
Commit: 03a58b64c0ed6093d375e37455618e1bfae0b1bb
Parents: e441ee7
Author: anatole <an...@apache.org>
Authored: Fri Oct 16 19:33:48 2015 +0200
Committer: anatole <an...@apache.org>
Committed: Fri Oct 16 19:33:48 2015 +0200
----------------------------------------------------------------------
.../clsupport/CLAwareConfigurationContext.java | 105 +++++++
.../tamaya/clsupport/CLAwareServiceContext.java | 246 +++++++++++++++
.../tamaya/clsupport/ServiceContainer.java | 311 +++++++++++++++++++
.../internal/CLAwareConfigurationContext.java | 106 -------
.../internal/CLAwareServiceContext.java | 247 ---------------
.../clsupport/internal/ServiceContainer.java | 311 -------------------
.../tamaya/clsupport/internal/package-info.java | 22 --
.../org.apache.tamaya.spi.ServiceContext | 2 +-
8 files changed, 663 insertions(+), 687 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/03a58b64/src/main/java/org/apache/tamaya/clsupport/CLAwareConfigurationContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/CLAwareConfigurationContext.java b/src/main/java/org/apache/tamaya/clsupport/CLAwareConfigurationContext.java
new file mode 100644
index 0000000..47b78b2
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/CLAwareConfigurationContext.java
@@ -0,0 +1,105 @@
+/*
+ * 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.clsupport;
+
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spisupport.DefaultConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+
+import javax.annotation.Priority;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * Default Implementation of a simple ConfigurationContext.
+ */
+@Priority(100)
+public class CLAwareConfigurationContext implements ConfigurationContext {
+
+ /** The logger used. */
+ private final static Logger LOG = Logger.getLogger(CLAwareConfigurationContext.class.getName());
+
+ private ContextManager contextManager = new ContextManager();
+
+
+ @Override
+ public void addPropertySources(PropertySource... propertySourcesToAdd) {
+ contextManager.getItemNoParent(true).addPropertySources(propertySourcesToAdd);
+ }
+
+ @Override
+ public List<PropertySource> getPropertySources() {
+ return contextManager.getItemNoParent(true).getPropertySources();
+ }
+
+ @Override
+ public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+ contextManager.getItemNoParent(true).addPropertyConverter(typeToConvert, propertyConverter);
+ }
+
+ @Override
+ public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+ return contextManager.getItemNoParent(true).getPropertyConverters();
+ }
+
+ @Override
+ public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+ return contextManager.getItemNoParent(true).getPropertyConverters(targetType);
+ }
+
+ @Override
+ public List<PropertyFilter> getPropertyFilters() {
+ return contextManager.getItemNoParent(true).getPropertyFilters();
+ }
+
+ @Override
+ public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(){
+ return contextManager.getItemNoParent(true).getPropertyValueCombinationPolicy();
+ }
+
+ @Override
+ public ConfigurationContextBuilder toBuilder() {
+ return contextManager.getItemNoParent(true).toBuilder();
+ }
+
+
+ /**
+ * Subcomponent managing {@link ConfigurationContext} instances, one per classloader.
+ */
+ private static final class ContextManager extends AbstractClassloaderAwareItemLoader<ConfigurationContext>{
+
+ @Override
+ protected ConfigurationContext createItem(ClassLoader classLoader) {
+ // Simply create a complete configuration manager for every classloader. Maybe we will optimize this at a
+ // later stage in the project but as for now it is the most simple working solution.
+ return new DefaultConfigurationContext();
+ }
+
+ @Override
+ protected void updateItem(ConfigurationContext currentItemSet, ClassLoader classLoader) {
+ // ignore, currently not supported.
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/03a58b64/src/main/java/org/apache/tamaya/clsupport/CLAwareServiceContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/CLAwareServiceContext.java b/src/main/java/org/apache/tamaya/clsupport/CLAwareServiceContext.java
new file mode 100644
index 0000000..392d8b1
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/CLAwareServiceContext.java
@@ -0,0 +1,246 @@
+/*
+ * 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.clsupport;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.ServiceContext;
+
+import javax.annotation.Priority;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * This class implements a {@link ServiceContext}, which basically provides a similar loading mechanism as used
+ * by the {@link java.util.ServiceLoader}. Whereas the {@link java.util.ServiceLoader} only loads configurations
+ * and instances from one classloader, this loader manages configs found and the related instances for each
+ * classloader along the classloader hierarchies individually. It ensures instances are loaded on the classloader
+ * level, where they first are visible. Additionally it ensures the same configuration resource (and its
+ * declared services) are loaded multiple times, when going up the classloader hierarchy.<p/>
+ * Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected.
+ * Refer also the inherited parent class for further details.<p/>
+ * This class uses an ordinal of {@code 10}, so it overrides any default {@link ServiceContext} implementations
+ * provided with the Tamaya core modules.
+ */
+@Priority(10)
+public class CLAwareServiceContext extends AbstractClassloaderAwareItemLoader<ServiceContainer>
+ implements ServiceContext{
+
+ private static final Logger LOG = Logger.getLogger(CLAwareServiceContext.class.getName());
+
+ /**
+ * Default location for service loader files.
+ */
+ private static final String PREFIX = "META-INF/services/";
+
+ /**
+ * Constructor, using the current default classloader as defined by
+ * {@link AbstractClassloaderAwareItemLoader#getDefaultClassLoader()}.
+ */
+ public CLAwareServiceContext(){
+ super();
+ }
+
+ /**
+ * Constructor, using the given classloader.
+ * @param classLoader the target classloader for initializing of services, not null.
+ */
+ public CLAwareServiceContext(ClassLoader classLoader) {
+ super(classLoader);
+ }
+
+
+ /**
+ * Implementation that creates a {@link ServiceContainer}, which manages all configs and instances loaded
+ * for a given classloader.
+ * @param classLoader the classloader, not null.
+ * @return a new empty, {@link ServiceContainer} instance.
+ */
+ @Override
+ protected ServiceContainer createItem(ClassLoader classLoader) {
+ if(LOG.isLoggable(Level.INFO)) {
+ LOG.info("Loading services for classloader: " + classLoader);
+ }
+ return new ServiceContainer(classLoader);
+ }
+
+ @Override
+ protected void updateItem(ServiceContainer currentContainer, ClassLoader classLoader) {
+ // nothing to be done here, since we dont have a specific target type.
+ }
+
+ @Override
+ public int ordinal() {
+ return 10;
+ }
+
+ /**
+ * This method tries to evaluate the current singleton from the {@link ServiceContainer} attached to the
+ * current classloader. If not found the singleton instance is evaluated based on the priorities
+ * assigned for all known providers. The resulting instance is then cached and always returned as
+ * singleton instance fomr this loader, when the same current classloader instance is active.
+ * @param serviceType the service type.
+ * @param <T> the type
+ * @return the item found, or null.
+ */
+ @Override
+ public <T> T getService(Class<T> serviceType) {
+ return getService(serviceType, getDefaultClassLoader());
+ }
+
+ /**
+ * Evaluates the current singleton instance using the given classloader context.
+ * @param serviceType the service type.
+ * @param classLoader the classloader, not null.
+ * @param <T> the type
+ * @return the item found, or null.
+ */
+ public <T> T getService(Class<T> serviceType, ClassLoader classLoader) {
+ if(LOG.isLoggable(Level.INFO)) {
+ LOG.info("Evaluating services for classloader: " + classLoader);
+ }
+ ServiceContainer container = getItemNoParent(classLoader, true);
+ T singleton = container.getSingleton(serviceType);
+ if(singleton!=null){
+ if(LOG.isLoggable(Level.FINEST)) {
+ LOG.finest("Evaluated singleton of type " + serviceType.getName() + " to " + singleton);
+ }
+ return singleton;
+ }
+ Collection<? extends T> services = getServices(serviceType, classLoader);
+ if (services.isEmpty()) {
+ singleton = null;
+ } else {
+ singleton = getServiceWithHighestPriority(services, serviceType);
+ }
+ if(singleton!=null) {
+ container.setSingleton(serviceType, singleton);
+ }
+ if(LOG.isLoggable(Level.FINEST)) {
+ LOG.finest("Evaluated singleton of type " + serviceType.getName() + " to " + singleton);
+ }
+ return singleton;
+ }
+
+ /**
+ * Gets the services visible.
+ * @param serviceType
+ * the service type.
+ * @param <T> the type param
+ * @return the services visible for the current classloader.
+ */
+ @Override
+ public <T> List<T> getServices(Class<T> serviceType) {
+ return getServices(serviceType, AbstractClassloaderAwareItemLoader.getDefaultClassLoader());
+ }
+
+ /**
+ * Gets the services visible.
+ * @param serviceType the service type.
+ * @param classLoader the classloader
+ * @param <T> the type param
+ * @return the services visible for the current classloader.
+ */
+ public <T> List<T> getServices(Class<T> serviceType, ClassLoader classLoader) {
+ List<T> services = new ArrayList<>();
+ ClassLoader cl = classLoader;
+ List<ServiceContainer> containers = new ArrayList<>();
+ while(cl!=null) {
+ ServiceContainer container = getItemNoParent(cl, true);
+ containers.add(container);
+ cl = cl.getParent();
+ }
+ List<ServiceContainer> prevContainers = new ArrayList<>();
+ Collections.reverse(containers);
+ for(ServiceContainer container: containers) {
+ if (!container.isTypeLoaded(serviceType)) {
+ container.loadServices(serviceType, prevContainers);
+ }
+ services.addAll(container.getServices(serviceType));
+ prevContainers.add(container);
+ }
+ if(LOG.isLoggable(Level.FINEST)) {
+ LOG.finest("Evaluated services of type " + serviceType.getName() + " to " + services);
+ }
+ return services;
+ }
+
+ /**
+ * @param services to scan
+ * @param <T> type of the service
+ *
+ * @return the service with the highest {@link javax.annotation.Priority#value()}
+ *
+ * @throws ConfigException if there are multiple service implementations with the maximum priority
+ */
+ private <T> T getServiceWithHighestPriority(Collection<? extends T> services, Class<T> serviceType) {
+
+ // we do not need the priority stuff if the list contains only one element
+ if (services.size() == 1) {
+ return services.iterator().next();
+ }
+
+ Integer highestPriority = null;
+ int highestPriorityServiceCount = 0;
+ T highestService = null;
+
+ 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));
+ }
+ return highestService;
+ }
+
+ /**
+ * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
+ * annotation is present, a default priority is returned (1);
+ * @param o the instance, not null.
+ * @return a priority, by default 1.
+ */
+ public static int getPriority(Object o){
+ int prio = 0;
+ Priority priority = o.getClass().getAnnotation(Priority.class);
+ if (priority != null) {
+ prio = priority.value();
+ }
+ if(LOG.isLoggable(Level.FINEST)) {
+ LOG.finest("Evaluated priority for " + o.getClass().getName() + " to " + prio);
+ }
+ return prio;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/03a58b64/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java b/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java
new file mode 100644
index 0000000..1eea749
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java
@@ -0,0 +1,311 @@
+/*
+ * 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.clsupport;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceConfigurationError;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Created by Anatole on 08.09.2015.
+ */
+class ServiceContainer {
+
+ private static final Logger LOG = Logger.getLogger(ServiceContainer.class.getName());
+
+ private static final String PREFIX = "META-INF/services/";
+
+ // The access control context taken when the ServiceLoader is created
+ private final AccessControlContext acc;
+
+ private WeakReference<ClassLoader> classLoaderRef;
+
+ /**
+ * List current services loaded using this classloader, per class.
+ */
+ private final Map<Class<?>, Map<String, Object>> servicesLoaded = new ConcurrentHashMap<>();
+ /**
+ * The cached singletons for the given classloader.
+ */
+ private final Map<Class, Object> singletons = new ConcurrentHashMap<>();
+
+ /**
+ * List current services loaded using this classloader, per class.
+ */
+ private final Map<Class, List<URL>> configsLoaded = new ConcurrentHashMap<>();
+
+ ServiceContainer(ClassLoader classLoader) {
+ acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;
+ this.classLoaderRef = new WeakReference<>(classLoader);
+ }
+
+ public ClassLoader getClassLoader() {
+ ClassLoader cl = classLoaderRef.get();
+ if (cl == null) {
+ throw new IllegalStateException("Classloader reference removed, not active anynire.");
+ }
+ return cl;
+ }
+
+
+ public <T> void loadServices(Class<?> type,
+ Collection<ServiceContainer> preceedingContainers) {
+ Map<String, Object> services = (Map<String, Object>) this.servicesLoaded.get(type);
+ if (services == null) {
+ services = new LinkedHashMap<>();
+ this.servicesLoaded.put(type, services);
+ }
+ loop:
+ for (URL config : getConfigs(type)) {
+ for (ServiceContainer cont : preceedingContainers) {
+ if (cont.getConfigs(type).contains(config)) {
+ LOG.finer("Ignoring already loaded config: " + config);
+ continue loop;
+ }
+ }
+ Collection<String> serviceNames = parse(type, config);
+ for (String s : serviceNames) {
+ for (ServiceContainer cont : preceedingContainers) {
+ if (cont.containsService(type, s)) {
+ LOG.finest("Ignoring duplicate service: " + s);
+ continue;
+ }
+ }
+ LOG.info("Loading component: " + s);
+ services.put(s, create(type, s));
+ }
+ }
+ }
+
+ private Collection<URL> getConfigs(Class<?> type) {
+ List<URL> result = this.configsLoaded.get(type);
+ if (result == null) {
+ ClassLoader cl = this.classLoaderRef.get();
+ if (cl == null) {
+ throw new IllegalStateException("CLassLoader dereferenced already.");
+ }
+ result = new ArrayList<>();
+ try {
+ Enumeration<URL> resources = cl.getResources(PREFIX + type.getName());
+ while (resources.hasMoreElements()) {
+ result.add(resources.nextElement());
+ }
+ } catch (Exception e) {
+ LOG.log(Level.WARNING, "Failed to read service config for " + type.getName() + " from " + cl, e);
+ }
+ this.configsLoaded.put(type, result);
+ LOG.log(Level.FINE, "Found service config for " + type.getName() + ": " + result);
+ }
+ return result;
+ }
+
+ private boolean containsService(Class<?> type, String serviceClassName) {
+ Map<String, Object> services = servicesLoaded.get(type);
+ if (services == null) {
+ return false;
+ }
+ return services.containsKey(serviceClassName);
+ }
+
+
+ private <S> S create(Class<S> serviceType, String className) {
+ Class<?> c = null;
+ ClassLoader classLoader = getClassLoader();
+ try {
+ c = Class.forName(className, false, classLoader);
+ } catch (ClassNotFoundException x) {
+ fail(serviceType,
+ "Provider " + className + " not found");
+ }
+ if (!serviceType.isAssignableFrom(c)) {
+ fail(serviceType,
+ "Provider " + className + " not a subtype");
+ }
+ try {
+ S p = serviceType.cast(c.newInstance());
+ return p;
+ } catch (Throwable x) {
+ fail(serviceType,
+ "Provider " + className + " could not be instantiated",
+ x);
+ }
+ throw new Error(); // This cannot happen
+ }
+
+ public <T> Collection<T> getServices(Class<T> serviceType) {
+ Map<String, Object> services = this.servicesLoaded.get(serviceType);
+ if (services != null) {
+ return (Collection<T>) services.values();
+ }
+ return Collections.emptySet();
+ }
+
+ public boolean isTypeLoaded(Class<?> serviceType) {
+ return this.servicesLoaded.containsKey(serviceType);
+ }
+
+ public Collection<URL> load(Class<?> serviceType) {
+ return load(serviceType, Collection.class.cast(Collections.emptySet()));
+ }
+
+ public Collection<URL> load(Class<?> serviceType, Collection<URL> configsLoaded) {
+ List<URL> result = new ArrayList<>();
+ try {
+ Enumeration<URL> resources = getClassLoader().getResources(PREFIX + serviceType.getName());
+ while (resources.hasMoreElements()) {
+ URL res = resources.nextElement();
+ if (!configsLoaded.contains(res)) {
+ result.add(res);
+ }
+ }
+ return result;
+ } catch (Exception e) {
+ fail(serviceType, "Failed to load service config: " + PREFIX + serviceType.getName(), e);
+ }
+ return result;
+ }
+
+
+ // Parse a single line from the given configuration file, adding the name
+ // on the line to the names list.
+ //
+ private int parseLine(Class<?> serviceType, URL u, BufferedReader r, int lc,
+ List<String> names)
+ throws IOException, ServiceConfigurationError {
+ String ln = r.readLine();
+ if (ln == null) {
+ return -1;
+ }
+ int ci = ln.indexOf('#');
+ if (ci >= 0) {
+ ln = ln.substring(0, ci);
+ }
+ ln = ln.trim();
+ int n = ln.length();
+ if (n != 0) {
+ if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) {
+ fail(serviceType, u, lc, "Illegal configuration-file syntax");
+ }
+ int cp = ln.codePointAt(0);
+ if (!Character.isJavaIdentifierStart(cp)) {
+ fail(serviceType, u, lc, "Illegal provider-class name: " + ln);
+ }
+ for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
+ cp = ln.codePointAt(i);
+ if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) {
+ fail(serviceType, u, lc, "Illegal provider-class name: " + ln);
+ }
+ }
+ Map<String, Object> services = this.servicesLoaded.get(serviceType);
+ if (services == null || !services.containsKey(ln) && !names.contains(ln)) {
+ names.add(ln);
+ }
+ }
+ return lc + 1;
+ }
+
+
+ // Parse the content of the given URL as a provider-configuration file.
+ //
+ // @param service
+ // The service type for which providers are being sought;
+ // used to construct error detail strings
+ //
+ // @param u
+ // The URL naming the configuration file to be parsed
+ //
+ // @return A (possibly empty) iterator that will yield the provider-class
+ // names in the given configuration file that are not yet members
+ // of the returned set
+ //
+ // @throws ServiceConfigurationError
+ // If an I/O error occurs while reading from the given URL, or
+ // if a configuration-file format error is detected
+ //
+ private Collection<String> parse(Class<?> service, URL u)
+ throws ServiceConfigurationError {
+ InputStream in = null;
+ BufferedReader r = null;
+ ArrayList<String> names = new ArrayList<>();
+ try {
+ in = u.openStream();
+ r = new BufferedReader(new InputStreamReader(in, "utf-8"));
+ int lc = 1;
+ while ((lc = parseLine(service, u, r, lc, names)) >= 0) {
+ // go ahead
+ }
+ } catch (IOException x) {
+ fail(service, "Error reading configuration file", x);
+ } finally {
+ try {
+ if (r != null) {
+ r.close();
+ }
+ if (in != null) {
+ in.close();
+ }
+ } catch (IOException y) {
+ fail(service, "Error closing configuration file", y);
+ }
+ }
+ return names;
+ }
+
+
+ private static void fail(Class<?> service, String msg, Throwable cause)
+ throws ServiceConfigurationError {
+ LOG.log(Level.SEVERE, "Failed to load: " + service.getName() + ": " + msg, cause);
+ }
+
+ private static void fail(Class<?> service, String msg)
+ throws ServiceConfigurationError {
+ LOG.log(Level.SEVERE, "Failed to load: " + service.getName() + ": " + msg);
+ }
+
+ private static void fail(Class<?> service, URL u, int line, String msg)
+ throws ServiceConfigurationError {
+ fail(service, u + ":" + line + ": " + msg);
+ }
+
+ public <T> T getSingleton(Class<T> serviceType) {
+ return (T) this.singletons.get(serviceType);
+ }
+
+ <T> void setSingleton(Class<T> type, T instance) {
+ LOG.info("Caching singleton for " + type.getName() + " and classloader: " +
+ getClassLoader().toString() + ": " + instance);
+ this.singletons.put(type, instance);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/03a58b64/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareConfigurationContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareConfigurationContext.java b/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareConfigurationContext.java
deleted file mode 100644
index 8575393..0000000
--- a/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareConfigurationContext.java
+++ /dev/null
@@ -1,106 +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.clsupport.internal;
-
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.clsupport.AbstractClassloaderAwareItemLoader;
-import org.apache.tamaya.clsupport.internal.ctx.DefaultConfigurationContext;
-import org.apache.tamaya.spi.ConfigurationContext;
-import org.apache.tamaya.spi.ConfigurationContextBuilder;
-import org.apache.tamaya.spi.PropertyConverter;
-import org.apache.tamaya.spi.PropertyFilter;
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
-
-import javax.annotation.Priority;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Logger;
-
-/**
- * Default Implementation of a simple ConfigurationContext.
- */
-@Priority(100)
-public class CLAwareConfigurationContext implements ConfigurationContext {
-
- /** The logger used. */
- private final static Logger LOG = Logger.getLogger(CLAwareConfigurationContext.class.getName());
-
- private ContextManager contextManager = new ContextManager();
-
-
- @Override
- public void addPropertySources(PropertySource... propertySourcesToAdd) {
- contextManager.getItemNoParent(true).addPropertySources(propertySourcesToAdd);
- }
-
- @Override
- public List<PropertySource> getPropertySources() {
- return contextManager.getItemNoParent(true).getPropertySources();
- }
-
- @Override
- public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
- contextManager.getItemNoParent(true).addPropertyConverter(typeToConvert, propertyConverter);
- }
-
- @Override
- public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
- return contextManager.getItemNoParent(true).getPropertyConverters();
- }
-
- @Override
- public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
- return contextManager.getItemNoParent(true).getPropertyConverters(targetType);
- }
-
- @Override
- public List<PropertyFilter> getPropertyFilters() {
- return contextManager.getItemNoParent(true).getPropertyFilters();
- }
-
- @Override
- public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(){
- return contextManager.getItemNoParent(true).getPropertyValueCombinationPolicy();
- }
-
- @Override
- public ConfigurationContextBuilder toBuilder() {
- return contextManager.getItemNoParent(true).toBuilder();
- }
-
-
- /**
- * Subcomponent managing {@link ConfigurationContext} instances, one per classloader.
- */
- private static final class ContextManager extends AbstractClassloaderAwareItemLoader<ConfigurationContext>{
-
- @Override
- protected ConfigurationContext createItem(ClassLoader classLoader) {
- // Simply create a complete configuration manager for every classloader. Maybe we will optimize this at a
- // later stage in the project but as for now it is the most simple working solution.
- return new DefaultConfigurationContext();
- }
-
- @Override
- protected void updateItem(ConfigurationContext currentItemSet, ClassLoader classLoader) {
- // ignore, currently not supported.
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/03a58b64/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java b/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
deleted file mode 100644
index 02caed0..0000000
--- a/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
+++ /dev/null
@@ -1,247 +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.clsupport.internal;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.clsupport.AbstractClassloaderAwareItemLoader;
-import org.apache.tamaya.spi.ServiceContext;
-
-import javax.annotation.Priority;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-
-/**
- * This class implements a {@link ServiceContext}, which basically provides a similar loading mechanism as used
- * by the {@link java.util.ServiceLoader}. Whereas the {@link java.util.ServiceLoader} only loads configurations
- * and instances from one classloader, this loader manages configs found and the related instances for each
- * classloader along the classloader hierarchies individually. It ensures instances are loaded on the classloader
- * level, where they first are visible. Additionally it ensures the same configuration resource (and its
- * declared services) are loaded multiple times, when going up the classloader hierarchy.<p/>
- * Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected.
- * Refer also the inherited parent class for further details.<p/>
- * This class uses an ordinal of {@code 10}, so it overrides any default {@link ServiceContext} implementations
- * provided with the Tamaya core modules.
- */
-@Priority(10)
-public class CLAwareServiceContext extends AbstractClassloaderAwareItemLoader<ServiceContainer>
- implements ServiceContext{
-
- private static final Logger LOG = Logger.getLogger(CLAwareServiceContext.class.getName());
-
- /**
- * Default location for service loader files.
- */
- private static final String PREFIX = "META-INF/services/";
-
- /**
- * Constructor, using the current default classloader as defined by
- * {@link AbstractClassloaderAwareItemLoader#getDefaultClassLoader()}.
- */
- public CLAwareServiceContext(){
- super();
- }
-
- /**
- * Constructor, using the given classloader.
- * @param classLoader the target classloader for initializing of services, not null.
- */
- public CLAwareServiceContext(ClassLoader classLoader) {
- super(classLoader);
- }
-
-
- /**
- * Implementation that creates a {@link ServiceContainer}, which manages all configs and instances loaded
- * for a given classloader.
- * @param classLoader the classloader, not null.
- * @return a new empty, {@link ServiceContainer} instance.
- */
- @Override
- protected ServiceContainer createItem(ClassLoader classLoader) {
- if(LOG.isLoggable(Level.INFO)) {
- LOG.info("Loading services for classloader: " + classLoader);
- }
- return new ServiceContainer(classLoader);
- }
-
- @Override
- protected void updateItem(ServiceContainer currentContainer, ClassLoader classLoader) {
- // nothing to be done here, since we dont have a specific target type.
- }
-
- @Override
- public int ordinal() {
- return 10;
- }
-
- /**
- * This method tries to evaluate the current singleton from the {@link ServiceContainer} attached to the
- * current classloader. If not found the singleton instance is evaluated based on the priorities
- * assigned for all known providers. The resulting instance is then cached and always returned as
- * singleton instance fomr this loader, when the same current classloader instance is active.
- * @param serviceType the service type.
- * @param <T> the type
- * @return the item found, or null.
- */
- @Override
- public <T> T getService(Class<T> serviceType) {
- return getService(serviceType, getDefaultClassLoader());
- }
-
- /**
- * Evaluates the current singleton instance using the given classloader context.
- * @param serviceType the service type.
- * @param classLoader the classloader, not null.
- * @param <T> the type
- * @return the item found, or null.
- */
- public <T> T getService(Class<T> serviceType, ClassLoader classLoader) {
- if(LOG.isLoggable(Level.INFO)) {
- LOG.info("Evaluating services for classloader: " + classLoader);
- }
- ServiceContainer container = getItemNoParent(classLoader, true);
- T singleton = container.getSingleton(serviceType);
- if(singleton!=null){
- if(LOG.isLoggable(Level.FINEST)) {
- LOG.finest("Evaluated singleton of type " + serviceType.getName() + " to " + singleton);
- }
- return singleton;
- }
- Collection<? extends T> services = getServices(serviceType, classLoader);
- if (services.isEmpty()) {
- singleton = null;
- } else {
- singleton = getServiceWithHighestPriority(services, serviceType);
- }
- if(singleton!=null) {
- container.setSingleton(serviceType, singleton);
- }
- if(LOG.isLoggable(Level.FINEST)) {
- LOG.finest("Evaluated singleton of type " + serviceType.getName() + " to " + singleton);
- }
- return singleton;
- }
-
- /**
- * Gets the services visible.
- * @param serviceType
- * the service type.
- * @param <T> the type param
- * @return the services visible for the current classloader.
- */
- @Override
- public <T> List<T> getServices(Class<T> serviceType) {
- return getServices(serviceType, AbstractClassloaderAwareItemLoader.getDefaultClassLoader());
- }
-
- /**
- * Gets the services visible.
- * @param serviceType the service type.
- * @param classLoader the classloader
- * @param <T> the type param
- * @return the services visible for the current classloader.
- */
- public <T> List<T> getServices(Class<T> serviceType, ClassLoader classLoader) {
- List<T> services = new ArrayList<>();
- ClassLoader cl = classLoader;
- List<ServiceContainer> containers = new ArrayList<>();
- while(cl!=null) {
- ServiceContainer container = getItemNoParent(cl, true);
- containers.add(container);
- cl = cl.getParent();
- }
- List<ServiceContainer> prevContainers = new ArrayList<>();
- Collections.reverse(containers);
- for(ServiceContainer container: containers) {
- if (!container.isTypeLoaded(serviceType)) {
- container.loadServices(serviceType, prevContainers);
- }
- services.addAll(container.getServices(serviceType));
- prevContainers.add(container);
- }
- if(LOG.isLoggable(Level.FINEST)) {
- LOG.finest("Evaluated services of type " + serviceType.getName() + " to " + services);
- }
- return services;
- }
-
- /**
- * @param services to scan
- * @param <T> type of the service
- *
- * @return the service with the highest {@link javax.annotation.Priority#value()}
- *
- * @throws ConfigException if there are multiple service implementations with the maximum priority
- */
- private <T> T getServiceWithHighestPriority(Collection<? extends T> services, Class<T> serviceType) {
-
- // we do not need the priority stuff if the list contains only one element
- if (services.size() == 1) {
- return services.iterator().next();
- }
-
- Integer highestPriority = null;
- int highestPriorityServiceCount = 0;
- T highestService = null;
-
- 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));
- }
- return highestService;
- }
-
- /**
- * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
- * annotation is present, a default priority is returned (1);
- * @param o the instance, not null.
- * @return a priority, by default 1.
- */
- public static int getPriority(Object o){
- int prio = 0;
- Priority priority = o.getClass().getAnnotation(Priority.class);
- if (priority != null) {
- prio = priority.value();
- }
- if(LOG.isLoggable(Level.FINEST)) {
- LOG.finest("Evaluated priority for " + o.getClass().getName() + " to " + prio);
- }
- return prio;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/03a58b64/src/main/java/org/apache/tamaya/clsupport/internal/ServiceContainer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/ServiceContainer.java b/src/main/java/org/apache/tamaya/clsupport/internal/ServiceContainer.java
deleted file mode 100644
index 713b292..0000000
--- a/src/main/java/org/apache/tamaya/clsupport/internal/ServiceContainer.java
+++ /dev/null
@@ -1,311 +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.clsupport.internal;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.ref.WeakReference;
-import java.net.URL;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.ServiceConfigurationError;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Created by Anatole on 08.09.2015.
- */
-class ServiceContainer {
-
- private static final Logger LOG = Logger.getLogger(ServiceContainer.class.getName());
-
- private static final String PREFIX = "META-INF/services/";
-
- // The access control context taken when the ServiceLoader is created
- private final AccessControlContext acc;
-
- private WeakReference<ClassLoader> classLoaderRef;
-
- /**
- * List current services loaded using this classloader, per class.
- */
- private final Map<Class<?>, Map<String, Object>> servicesLoaded = new ConcurrentHashMap<>();
- /**
- * The cached singletons for the given classloader.
- */
- private final Map<Class, Object> singletons = new ConcurrentHashMap<>();
-
- /**
- * List current services loaded using this classloader, per class.
- */
- private final Map<Class, List<URL>> configsLoaded = new ConcurrentHashMap<>();
-
- ServiceContainer(ClassLoader classLoader) {
- acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;
- this.classLoaderRef = new WeakReference<>(classLoader);
- }
-
- public ClassLoader getClassLoader() {
- ClassLoader cl = classLoaderRef.get();
- if (cl == null) {
- throw new IllegalStateException("Classloader reference removed, not active anynire.");
- }
- return cl;
- }
-
-
- public <T> void loadServices(Class<?> type,
- Collection<ServiceContainer> preceedingContainers) {
- Map<String, Object> services = (Map<String, Object>) this.servicesLoaded.get(type);
- if (services == null) {
- services = new LinkedHashMap<>();
- this.servicesLoaded.put(type, services);
- }
- loop:
- for (URL config : getConfigs(type)) {
- for (ServiceContainer cont : preceedingContainers) {
- if (cont.getConfigs(type).contains(config)) {
- LOG.finer("Ignoring already loaded config: " + config);
- continue loop;
- }
- }
- Collection<String> serviceNames = parse(type, config);
- for (String s : serviceNames) {
- for (ServiceContainer cont : preceedingContainers) {
- if (cont.containsService(type, s)) {
- LOG.finest("Ignoring duplicate service: " + s);
- continue;
- }
- }
- LOG.info("Loading component: " + s);
- services.put(s, create(type, s));
- }
- }
- }
-
- private Collection<URL> getConfigs(Class<?> type) {
- List<URL> result = this.configsLoaded.get(type);
- if (result == null) {
- ClassLoader cl = this.classLoaderRef.get();
- if (cl == null) {
- throw new IllegalStateException("CLassLoader dereferenced already.");
- }
- result = new ArrayList<>();
- try {
- Enumeration<URL> resources = cl.getResources(PREFIX + type.getName());
- while (resources.hasMoreElements()) {
- result.add(resources.nextElement());
- }
- } catch (Exception e) {
- LOG.log(Level.WARNING, "Failed to read service config for " + type.getName() + " from " + cl, e);
- }
- this.configsLoaded.put(type, result);
- LOG.log(Level.FINE, "Found service config for " + type.getName() + ": " + result);
- }
- return result;
- }
-
- private boolean containsService(Class<?> type, String serviceClassName) {
- Map<String, Object> services = servicesLoaded.get(type);
- if (services == null) {
- return false;
- }
- return services.containsKey(serviceClassName);
- }
-
-
- private <S> S create(Class<S> serviceType, String className) {
- Class<?> c = null;
- ClassLoader classLoader = getClassLoader();
- try {
- c = Class.forName(className, false, classLoader);
- } catch (ClassNotFoundException x) {
- fail(serviceType,
- "Provider " + className + " not found");
- }
- if (!serviceType.isAssignableFrom(c)) {
- fail(serviceType,
- "Provider " + className + " not a subtype");
- }
- try {
- S p = serviceType.cast(c.newInstance());
- return p;
- } catch (Throwable x) {
- fail(serviceType,
- "Provider " + className + " could not be instantiated",
- x);
- }
- throw new Error(); // This cannot happen
- }
-
- public <T> Collection<T> getServices(Class<T> serviceType) {
- Map<String, Object> services = this.servicesLoaded.get(serviceType);
- if (services != null) {
- return (Collection<T>) services.values();
- }
- return Collections.emptySet();
- }
-
- public boolean isTypeLoaded(Class<?> serviceType) {
- return this.servicesLoaded.containsKey(serviceType);
- }
-
- public Collection<URL> load(Class<?> serviceType) {
- return load(serviceType, Collection.class.cast(Collections.emptySet()));
- }
-
- public Collection<URL> load(Class<?> serviceType, Collection<URL> configsLoaded) {
- List<URL> result = new ArrayList<>();
- try {
- Enumeration<URL> resources = getClassLoader().getResources(PREFIX + serviceType.getName());
- while (resources.hasMoreElements()) {
- URL res = resources.nextElement();
- if (!configsLoaded.contains(res)) {
- result.add(res);
- }
- }
- return result;
- } catch (Exception e) {
- fail(serviceType, "Failed to load service config: " + PREFIX + serviceType.getName(), e);
- }
- return result;
- }
-
-
- // Parse a single line from the given configuration file, adding the name
- // on the line to the names list.
- //
- private int parseLine(Class<?> serviceType, URL u, BufferedReader r, int lc,
- List<String> names)
- throws IOException, ServiceConfigurationError {
- String ln = r.readLine();
- if (ln == null) {
- return -1;
- }
- int ci = ln.indexOf('#');
- if (ci >= 0) {
- ln = ln.substring(0, ci);
- }
- ln = ln.trim();
- int n = ln.length();
- if (n != 0) {
- if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) {
- fail(serviceType, u, lc, "Illegal configuration-file syntax");
- }
- int cp = ln.codePointAt(0);
- if (!Character.isJavaIdentifierStart(cp)) {
- fail(serviceType, u, lc, "Illegal provider-class name: " + ln);
- }
- for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
- cp = ln.codePointAt(i);
- if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) {
- fail(serviceType, u, lc, "Illegal provider-class name: " + ln);
- }
- }
- Map<String, Object> services = this.servicesLoaded.get(serviceType);
- if (services == null || !services.containsKey(ln) && !names.contains(ln)) {
- names.add(ln);
- }
- }
- return lc + 1;
- }
-
-
- // Parse the content of the given URL as a provider-configuration file.
- //
- // @param service
- // The service type for which providers are being sought;
- // used to construct error detail strings
- //
- // @param u
- // The URL naming the configuration file to be parsed
- //
- // @return A (possibly empty) iterator that will yield the provider-class
- // names in the given configuration file that are not yet members
- // of the returned set
- //
- // @throws ServiceConfigurationError
- // If an I/O error occurs while reading from the given URL, or
- // if a configuration-file format error is detected
- //
- private Collection<String> parse(Class<?> service, URL u)
- throws ServiceConfigurationError {
- InputStream in = null;
- BufferedReader r = null;
- ArrayList<String> names = new ArrayList<>();
- try {
- in = u.openStream();
- r = new BufferedReader(new InputStreamReader(in, "utf-8"));
- int lc = 1;
- while ((lc = parseLine(service, u, r, lc, names)) >= 0) {
- // go ahead
- }
- } catch (IOException x) {
- fail(service, "Error reading configuration file", x);
- } finally {
- try {
- if (r != null) {
- r.close();
- }
- if (in != null) {
- in.close();
- }
- } catch (IOException y) {
- fail(service, "Error closing configuration file", y);
- }
- }
- return names;
- }
-
-
- private static void fail(Class<?> service, String msg, Throwable cause)
- throws ServiceConfigurationError {
- LOG.log(Level.SEVERE, "Failed to load: " + service.getName() + ": " + msg, cause);
- }
-
- private static void fail(Class<?> service, String msg)
- throws ServiceConfigurationError {
- LOG.log(Level.SEVERE, "Failed to load: " + service.getName() + ": " + msg);
- }
-
- private static void fail(Class<?> service, URL u, int line, String msg)
- throws ServiceConfigurationError {
- fail(service, u + ":" + line + ": " + msg);
- }
-
- public <T> T getSingleton(Class<T> serviceType) {
- return (T) this.singletons.get(serviceType);
- }
-
- <T> void setSingleton(Class<T> type, T instance) {
- LOG.info("Caching singleton for " + type.getName() + " and classloader: " +
- getClassLoader().toString() + ": " + instance);
- this.singletons.put(type, instance);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/03a58b64/src/main/java/org/apache/tamaya/clsupport/internal/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/package-info.java b/src/main/java/org/apache/tamaya/clsupport/internal/package-info.java
deleted file mode 100644
index 3949b74..0000000
--- a/src/main/java/org/apache/tamaya/clsupport/internal/package-info.java
+++ /dev/null
@@ -1,22 +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.
- */
-/**
- * Contains the provided implementation classes for the classloader support module.
- */
-package org.apache.tamaya.clsupport.internal;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/03a58b64/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
----------------------------------------------------------------------
diff --git a/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext b/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
index c3b6acd..7016afb 100644
--- a/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
+++ b/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
@@ -16,4 +16,4 @@
# specific language governing permissions and limitations
# under the License.
#
-org.apache.tamaya.clsupport.internal.CLAwareServiceContext
+org.apache.tamaya.clsupport.CLAwareServiceContext
[23/23] incubator-tamaya-sandbox git commit: Moved the
classloader-support to the sandbox. It won't be part of the official
extensions.
Posted by pl...@apache.org.
Moved the classloader-support to the sandbox. It won't be part of the official extensions.
Merge branch 'master' of /Users/obf/tamaya-splitted/tamaya-backup
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/30633b6e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/30633b6e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/30633b6e
Branch: refs/heads/master
Commit: 30633b6e691413eed6d486c34cd1394fbae33e6c
Parents: 7acfa80 510070e
Author: Oliver B. Fischer <pl...@apache.org>
Authored: Sun Sep 25 23:34:38 2016 +0200
Committer: Oliver B. Fischer <pl...@apache.org>
Committed: Sun Sep 25 23:34:38 2016 +0200
----------------------------------------------------------------------
pom.xml | 74 +++++
.../AbstractClassloaderAwareItemLoader.java | 268 ++++++++++++++++
.../clsupport/CLAwareConfigurationContext.java | 105 +++++++
.../tamaya/clsupport/CLAwareServiceContext.java | 248 +++++++++++++++
.../tamaya/clsupport/ServiceContainer.java | 306 +++++++++++++++++++
.../apache/tamaya/clsupport/package-info.java | 22 ++
.../org.apache.tamaya.spi.ServiceContext | 19 ++
...he.tamaya.environment.spi.ContextProviderSpi | 23 ++
...org.apache.tamaya.environment.spi.ContextSpi | 19 ++
9 files changed, 1084 insertions(+)
----------------------------------------------------------------------
[03/23] incubator-tamaya-sandbox git commit: TAMAYA-113: Remove Java
8 related parts - basic work done.
Posted by pl...@apache.org.
TAMAYA-113: Remove Java 8 related parts - basic work done.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/87d5224b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/87d5224b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/87d5224b
Branch: refs/heads/master
Commit: 87d5224b4a7bc9696d78359053935f8351f9547e
Parents: 6e6419c
Author: anatole <an...@apache.org>
Authored: Tue Sep 29 01:31:22 2015 +0200
Committer: anatole <an...@apache.org>
Committed: Tue Sep 29 01:31:26 2015 +0200
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/87d5224b/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 4aef40b..251bf64 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,7 +41,7 @@ under the License.
<dependencies>
<dependency>
<groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-java7-api</artifactId>
+ <artifactId>tamaya-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
[22/23] incubator-tamaya-sandbox git commit: TAMAYA-148 Removed
existing tests,
to be replaced by pax-exam. Added a karaf integration layer to generate an
aggregate features.xml
Posted by pl...@apache.org.
TAMAYA-148 Removed existing tests, to be replaced by pax-exam. Added a karaf integration layer to generate an aggregate features.xml
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/510070ea
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/510070ea
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/510070ea
Branch: refs/heads/master
Commit: 510070ea47b2993df3fb8d13e31dae1a60af0f19
Parents: 7b3b5ec
Author: John D. Ament <jo...@apache.org>
Authored: Sat Apr 30 07:30:14 2016 -0400
Committer: John D. Ament <jo...@apache.org>
Committed: Sat Apr 30 07:30:14 2016 -0400
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/510070ea/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1d27df4..adea1d3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,4 +1,4 @@
-<!--
+<!--
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
[21/23] incubator-tamaya-sandbox git commit: Set new development
version.
Posted by pl...@apache.org.
Set new development version.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/7b3b5ec7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/7b3b5ec7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/7b3b5ec7
Branch: refs/heads/master
Commit: 7b3b5ec714e625ee41fbbf1612ebf1a540a8a2d2
Parents: ecd3cdc
Author: anatole <an...@apache.org>
Authored: Thu Apr 14 00:47:11 2016 +0200
Committer: anatole <an...@apache.org>
Committed: Thu Apr 14 00:47:11 2016 +0200
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/7b3b5ec7/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 82bbd15..1d27df4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-extensions</artifactId>
- <version>0.2-incubating</version>
+ <version>0.3-incubating-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
[17/23] incubator-tamaya-sandbox git commit: [maven-release-plugin]
prepare release tamaya-all-0.2-incubating
Posted by pl...@apache.org.
[maven-release-plugin] prepare release tamaya-all-0.2-incubating
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/f1763726
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/f1763726
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/f1763726
Branch: refs/heads/master
Commit: f1763726764a606f2391749c506dd3fc24a9364c
Parents: 08bc448
Author: anatole <an...@apache.org>
Authored: Wed Mar 16 16:20:07 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Wed Mar 16 16:20:07 2016 +0100
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/f1763726/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 24322dd..82bbd15 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-extensions</artifactId>
- <version>0.2-incubating-SNAPSHOT</version>
+ <version>0.2-incubating</version>
<relativePath>..</relativePath>
</parent>
[10/23] incubator-tamaya-sandbox git commit: Fixed further issues
from quality gates.
Posted by pl...@apache.org.
Fixed further issues from quality gates.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/8c370a7f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/8c370a7f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/8c370a7f
Branch: refs/heads/master
Commit: 8c370a7fa1db404de0179eb4a8db9f291cb2e99d
Parents: 8def21e
Author: anatole <an...@apache.org>
Authored: Sun Jan 10 02:14:41 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Sun Jan 10 02:14:41 2016 +0100
----------------------------------------------------------------------
.../AbstractClassloaderAwareItemLoader.java | 4 ++--
.../clsupport/CLAwareConfigurationContext.java | 2 +-
.../apache/tamaya/clsupport/ServiceContainer.java | 15 +++++----------
3 files changed, 8 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/8c370a7f/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java b/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
index 775d778..0145d1f 100644
--- a/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
+++ b/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
@@ -49,7 +49,7 @@ public abstract class AbstractClassloaderAwareItemLoader<T> {
/**
* The items managed, related to their classloader.
*/
- private Map<String, T> items = new ConcurrentHashMap<>();
+ private final Map<String, T> items = new ConcurrentHashMap<>();
/**
* Creates a new instance, using the current Thread context classloader, or - if null - the classloader that
@@ -115,7 +115,7 @@ public abstract class AbstractClassloaderAwareItemLoader<T> {
* Creates a new item for being stored linked with the given lassloader.
*
* @param classLoader the classloader, not null.
- * @return
+ * @return the new item loaded.
*/
protected abstract T createItem(ClassLoader classLoader);
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/8c370a7f/src/main/java/org/apache/tamaya/clsupport/CLAwareConfigurationContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/CLAwareConfigurationContext.java b/src/main/java/org/apache/tamaya/clsupport/CLAwareConfigurationContext.java
index 47b78b2..94e5fb5 100644
--- a/src/main/java/org/apache/tamaya/clsupport/CLAwareConfigurationContext.java
+++ b/src/main/java/org/apache/tamaya/clsupport/CLAwareConfigurationContext.java
@@ -41,7 +41,7 @@ public class CLAwareConfigurationContext implements ConfigurationContext {
/** The logger used. */
private final static Logger LOG = Logger.getLogger(CLAwareConfigurationContext.class.getName());
- private ContextManager contextManager = new ContextManager();
+ private final ContextManager contextManager = new ContextManager();
@Override
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/8c370a7f/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java b/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java
index 1eea749..23e73c0 100644
--- a/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java
+++ b/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java
@@ -39,7 +39,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
- * Created by Anatole on 08.09.2015.
+ * Classloader managed ServiceContainer.
*/
class ServiceContainer {
@@ -50,7 +50,7 @@ class ServiceContainer {
// The access control context taken when the ServiceLoader is created
private final AccessControlContext acc;
- private WeakReference<ClassLoader> classLoaderRef;
+ private final WeakReference<ClassLoader> classLoaderRef;
/**
* List current services loaded using this classloader, per class.
@@ -82,7 +82,7 @@ class ServiceContainer {
public <T> void loadServices(Class<?> type,
Collection<ServiceContainer> preceedingContainers) {
- Map<String, Object> services = (Map<String, Object>) this.servicesLoaded.get(type);
+ Map<String, Object> services = this.servicesLoaded.get(type);
if (services == null) {
services = new LinkedHashMap<>();
this.servicesLoaded.put(type, services);
@@ -100,7 +100,6 @@ class ServiceContainer {
for (ServiceContainer cont : preceedingContainers) {
if (cont.containsService(type, s)) {
LOG.finest("Ignoring duplicate service: " + s);
- continue;
}
}
LOG.info("Loading component: " + s);
@@ -133,10 +132,7 @@ class ServiceContainer {
private boolean containsService(Class<?> type, String serviceClassName) {
Map<String, Object> services = servicesLoaded.get(type);
- if (services == null) {
- return false;
- }
- return services.containsKey(serviceClassName);
+ return services != null && services.containsKey(serviceClassName);
}
@@ -154,8 +150,7 @@ class ServiceContainer {
"Provider " + className + " not a subtype");
}
try {
- S p = serviceType.cast(c.newInstance());
- return p;
+ return serviceType.cast(c.newInstance());
} catch (Throwable x) {
fail(serviceType,
"Provider " + className + " could not be instantiated",
[12/23] incubator-tamaya-sandbox git commit: [maven-release-plugin]
prepare release 0.2-incubating
Posted by pl...@apache.org.
[maven-release-plugin] prepare release 0.2-incubating
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/3f364605
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/3f364605
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/3f364605
Branch: refs/heads/master
Commit: 3f364605f699dfea972a2b250bbdc180418c2efc
Parents: f37fcb3
Author: anatole <an...@apache.org>
Authored: Tue Mar 8 17:39:55 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Tue Mar 8 17:39:55 2016 +0100
----------------------------------------------------------------------
pom.xml | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/3f364605/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 5f8eeb5..82bbd15 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,14 +16,13 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-extensions</artifactId>
- <version>0.2-incubating-SNAPSHOT</version>
+ <version>0.2-incubating</version>
<relativePath>..</relativePath>
</parent>
[04/23] incubator-tamaya-sandbox git commit: TAMAYA-123: Adding OSGI
Support.
Posted by pl...@apache.org.
TAMAYA-123: Adding OSGI Support.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/351d2051
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/351d2051
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/351d2051
Branch: refs/heads/master
Commit: 351d2051effcce2813bed316927a49e9d8c3d52a
Parents: 87d5224
Author: anatole <an...@apache.org>
Authored: Fri Oct 16 19:15:21 2015 +0200
Committer: anatole <an...@apache.org>
Committed: Fri Oct 16 19:15:21 2015 +0200
----------------------------------------------------------------------
pom.xml | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/351d2051/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 251bf64..953875d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,7 +32,7 @@ under the License.
<description>Apache Tamaya Classloader Support registers a ConfigurationContext that leverages
classloader hierarchies. Also visibility of features and components is aligned with the
corresponding hierarchy of classloaders.</description>
- <packaging>jar</packaging>
+ <packaging>bundle</packaging>
<properties>
<jdkVersion>1.7</jdkVersion>
@@ -45,9 +45,31 @@ under the License.
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-spisupport</artifactId>
+ <version>0.2-incubating-SNAPSHOT</version>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.tamaya.clsupport
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
</project>
[08/23] incubator-tamaya-sandbox git commit: Fixed all Javadoc
problems for now...
Posted by pl...@apache.org.
Fixed all Javadoc problems for now...
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/f4f89d37
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/f4f89d37
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/f4f89d37
Branch: refs/heads/master
Commit: f4f89d370c76c9b0b59f352a088154dcee935e66
Parents: 03a58b6
Author: Oliver B. Fischer <pl...@apache.org>
Authored: Fri Jan 1 23:58:57 2016 +0100
Committer: Oliver B. Fischer <pl...@apache.org>
Committed: Fri Jan 1 23:58:57 2016 +0100
----------------------------------------------------------------------
.../clsupport/AbstractClassloaderAwareItemLoader.java | 13 +++++++------
.../tamaya/clsupport/CLAwareServiceContext.java | 14 ++++++++------
2 files changed, 15 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/f4f89d37/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java b/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
index 0c90653..775d778 100644
--- a/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
+++ b/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
@@ -30,13 +30,15 @@ import java.util.logging.Logger;
/**
- * This class implements an abstract base class, which basically provides a loading mechanism that supports
+ * <p>This class implements an abstract base class, which basically provides a loading mechanism that supports
* loading and managing resources along the classloader hierarchies individually. It ensures resources are loaded
* and stored related to the each target classloader within the hierarchy individually. Additionally it enables
- * mechanisms to ensure an item T is not loaded multiple times, when traversing up the classloader hierarchy.<p/>
- * Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected.
+ * mechanisms to ensure an item T is not loaded multiple times, when traversing up the classloader hierarchy.</p>
+ *
+ * <p>Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected.
* Instead this class uses the fully qualified class name of the loader and the corresponsing hashCode as returned
- * by {@link Objects#hashCode(Object)}.
+ * by {@link Objects#hashCode(Object)}.</p>
+ *
* @param <T> the managed item type.
*/
public abstract class AbstractClassloaderAwareItemLoader<T> {
@@ -122,7 +124,6 @@ public abstract class AbstractClassloaderAwareItemLoader<T> {
*
* @param currentItemSet the current found ItemContainer instance to be updated.
* @param classLoader the classloader, not null.
- * @return
*/
protected abstract void updateItem(T currentItemSet, ClassLoader classLoader);
@@ -131,7 +132,7 @@ public abstract class AbstractClassloaderAwareItemLoader<T> {
* This prevents the storage of classloader references as keys and therefore enables classloaders not used anymore
* to be garbage collected.
*
- * @param classLoader
+ * @param classLoader {@link ClassLoader} to be identified, must not be {@code null}.
* @return the unique key for the given classloader
*/
public static String getClassLoaderID(ClassLoader classLoader) {
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/f4f89d37/src/main/java/org/apache/tamaya/clsupport/CLAwareServiceContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/CLAwareServiceContext.java b/src/main/java/org/apache/tamaya/clsupport/CLAwareServiceContext.java
index 392d8b1..a5d1700 100644
--- a/src/main/java/org/apache/tamaya/clsupport/CLAwareServiceContext.java
+++ b/src/main/java/org/apache/tamaya/clsupport/CLAwareServiceContext.java
@@ -32,16 +32,18 @@ import java.util.logging.Logger;
/**
- * This class implements a {@link ServiceContext}, which basically provides a similar loading mechanism as used
+ * <p>This class implements a {@link ServiceContext}, which basically provides a similar loading mechanism as used
* by the {@link java.util.ServiceLoader}. Whereas the {@link java.util.ServiceLoader} only loads configurations
* and instances from one classloader, this loader manages configs found and the related instances for each
* classloader along the classloader hierarchies individually. It ensures instances are loaded on the classloader
* level, where they first are visible. Additionally it ensures the same configuration resource (and its
- * declared services) are loaded multiple times, when going up the classloader hierarchy.<p/>
- * Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected.
- * Refer also the inherited parent class for further details.<p/>
- * This class uses an ordinal of {@code 10}, so it overrides any default {@link ServiceContext} implementations
- * provided with the Tamaya core modules.
+ * declared services) are loaded multiple times, when going up the classloader hierarchy.</p>
+ *
+ * <p>Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected.
+ * Refer also the inherited parent class for further details.</p>
+ *
+ * <p>This class uses an ordinal of {@code 10}, so it overrides any default {@link ServiceContext} implementations
+ * provided with the Tamaya core modules.</p>
*/
@Priority(10)
public class CLAwareServiceContext extends AbstractClassloaderAwareItemLoader<ServiceContainer>
[09/23] incubator-tamaya-sandbox git commit: Cleanup of version
informations in the POMs.
Posted by pl...@apache.org.
Cleanup of version informations in the POMs.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/8def21e6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/8def21e6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/8def21e6
Branch: refs/heads/master
Commit: 8def21e675119743bcf73330c46f21f4d545c39e
Parents: f4f89d3
Author: Oliver B. Fischer <pl...@apache.org>
Authored: Sat Jan 2 15:40:37 2016 +0100
Committer: Oliver B. Fischer <pl...@apache.org>
Committed: Sat Jan 2 15:40:37 2016 +0100
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/8def21e6/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 953875d..1b593d4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,7 +47,7 @@ under the License.
<dependency>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-spisupport</artifactId>
- <version>0.2-incubating-SNAPSHOT</version>
+ <version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
[05/23] incubator-tamaya-sandbox git commit: TAMAYA-124: Unifying
annotations for SE and EE based injection.
Posted by pl...@apache.org.
TAMAYA-124: Unifying annotations for SE and EE based injection.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/32235c49
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/32235c49
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/32235c49
Branch: refs/heads/master
Commit: 32235c493c05a4190a4a1d2291f7309f01cf2fcc
Parents: 351d205
Author: anatole <an...@apache.org>
Authored: Fri Oct 16 19:31:25 2015 +0200
Committer: anatole <an...@apache.org>
Committed: Fri Oct 16 19:31:25 2015 +0200
----------------------------------------------------------------------
.../tamaya/clsupport/spi/package-info.java | 22 --------------------
1 file changed, 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/32235c49/src/main/java/org/apache/tamaya/clsupport/spi/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/spi/package-info.java b/src/main/java/org/apache/tamaya/clsupport/spi/package-info.java
deleted file mode 100644
index 6eb85d3..0000000
--- a/src/main/java/org/apache/tamaya/clsupport/spi/package-info.java
+++ /dev/null
@@ -1,22 +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.
- */
-/**
- * Defines the SPI of the classloader support module.
- */
-package org.apache.tamaya.clsupport.spi;
\ No newline at end of file
[14/23] incubator-tamaya-sandbox git commit: [maven-release-plugin]
prepare release 0.2-incubating-rc1
Posted by pl...@apache.org.
[maven-release-plugin] prepare release 0.2-incubating-rc1
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/c775209b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/c775209b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/c775209b
Branch: refs/heads/master
Commit: c775209b65f7b5b3feb81ab773340a9d79d7d2aa
Parents: fcf04cf
Author: anatole <an...@apache.org>
Authored: Tue Mar 8 20:39:05 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Tue Mar 8 20:39:05 2016 +0100
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/c775209b/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1d27df4..82bbd15 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-extensions</artifactId>
- <version>0.3-incubating-SNAPSHOT</version>
+ <version>0.2-incubating</version>
<relativePath>..</relativePath>
</parent>
[18/23] incubator-tamaya-sandbox git commit: [maven-release-plugin]
prepare for next development iteration
Posted by pl...@apache.org.
[maven-release-plugin] prepare for next development iteration
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/762d307a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/762d307a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/762d307a
Branch: refs/heads/master
Commit: 762d307aa076e66452afd0b62123abcd8d7d8358
Parents: f176372
Author: anatole <an...@apache.org>
Authored: Wed Mar 16 16:20:17 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Wed Mar 16 16:20:17 2016 +0100
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/762d307a/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 82bbd15..1d27df4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-extensions</artifactId>
- <version>0.2-incubating</version>
+ <version>0.3-incubating-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
[16/23] incubator-tamaya-sandbox git commit: Reset version for new
release run.
Posted by pl...@apache.org.
Reset version for new release run.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/08bc448e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/08bc448e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/08bc448e
Branch: refs/heads/master
Commit: 08bc448e48593da1d878fb3ecf7e65a421ac876c
Parents: 1f6177f
Author: anatole <an...@apache.org>
Authored: Wed Mar 9 14:09:25 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Wed Mar 9 14:09:25 2016 +0100
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/08bc448e/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1d27df4..24322dd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-extensions</artifactId>
- <version>0.3-incubating-SNAPSHOT</version>
+ <version>0.2-incubating-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>