Repository: incubator-tamaya-extensions Updated Branches: refs/heads/master a35fb2a0b -> a8b7f757e
TAMAYA-210: Added additional resource location logic. Tested and implemented especially with OSGI. Added create method. Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/commit/9e4991b6 Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/tree/9e4991b6 Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/diff/9e4991b6 Branch: refs/heads/master Commit: 9e4991b63ba223e57b9736c89d0e0441245632b7 Parents: a35fb2a Author: anatole <anat...@apache.org> Authored: Wed Dec 21 16:50:23 2016 +0100 Committer: anatole <anat...@apache.org> Committed: Wed Dec 21 16:50:23 2016 +0100 ---------------------------------------------------------------------- modules/injection/cdi-ee/pom.xml | 5 ++ .../integration/cdi/CDIAwareServiceContext.java | 45 ++++++++++- .../cdi/ServiceLoaderServiceContext.java | 82 +++++++++++++++----- .../integration/cdi/CDIAwareServiceContext.java | 45 ++++++++++- .../cdi/ServiceLoaderServiceContext.java | 73 +++++++++++++---- .../resolver/internal/ResourceResolver.java | 3 +- .../internal/ClassPathResourceLocator.java | 4 +- .../resource/internal/ClasspathCollector.java | 5 +- .../spisupport/DefaultConfigurationContext.java | 2 +- 9 files changed, 217 insertions(+), 47 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/9e4991b6/modules/injection/cdi-ee/pom.xml ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/pom.xml b/modules/injection/cdi-ee/pom.xml index 89f05f9..c16b3a7 100644 --- a/modules/injection/cdi-ee/pom.xml +++ b/modules/injection/cdi-ee/pom.xml @@ -73,6 +73,11 @@ under the License. <scope>provided</scope> </dependency> <dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-spisupport</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> <groupId>org.apache.openejb</groupId> <artifactId>javaee-api</artifactId> <version>${javaee-api.version}</version> http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/9e4991b6/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java index 5bfb1c1..8c1312f 100644 --- a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java +++ b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java @@ -25,12 +25,13 @@ import javax.annotation.Priority; import javax.enterprise.inject.Instance; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; +import java.io.IOException; +import java.net.URL; import java.text.MessageFormat; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; /** @@ -100,6 +101,42 @@ public class CDIAwareServiceContext implements ServiceContext { return found; } + @Override + public <T> T create(Class<T> serviceType) { + T serv = getService(serviceType); + if(serv!=null){ + try { + return (T)serv.getClass().newInstance(); + } catch (Exception e) { + Logger.getLogger(getClass().getName()) + .log(Level.SEVERE, "Failed to create new instance of: " +serviceType.getName(), e); + } + } + return null; + } + + @Override + public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException { + if(cl==null){ + cl = Thread.currentThread().getContextClassLoader(); + } + if(cl==null){ + cl = getClass().getClassLoader(); + } + return cl.getResources(resource); + } + + @Override + public URL getResource(String resource, ClassLoader cl) { + if(cl==null){ + cl = Thread.currentThread().getContextClassLoader(); + } + if(cl==null){ + cl = getClass().getClassLoader(); + } + return cl.getResource(resource); + } + /** * 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); http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/9e4991b6/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java index 5171d91..4b82429 100644 --- a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java +++ b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java @@ -20,10 +20,20 @@ package org.apache.tamaya.integration.cdi; import org.apache.tamaya.ConfigException; import org.apache.tamaya.spi.ServiceContext; +import org.apache.tamaya.spisupport.PriorityServiceComparator; import javax.annotation.Priority; +import java.io.IOException; +import java.net.URL; import java.text.MessageFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; +import java.util.ServiceConfigurationError; +import java.util.ServiceLoader; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; @@ -33,6 +43,7 @@ import java.util.logging.Logger; * {@link ServiceLoader} to load the services required. */ final class ServiceLoaderServiceContext implements ServiceContext { + private static final Logger LOG = Logger.getLogger(ServiceLoaderServiceContext.class.getName()); /** * List current services loaded, per class. */ @@ -41,17 +52,13 @@ final class ServiceLoaderServiceContext implements ServiceContext { * Singletons. */ private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>(); + private Map<Class, Class> factoryTypes = new ConcurrentHashMap<>(); @Override public <T> T getService(Class<T> serviceType) { Object cached = singletons.get(serviceType); if (cached == null) { - Collection<T> services = getServices(serviceType); - if (services.isEmpty()) { - cached = null; - } else { - cached = getServiceWithHighestPriority(services, serviceType); - } + cached = create(serviceType); if(cached!=null) { singletons.put(serviceType, cached); } @@ -59,6 +66,25 @@ final class ServiceLoaderServiceContext implements ServiceContext { return serviceType.cast(cached); } + @Override + public <T> T create(Class<T> serviceType) { + Class<? extends T> implType = factoryTypes.get(serviceType); + if(implType==null) { + Collection<T> services = getServices(serviceType); + if (services.isEmpty()) { + return null; + } else { + return getServiceWithHighestPriority(services, serviceType); + } + } + try { + return implType.newInstance(); + } catch (Exception e) { + LOG.log(Level.SEVERE, "Failed to create instabce of " + implType.getName(), e); + return null; + } + } + /** * Loads and registers services. * @@ -77,10 +103,14 @@ final class ServiceLoaderServiceContext implements ServiceContext { for (T t : ServiceLoader.load(serviceType)) { services.add(t); } + Collections.sort(services, PriorityServiceComparator.getInstance()); services = Collections.unmodifiableList(services); - } catch (Exception e) { - Logger.getLogger(ServiceLoaderServiceContext.class.getName()).log(Level.WARNING, + } catch (ServiceConfigurationError e) { + LOG.log(Level.WARNING, "Error loading services current type " + serviceType, e); + if(services==null){ + services = Collections.emptyList(); + } } final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services)); return previousServices != null ? previousServices : services; @@ -105,20 +135,21 @@ final class ServiceLoaderServiceContext implements ServiceContext { * @param services to scan * @param <T> type of the service * - * @return the service with the highest {@link Priority#value()} + * @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<T> services, Class<T> serviceType) { - + T highestService = null; // we do not need the priority stuff if the list contains only one element if (services.size() == 1) { - return services.iterator().next(); + highestService = services.iterator().next(); + this.factoryTypes.put(serviceType, highestService.getClass()); + return highestService; } Integer highestPriority = null; int highestPriorityServiceCount = 0; - T highestService = null; for (T service : services) { int prio = getPriority(service); @@ -133,12 +164,12 @@ final class ServiceLoaderServiceContext implements ServiceContext { if (highestPriorityServiceCount > 1) { throw new ConfigException(MessageFormat.format("Found {0} implementations for Service {1} with Priority {2}: {3}", - highestPriorityServiceCount, - serviceType.getName(), - highestPriority, - services)); + highestPriorityServiceCount, + serviceType.getName(), + highestPriority, + services)); } - + this.factoryTypes.put(serviceType, highestService.getClass()); return highestService; } @@ -147,5 +178,20 @@ final class ServiceLoaderServiceContext implements ServiceContext { return 1; } + @Override + public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException{ + if(cl==null){ + cl = Thread.currentThread().getContextClassLoader(); + } + return cl.getResources(resource); + } + + @Override + public URL getResource(String resource, ClassLoader cl){ + if(cl==null){ + cl = Thread.currentThread().getContextClassLoader(); + } + return cl.getResource(resource); + } } http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/9e4991b6/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java index 566d00e..08c12b7 100644 --- a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java +++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java @@ -25,12 +25,13 @@ import javax.annotation.Priority; import javax.enterprise.inject.Instance; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; +import java.io.IOException; +import java.net.URL; import java.text.MessageFormat; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; /** @@ -74,6 +75,20 @@ public class CDIAwareServiceContext implements ServiceContext { return serviceType.cast(cached); } + @Override + public <T> T create(Class<T> serviceType) { + T serv = getService(serviceType); + if(serv!=null){ + try { + return (T)serv.getClass().newInstance(); + } catch (Exception e) { + Logger.getLogger(getClass().getName()) + .log(Level.SEVERE, "Failed to create new instance of: " +serviceType.getName(), e); + } + } + return null; + } + /** * Loads and registers services. * @@ -100,6 +115,28 @@ public class CDIAwareServiceContext implements ServiceContext { return found; } + @Override + public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException { + if(cl==null){ + cl = Thread.currentThread().getContextClassLoader(); + } + if(cl==null){ + cl = getClass().getClassLoader(); + } + return cl.getResources(resource); + } + + @Override + public URL getResource(String resource, ClassLoader cl) { + if(cl==null){ + cl = Thread.currentThread().getContextClassLoader(); + } + if(cl==null){ + cl = getClass().getClassLoader(); + } + return cl.getResource(resource); + } + /** * 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); http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/9e4991b6/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java index 5171d91..1de0655 100644 --- a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java +++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java @@ -20,8 +20,11 @@ package org.apache.tamaya.integration.cdi; import org.apache.tamaya.ConfigException; import org.apache.tamaya.spi.ServiceContext; +import org.apache.tamaya.spisupport.PriorityServiceComparator; import javax.annotation.Priority; +import java.io.IOException; +import java.net.URL; import java.text.MessageFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -33,6 +36,7 @@ import java.util.logging.Logger; * {@link ServiceLoader} to load the services required. */ final class ServiceLoaderServiceContext implements ServiceContext { + private static final Logger LOG = Logger.getLogger(ServiceLoaderServiceContext.class.getName()); /** * List current services loaded, per class. */ @@ -41,17 +45,13 @@ final class ServiceLoaderServiceContext implements ServiceContext { * Singletons. */ private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>(); + private Map<Class, Class> factoryTypes = new ConcurrentHashMap<>(); @Override public <T> T getService(Class<T> serviceType) { Object cached = singletons.get(serviceType); if (cached == null) { - Collection<T> services = getServices(serviceType); - if (services.isEmpty()) { - cached = null; - } else { - cached = getServiceWithHighestPriority(services, serviceType); - } + cached = create(serviceType); if(cached!=null) { singletons.put(serviceType, cached); } @@ -59,6 +59,25 @@ final class ServiceLoaderServiceContext implements ServiceContext { return serviceType.cast(cached); } + @Override + public <T> T create(Class<T> serviceType) { + Class<? extends T> implType = factoryTypes.get(serviceType); + if(implType==null) { + Collection<T> services = getServices(serviceType); + if (services.isEmpty()) { + return null; + } else { + return getServiceWithHighestPriority(services, serviceType); + } + } + try { + return implType.newInstance(); + } catch (Exception e) { + LOG.log(Level.SEVERE, "Failed to create instabce of " + implType.getName(), e); + return null; + } + } + /** * Loads and registers services. * @@ -77,10 +96,14 @@ final class ServiceLoaderServiceContext implements ServiceContext { for (T t : ServiceLoader.load(serviceType)) { services.add(t); } + Collections.sort(services, PriorityServiceComparator.getInstance()); services = Collections.unmodifiableList(services); - } catch (Exception e) { - Logger.getLogger(ServiceLoaderServiceContext.class.getName()).log(Level.WARNING, + } catch (ServiceConfigurationError e) { + LOG.log(Level.WARNING, "Error loading services current type " + serviceType, e); + if(services==null){ + services = Collections.emptyList(); + } } final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services)); return previousServices != null ? previousServices : services; @@ -105,20 +128,21 @@ final class ServiceLoaderServiceContext implements ServiceContext { * @param services to scan * @param <T> type of the service * - * @return the service with the highest {@link Priority#value()} + * @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<T> services, Class<T> serviceType) { - + T highestService = null; // we do not need the priority stuff if the list contains only one element if (services.size() == 1) { - return services.iterator().next(); + highestService = services.iterator().next(); + this.factoryTypes.put(serviceType, highestService.getClass()); + return highestService; } Integer highestPriority = null; int highestPriorityServiceCount = 0; - T highestService = null; for (T service : services) { int prio = getPriority(service); @@ -133,12 +157,12 @@ final class ServiceLoaderServiceContext implements ServiceContext { if (highestPriorityServiceCount > 1) { throw new ConfigException(MessageFormat.format("Found {0} implementations for Service {1} with Priority {2}: {3}", - highestPriorityServiceCount, - serviceType.getName(), - highestPriority, - services)); + highestPriorityServiceCount, + serviceType.getName(), + highestPriority, + services)); } - + this.factoryTypes.put(serviceType, highestService.getClass()); return highestService; } @@ -147,5 +171,20 @@ final class ServiceLoaderServiceContext implements ServiceContext { return 1; } + @Override + public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException{ + if(cl==null){ + cl = Thread.currentThread().getContextClassLoader(); + } + return cl.getResources(resource); + } + + @Override + public URL getResource(String resource, ClassLoader cl){ + if(cl==null){ + cl = Thread.currentThread().getContextClassLoader(); + } + return cl.getResource(resource); + } } http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/9e4991b6/modules/resolver/src/main/java/org/apache/tamaya/resolver/internal/ResourceResolver.java ---------------------------------------------------------------------- diff --git a/modules/resolver/src/main/java/org/apache/tamaya/resolver/internal/ResourceResolver.java b/modules/resolver/src/main/java/org/apache/tamaya/resolver/internal/ResourceResolver.java index 270459c..52db593 100644 --- a/modules/resolver/src/main/java/org/apache/tamaya/resolver/internal/ResourceResolver.java +++ b/modules/resolver/src/main/java/org/apache/tamaya/resolver/internal/ResourceResolver.java @@ -124,7 +124,8 @@ public final class ResourceResolver implements ExpressionResolver { List<URL> resources = new ArrayList<>(); Enumeration<URL> found; try { - found = cl.getResources(expression); + found = ServiceContextManager.getServiceContext() + .getResources(expression, cl); } catch (Exception e) { LOG.log(Level.SEVERE, "Error resolving expression: " + expression, e); continue; http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/9e4991b6/modules/resources/src/main/java/org/apache/tamaya/resource/internal/ClassPathResourceLocator.java ---------------------------------------------------------------------- diff --git a/modules/resources/src/main/java/org/apache/tamaya/resource/internal/ClassPathResourceLocator.java b/modules/resources/src/main/java/org/apache/tamaya/resource/internal/ClassPathResourceLocator.java index 5a49d50..35aa4d5 100644 --- a/modules/resources/src/main/java/org/apache/tamaya/resource/internal/ClassPathResourceLocator.java +++ b/modules/resources/src/main/java/org/apache/tamaya/resource/internal/ClassPathResourceLocator.java @@ -19,6 +19,7 @@ package org.apache.tamaya.resource.internal; import org.apache.tamaya.resource.ResourceLocator; +import org.apache.tamaya.spi.ServiceContextManager; import javax.annotation.Priority; import java.io.IOException; @@ -50,7 +51,8 @@ public class ClassPathResourceLocator implements ResourceLocator{ public Collection<URL> lookup(ClassLoader classLoader, String expression) { List<URL> resources = new ArrayList<>(); try { - Enumeration<URL> urls = classLoader.getResources(expression); + Enumeration<URL> urls = ServiceContextManager.getServiceContext() + .getResources(expression, classLoader); while (urls.hasMoreElements()) { URL url = urls.nextElement(); resources.add(url); http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/9e4991b6/modules/resources/src/main/java/org/apache/tamaya/resource/internal/ClasspathCollector.java ---------------------------------------------------------------------- diff --git a/modules/resources/src/main/java/org/apache/tamaya/resource/internal/ClasspathCollector.java b/modules/resources/src/main/java/org/apache/tamaya/resource/internal/ClasspathCollector.java index 4eb6b3e..99ee5c4 100644 --- a/modules/resources/src/main/java/org/apache/tamaya/resource/internal/ClasspathCollector.java +++ b/modules/resources/src/main/java/org/apache/tamaya/resource/internal/ClasspathCollector.java @@ -18,6 +18,8 @@ */ package org.apache.tamaya.resource.internal; +import org.apache.tamaya.spi.ServiceContextManager; + import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationHandler; @@ -113,7 +115,8 @@ public class ClasspathCollector { Locator locator = Locator.of(expression); List<URL> result = new ArrayList<>(); try { - Enumeration<URL> rootResources = this.classLoader.getResources(locator.getRootPath()); + Enumeration<URL> rootResources = ServiceContextManager.getServiceContext() + .getResources(locator.getRootPath(), this.classLoader); while (rootResources.hasMoreElements()) { URL resource = rootResources.nextElement(); try { http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/9e4991b6/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java ---------------------------------------------------------------------- diff --git a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java index ad35452..7b177a2 100644 --- a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java +++ b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java @@ -124,7 +124,7 @@ public class DefaultConfigurationContext implements ConfigurationContext { writeLock.lock(); List<PropertySource> newPropertySources = new ArrayList<>(this.immutablePropertySources); newPropertySources.addAll(Arrays.asList(propertySourcesToAdd)); - Collections.sort(newPropertySources, new PropertySourceComparator()); + Collections.sort(newPropertySources, PropertySourceComparator.getInstance()); this.immutablePropertySources = Collections.unmodifiableList(newPropertySources); } finally {