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:47 UTC
[07/23] incubator-tamaya-sandbox git commit: TAMAYA-123: Adding OSGI
Support: had to move some aspects out of (non-accessible) internal packages.
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