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.hk2.utilities.binding.AbstractBindingBuilder Maven / Gradle / Ivy
/*
* Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.hk2.utilities.binding;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import jakarta.inject.Named;
import org.glassfish.hk2.api.DynamicConfiguration;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.HK2Loader;
import org.glassfish.hk2.api.TypeLiteral;
import org.glassfish.hk2.utilities.AbstractActiveDescriptor;
import org.glassfish.hk2.utilities.ActiveDescriptorBuilder;
import org.glassfish.hk2.utilities.BuilderHelper;
import org.glassfish.hk2.utilities.FactoryDescriptorsImpl;
import org.glassfish.hk2.utilities.reflection.ParameterizedTypeImpl;
import org.glassfish.hk2.utilities.reflection.ReflectionHelper;
import org.jvnet.hk2.component.MultiMap;
/**
* Abstract binding builder implementation.
*
* @param bound service type.
* @author Marek Potociar (marek.potociar at oracle.com)
*/
abstract class AbstractBindingBuilder implements
ServiceBindingBuilder, NamedBindingBuilder, ScopedBindingBuilder, ScopedNamedBindingBuilder {
/**
* Contracts the service should be bound to.
*/
Set contracts = new HashSet();
/**
* Bound service loader.
*/
HK2Loader loader = null;
/**
* Binding metadata (e.g. useful for filtering).
*/
final MultiMap metadata = new MultiMap();
/**
* Qualifiers (other than @Named).
*/
Set qualifiers = new HashSet();
/**
* Binding scope as annotation
*/
Annotation scopeAnnotation = null;
/**
* Binding scope.
*/
Class extends Annotation> scope = null;
/**
* Binding rank.
*/
Integer ranked = null;
/**
* Binding name (see @Named).
*/
String name = null;
/**
* Injectee is proxiable.
*/
Boolean proxiable = null;
/**
* Injectee should be proxied even inside the same scope
*/
Boolean proxyForSameScope = null;
Type implementationType = null;
@Override
public AbstractBindingBuilder proxy(boolean proxiable) {
this.proxiable = proxiable;
return this;
}
@Override
public AbstractBindingBuilder proxyForSameScope(boolean proxyForSameScope) {
this.proxyForSameScope = proxyForSameScope;
return this;
}
/**
* Analyzer to use with this descriptor
*/
String analyzer = null;
@Override
public AbstractBindingBuilder analyzeWith(String analyzer) {
this.analyzer = analyzer;
return this;
}
@Override
public AbstractBindingBuilder to(Class super T> contract) {
contracts.add(contract);
return this;
}
@Override
public AbstractBindingBuilder to(TypeLiteral> contract) {
contracts.add(contract.getType());
return this;
}
@Override
public AbstractBindingBuilder to(Type contract) {
contracts.add(contract);
return this;
}
@Override
public AbstractBindingBuilder loadedBy(HK2Loader loader) {
this.loader = loader;
return this;
}
@Override
public AbstractBindingBuilder withMetadata(String key, String value) {
this.metadata.add(key, value);
return this;
}
@Override
public AbstractBindingBuilder withMetadata(String key, List values) {
for (String value : values) {
this.metadata.add(key,value);
}
return this;
}
@Override
public AbstractBindingBuilder qualifiedBy(Annotation annotation) {
if (Named.class.equals(annotation.annotationType())) {
this.name = ((Named) annotation).value();
}
this.qualifiers.add(annotation);
return this;
}
@Override
public AbstractBindingBuilder in(Annotation scopeAnnotation) {
this.scopeAnnotation = scopeAnnotation;
return this;
}
@Override
public AbstractBindingBuilder in(Class extends Annotation> scopeAnnotation) {
this.scope = scopeAnnotation;
return this;
}
@Override
public AbstractBindingBuilder named(String name) {
this.name = name;
return this;
}
@Override
public void ranked(int rank) {
this.ranked = rank;
}
public AbstractBindingBuilder asType(Type t) {
this.implementationType = t;
return this;
}
/**
* Build the binding descriptor and bind it in the {@link DynamicConfiguration
* dynamic configuration}.
*
* @param configuration dynamic binding configuration.
* @param defaultLoader default HK2 loader that should be used in case a custom loader
* was not set.
*/
abstract void complete(DynamicConfiguration configuration, HK2Loader defaultLoader);
private static class ClassBasedBindingBuilder extends AbstractBindingBuilder {
private final Class service;
public ClassBasedBindingBuilder(Class service, Type serviceContractType) {
this.service = service;
if (serviceContractType != null) {
super.contracts.add(serviceContractType);
}
}
@Override
void complete(final DynamicConfiguration configuration, final HK2Loader defaultLoader) {
if (this.loader == null) {
this.loader = defaultLoader;
}
ActiveDescriptorBuilder builder = BuilderHelper.activeLink(service)
.named(name)
.andLoadWith(this.loader)
.analyzeWith(this.analyzer);
if (scopeAnnotation != null) {
builder.in(scopeAnnotation);
}
if (scope != null) {
builder.in(scope);
}
if (ranked != null) {
builder.ofRank(ranked);
}
for (String key : metadata.keySet()) {
for (String value : metadata.get(key)) {
builder.has(key, value);
}
}
for (Annotation annotation : qualifiers) {
builder.qualifiedBy(annotation);
}
for (Type contract : contracts) {
builder.to(contract);
}
if (proxiable != null) {
builder.proxy(proxiable);
}
if (proxyForSameScope != null) {
builder.proxyForSameScope(proxyForSameScope);
}
if (implementationType != null) {
builder.asType(implementationType);
}
configuration.bind(builder.build(), false);
}
}
private static class InstanceBasedBindingBuilder extends AbstractBindingBuilder {
private final T service;
public InstanceBasedBindingBuilder(T service) {
if (service == null) throw new IllegalArgumentException();
this.service = service;
}
@Override
void complete(DynamicConfiguration configuration, HK2Loader defaultLoader) {
if (this.loader == null) {
this.loader = defaultLoader;
}
AbstractActiveDescriptor> descriptor = BuilderHelper.createConstantDescriptor(service);
descriptor.setName(name);
descriptor.setLoader(this.loader);
descriptor.setClassAnalysisName(this.analyzer);
if (scope != null) {
descriptor.setScope(scope.getName());
}
if (ranked != null) {
descriptor.setRanking(ranked);
}
for (String key : metadata.keySet()) {
for (String value : metadata.get(key)) {
descriptor.addMetadata(key, value);
}
}
for (Annotation annotation : qualifiers) {
descriptor.addQualifierAnnotation(annotation);
}
for (Type contract : contracts) {
descriptor.addContractType(contract);
}
if (proxiable != null) {
descriptor.setProxiable(proxiable);
}
if (proxyForSameScope != null) {
descriptor.setProxyForSameScope(proxyForSameScope);
}
configuration.bind(descriptor, false);
}
}
private static class FactoryInstanceBasedBindingBuilder extends AbstractBindingBuilder {
private final Factory factory;
public FactoryInstanceBasedBindingBuilder(Factory factory) {
this.factory = factory;
}
@Override
void complete(DynamicConfiguration configuration, HK2Loader defaultLoader) {
if (this.loader == null) {
this.loader = defaultLoader;
}
AbstractActiveDescriptor> factoryContractDescriptor = BuilderHelper.createConstantDescriptor(factory);
factoryContractDescriptor.addContractType(factory.getClass());
factoryContractDescriptor.setLoader(this.loader);
ActiveDescriptorBuilder descriptorBuilder = BuilderHelper.activeLink(factory.getClass())
.named(name)
.andLoadWith(this.loader)
.analyzeWith(this.analyzer);
if (scope != null) {
descriptorBuilder.in(scope);
}
if (ranked != null) {
descriptorBuilder.ofRank(ranked);
}
for (Annotation qualifier : qualifiers) {
factoryContractDescriptor.addQualifierAnnotation(qualifier);
descriptorBuilder.qualifiedBy(qualifier);
}
for (Type contract : contracts) {
factoryContractDescriptor.addContractType(new ParameterizedTypeImpl(Factory.class, contract));
descriptorBuilder.to(contract);
}
Set keys = metadata.keySet();
for (String key : keys) {
List values = metadata.get(key);
for (String value : values) {
factoryContractDescriptor.addMetadata(key, value);
descriptorBuilder.has(key, value);
}
}
if (proxiable != null) {
descriptorBuilder.proxy(proxiable);
}
if (proxyForSameScope != null) {
descriptorBuilder.proxyForSameScope(proxyForSameScope);
}
configuration.bind(new FactoryDescriptorsImpl(
factoryContractDescriptor,
descriptorBuilder.buildProvideMethod()));
}
}
private static class FactoryTypeBasedBindingBuilder extends AbstractBindingBuilder {
private final Class extends Factory> factoryClass;
private final Class extends Annotation> factoryScope;
public FactoryTypeBasedBindingBuilder(Class extends Factory> factoryClass, Class extends Annotation> factoryScope) {
this.factoryClass = factoryClass;
this.factoryScope = factoryScope;
}
@Override
void complete(DynamicConfiguration configuration, HK2Loader defaultLoader) {
if (this.loader == null) {
this.loader = defaultLoader;
}
ActiveDescriptorBuilder factoryDescriptorBuilder = BuilderHelper.activeLink(factoryClass)
.named(name)
.andLoadWith(this.loader)
.analyzeWith(this.analyzer);
if (factoryScope != null) {
factoryDescriptorBuilder.in(factoryScope);
}
ActiveDescriptorBuilder descriptorBuilder = BuilderHelper.activeLink(factoryClass)
.named(name)
.andLoadWith(this.loader)
.analyzeWith(this.analyzer);
if (scope != null) {
descriptorBuilder.in(scope);
}
if (ranked != null) {
// factoryContractDescriptor.ofRank(factoryRank);
descriptorBuilder.ofRank(ranked);
}
for (Annotation qualifier : qualifiers) {
factoryDescriptorBuilder.qualifiedBy(qualifier);
descriptorBuilder.qualifiedBy(qualifier);
}
for (Type contract : contracts) {
factoryDescriptorBuilder.to(new ParameterizedTypeImpl(Factory.class, contract));
descriptorBuilder.to(contract);
}
Set keys = metadata.keySet();
for (String key : keys) {
List values = metadata.get(key);
for (String value : values) {
factoryDescriptorBuilder.has(key, value);
descriptorBuilder.has(key, value);
}
}
if (proxiable != null) {
descriptorBuilder.proxy(proxiable);
}
if (proxyForSameScope != null) {
descriptorBuilder.proxyForSameScope(proxyForSameScope);
}
configuration.bind(new FactoryDescriptorsImpl(
factoryDescriptorBuilder.build(),
descriptorBuilder.buildProvideMethod()));
}
}
/**
* Create a new service binding builder.
*
* @param service type.
* @param serviceType service class.
* @param bindAsContract if {@code true}, the service class will be bound as one of the contracts.
* @return initialized binding builder.
*/
static AbstractBindingBuilder create(Class serviceType, boolean bindAsContract) {
return new ClassBasedBindingBuilder(serviceType, bindAsContract ? serviceType : null);
}
/**
* Create a new service binding builder.
*
* @param service type.
* @param serviceType service class.
* @param bindAsContract if {@code true}, the service class will be bound as one of the contracts.
* @return initialized binding builder.
*/
@SuppressWarnings("unchecked")
static AbstractBindingBuilder create(Type serviceType, boolean bindAsContract) {
return new ClassBasedBindingBuilder(
(Class) ReflectionHelper.getRawClass(serviceType), bindAsContract ? serviceType : null).asType(serviceType);
}
/**
* Create a new service binding builder.
*
* @param service type.
* @param serviceType generic service type.
* @param bindAsContract if {@code true}, the service class will be bound as one of the contracts.
* @return initialized binding builder.
*/
static AbstractBindingBuilder create(TypeLiteral serviceType, boolean bindAsContract) {
Type type = serviceType.getType();
return new ClassBasedBindingBuilder(serviceType.getRawType(), bindAsContract ? serviceType.getType() : null).asType(type);
}
/**
* Create a new service binding builder.
*
* @param service service instance.
* @return initialized binding builder.
*/
static AbstractBindingBuilder create(T service) {
return new InstanceBasedBindingBuilder(service);
}
/**
* Create a new service binding builder.
*
* @param factory service factory instance.
* @return initialized binding builder.
*/
static AbstractBindingBuilder createFactoryBinder(Factory factory) {
return new FactoryInstanceBasedBindingBuilder(factory);
}
/**
* Create a new service binding builder.
*
* @param factoryType service factory class.
* @param factoryScope service factory scope.
* @return initialized binding builder.
*/
static AbstractBindingBuilder createFactoryBinder(Class extends Factory> factoryType, Class extends Annotation> factoryScope) {
return new FactoryTypeBasedBindingBuilder(factoryType, factoryScope);
}
}