All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.glassfish.jersey.internal.ServiceProviders Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2010-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.glassfish.jersey.internal;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.glassfish.jersey.internal.inject.Providers;
import org.glassfish.jersey.internal.util.ReflectionHelper;
import org.glassfish.hk2.Services;
import org.jvnet.hk2.annotations.Inject;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
/**
* Combines access to custom provider classes and instances
* and providers registered via a HK2 module or Java Service Provider mechanism
* ({@code META-INF/services}).
*
* @author Paul Sandoz
* @author Marek Potociar (marek.potociar at oracle.com)
*/
public class ServiceProviders {
/**
* Service providers builder.
*/
public static final class Builder {
private final Services services;
private Set> classes;
private Set instances;
/**
* Injection constructor.
*
* @param services HK2 services to be used for service providers lookup.
*/
public Builder(@Inject Services services) {
this.services = services;
}
/**
* Set custom service provider classes that will take precedence over the default
* service providers provided by the underlying HK2 services.
*
* @param classes custom service classes.
* @return the updated builder instance.
*/
public Builder setProviderClasses(Set> classes) {
this.classes = classes;
return this;
}
/**
* Set custom service provider instances that will take precedence over the default
* service providers provided by the underlying HK2 services.
*
* @param instances custom service provider instances.
* @return the updated builder instance.
*/
public Builder setProviderInstances(Set instances) {
this.instances = instances;
return this;
}
/**
* Build service providers.
*
* @return configured service providers.
*/
public ServiceProviders build() {
return new ServiceProviders(services, classes, instances);
}
}
//
private static final Logger LOGGER = Logger.getLogger(ServiceProviders.class.getName());
//
private final Services services;
private final Set> providerClasses;
private final Set providerInstances;
private ServiceProviders(final Services services, final Set> classes, final Set instances) {
this.services = services;
this.providerClasses = Collections.unmodifiableSet(Sets.newHashSet(classes == null ? Collections.>emptySet() : classes));
this.providerInstances = Collections.unmodifiableSet(Sets.newHashSet(instances == null ? Collections.emptySet() : instances));
}
/**
* Get all provider instances of the requested provider type from the list of internally
* registered provider instances and classes. This method does not perform
* service provider lookup in {@code META-INF/services}.
*
* @param provider Java type.
* @param providerContract provider contract class.
* @return instances of all internally registered providers of the given
* provider type.
*/
public Set getCustom(Class providerContract) {
Set result = new LinkedHashSet(getCustomInstances(providerContract));
for (Class pc : providerClasses) {
if (providerContract.isAssignableFrom(pc)) {
Object o = getComponent(pc);
if (o != null) {
result.add(providerContract.cast(o));
}
}
}
return result;
}
/**
* Get all provider instances of the requested provider type from the list of internally
* registered provider instances and classes. This method does not perform
* service provider lookup in {@code META-INF/services}.
*
* The returned provider list, if not empty, is sorted using the supplied
* {@link Comparator comparator} before it is returned.
*
* @param provider Java type.
* @param providerContract provider contract class.
* @param comparator contract comparator used for ordering provider instances
* in the set.
* @return sorted list of instances of all internally registered providers of
* the given provider type.
*/
public List getCustom(Class providerContract, final Comparator comparator) {
final List providers = Lists.newArrayList(getDefault(providerContract));
Collections.sort(providers, comparator);
return providers;
}
/**
* Get all provider instances of the requested provider type found by performing
* service provider lookup in {@code META-INF/services}. This method ignores any
* internally registered provider instances or classes.
*
* @param provider Java type.
* @param providerContract provider contract class.
* @return instances of all providers of the given provider type found
* during the service provider lookup.
*/
public Set getDefault(Class providerContract) {
return Providers.getProviders(services, providerContract);
}
/**
* Get all provider instances of the requested provider type found by performing
* service provider lookup in {@code META-INF/services}. This method ignores any
* internally registered provider instances or classes.
*
* The returned provider list, if not empty, is sorted using the supplied
* {@link Comparator comparator} before it is returned.
*
* @param provider Java type.
* @param providerContract provider contract class.
* @param comparator contract comparator used for ordering provider instances
* in the set.
* @return sorted list of instances of all providers of the given provider type
* found during the service provider lookup.
*/
public List getDefault(Class providerContract, final Comparator comparator) {
final List providers = Lists.newArrayList(getDefault(providerContract));
Collections.sort(providers, comparator);
return providers;
}
/**
* Get all provider instances of the requested provider type found both
* in the internal storage as well as by performing service provider lookup
* in {@code META-INF/services}. This method returns a result that is a
* combination of the results returned by {@link #getCustom(java.lang.Class)}
* and {@link #getDefault(java.lang.Class)}.
*
* @param provider Java type.
* @param providerContract provider contract class.
* @return instances of all providers of the given provider type found both
* in the internal storage as well as during the service provider lookup.
*/
public Set getAll(Class providerContract) {
Set result = new LinkedHashSet(getCustom(providerContract));
result.addAll(getDefault(providerContract));
return result;
}
/**
* Get all provider instances of the requested provider type found both
* in the internal storage as well as by performing service provider lookup
* in {@code META-INF/services}. This method returns a result that is a
* combination of the results returned by {@link #getCustom(java.lang.Class)}
* and {@link #getDefault(java.lang.Class)}.
*
* The returned provider list, if not empty, is sorted using the supplied
* {@link Comparator comparator} before it is returned.
*
* @param provider Java type.
* @param providerContract provider contract class.
* @param comparator contract comparator used for ordering provider instances
* in the set.
* @return sorted list of instances of all providers of the given provider type
* found both in the internal storage as well as during the service provider
* lookup.
*/
public List getAll(Class providerContract, final Comparator comparator) {
final List providers = Lists.newArrayList(getAll(providerContract));
Collections.sort(providers, comparator);
return providers;
}
/**
* Asynchronous callback interface for handling all the service providers of
* a given contract type.
*
* @param
*/
public static interface ServiceListener {
/**
* Invoked whenever a new provider instance of the given type has been found.
*
* @param service most recently found provider instance.
*/
public void onAdd(T service);
}
/**
* Get all provider instances of the requested provider type from the list of
* internally registered provider instances and classes. This method does not
* perform service provider lookup in {@code META-INF/services}.
*
* Rather than returning the list of found provider instances, the method
* {@link ServiceListener#onAdd(java.lang.Object) invokes} the supplied provider
* listener for every provider instance that matches the requested provider
* type.
*
* @param provider Java type.
* @param providerContract provider contract class.
* @param listener provider listener invoked with every matched provider instance.
*/
public void getCustom(Class providerContract, ServiceListener listener) {
for (T t : getCustom(providerContract)) {
listener.onAdd(t);
}
}
/**
* Get all provider instances of the requested provider type found both
* in the internal storage as well as by performing service provider lookup
* in {@code META-INF/services}.
*
* Rather than returning the list of found provider instances, the method
* {@link ServiceListener#onAdd(java.lang.Object) invokes} the supplied provider
* listener for every provider instance that matches the requested provider
* type.
*
* @param provider Java type.
* @param providerContract provider contract class.
* @param listener provider listener invoked with every matched provider instance.
*/
public void getAll(Class providerContract, ServiceListener listener) {
for (T t : getCustom(providerContract)) {
listener.onAdd(t);
}
for (T t : getDefault(providerContract)) {
listener.onAdd(t);
}
}
/**
* Instantiate providers of the given type using the array of provider implementation
* class names.
*
* Note that this method does not fail in case any of the implementation classes
* cannot be found or instantiated or if it does not match the requested provider
* type. Instead, a {@link Level#SEVERE severe} log entry is recorded and the
* failing implementation class is ignored and not included in the returned
* list of provider instances.
*
* @param requested provider Java type.
* @param providerContract provider contract class.
* @param classNames provider implementation class names.
* @return provider instances instantiated from the supplied provider implementation
* class names.
*/
public List instantiate(Class providerContract, String[] classNames) {
List ps = new LinkedList();
for (String className : classNames) {
try {
Class c = ReflectionHelper.classForNameWithException(className);
if (providerContract.isAssignableFrom(c)) {
Object o = getComponent(c);
if (o != null) {
ps.add(providerContract.cast(o));
}
} else {
LOGGER.log(Level.SEVERE,
"The class {0} is not assignable to the class {1}. This class is ignored.",
new Object[]{className, providerContract.getName()});
}
} catch (ClassNotFoundException e) {
LOGGER.log(Level.SEVERE, "The class {0}"
+ " could not be found"
+ ". This class is ignored.", className);
}
}
return ps;
}
/**
* Instantiate providers of the given type using the array of provider implementation
* classes.
*
* Note that this method does not fail in case any of the implementation classes
* cannot be instantiated or if it does not match the requested provider type.
* Instead, a {@link Level#SEVERE severe} log entry is recorded and the failing
* implementation class is ignored and not included in the returned list of
* provider instances.
*
* @param requested provider Java type.
* @param providerContract provider contract class.
* @param classes provider implementation classes.
* @return provider instances instantiated from the supplied provider implementation
* class names.
*/
public List instantiate(Class providerContract, Class[] classes) {
List ps = new LinkedList();
for (Class c : classes) {
Object o = getComponent(c);
if (o != null) {
ps.add(providerContract.cast(o));
}
}
return ps;
}
private Object getComponent(Class provider) {
try {
return services.byType(provider).get();
} catch (Exception ex) {
LOGGER.log(Level.WARNING, "Component instantiation failed.", ex);
return null;
}
}
private Set getCustomInstances(final Class contract) {
Set sp = new LinkedHashSet();
for (Object p : providerInstances) {
if (contract.isInstance(p)) {
sp.add(contract.cast(p));
}
}
return sp;
}
}