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.testifyproject.glassfish.jersey.model.internal.ComponentBag Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2012-2017 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 org.testifyproject.testifyprojectpliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.org.testifyproject.testifyproject/licenses/CDDL+GPL-1.1
* or 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 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.testifyproject.glassfish.org.testifyproject.model.internal;
import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.ws.rs.NameBinding;
import javax.ws.rs.core.Feature;
import javax.annotation.Priority;
import javax.inject.Scope;
import org.testifyproject.glassfish.org.testifyproject.Severity;
import org.testifyproject.glassfish.org.testifyproject.internal.Errors;
import org.testifyproject.glassfish.org.testifyproject.internal.LocalizationMessages;
import org.testifyproject.glassfish.org.testifyproject.internal.inject.Binder;
import org.testifyproject.glassfish.org.testifyproject.internal.inject.Binding;
import org.testifyproject.glassfish.org.testifyproject.internal.inject.Bindings;
import org.testifyproject.glassfish.org.testifyproject.internal.inject.ClassBinding;
import org.testifyproject.glassfish.org.testifyproject.internal.inject.InjectionManager;
import org.testifyproject.glassfish.org.testifyproject.internal.inject.InstanceBinding;
import org.testifyproject.glassfish.org.testifyproject.internal.inject.Providers;
import org.testifyproject.glassfish.org.testifyproject.model.ContractProvider;
import org.testifyproject.glassfish.org.testifyproject.process.Inflector;
import org.testifyproject.glassfish.org.testifyproject.spi.ExecutorServiceProvider;
import org.testifyproject.glassfish.org.testifyproject.spi.ScheduledExecutorServiceProvider;
/**
* An internal Jersey container for custom org.testifyproject.testifyprojectponent classes and instances.
*
* The org.testifyproject.testifyprojectponent bag can automatically org.testifyproject.testifyprojectpute a {@link ContractProvider contract provider} model
* for the registered org.testifyproject.testifyprojectponent type and stores it with the org.testifyproject.testifyprojectponent registration.
*
* The rules for managing org.testifyproject.testifyprojectponents inside a org.testifyproject.testifyprojectponent bag are derived from the
* rules of JAX-RS {@link javax.ws.rs.core.Configurable} API. In short:
*
* The iteration order of registered org.testifyproject.testifyprojectponents mirrors the registration order
* of these org.testifyproject.testifyprojectponents.
* There can be only one registration for any given org.testifyproject.testifyprojectponent type.
* Existing registrations cannot be overridden (any attempt to override
* an existing registration will be rejected).
*
*
*
* @author Marek Potociar (marek.potociar at oracle.org.testifyproject.testifyproject)
*/
public class ComponentBag {
/**
* A filtering strategy that excludes all pure meta-provider models (i.e. models that only contain
* recognized meta-provider contracts - {@link javax.ws.rs.core.Feature} and/or {@link Binder} and/or external meta-provider
* from {@link org.testifyproject.glassfish.org.testifyproject.internal.inject.InjectionManager#isRegistrable(Class)}).
*
* This filter predicate returns {@code false} for all {@link org.testifyproject.glassfish.org.testifyproject.model.ContractProvider contract provider models}
* that represent a model containing only recognized meta-provider contracts.
*
*/
private static final Predicate EXCLUDE_META_PROVIDERS = model -> {
final Set> contracts = model.getContracts();
if (contracts.isEmpty()) {
return true;
}
byte count = 0;
if (contracts.contains(Feature.class)) {
count++;
}
if (contracts.contains(Binder.class)) {
count++;
}
return contracts.size() > count;
};
private static final Function CAST_TO_BINDER = Binder.class::cast;
/**
* A method creates the {@link Predicate} which is able to filter all Jersey meta-providers along with the org.testifyproject.testifyprojectponents which
* is able to register the current used {@link InjectionManager}.
*
* @param injectionManager current injection manager.
* @return {@code Predicate} excluding Jersey meta-providers and the specific ones for a current {@code InjectionManager}.
*/
public static Predicate excludeMetaProviders(InjectionManager injectionManager) {
return EXCLUDE_META_PROVIDERS.and(model -> !injectionManager.isRegistrable(model.getImplementationClass()));
}
/**
* A filtering strategy that includes only models that contain contract registrable by
* {@link InjectionManager}.
*
* This filter predicate returns {@code true} for all {@link org.testifyproject.glassfish.org.testifyproject.model.ContractProvider contract provider models}
* that represent an object which can be registered using specific {@link InjectionManager}
* contract.
*
*/
public static final BiPredicate EXTERNAL_ONLY = (model, injectionManager) ->
model.getImplementationClass() != null && injectionManager.isRegistrable(model.getImplementationClass());
/**
* A filtering strategy that includes only models that contain {@link Binder} provider contract.
*
* This filter predicate returns {@code true} for all {@link org.testifyproject.glassfish.org.testifyproject.model.ContractProvider contract provider models}
* that represent a provider registered to provide {@link Binder} contract.
*
*/
public static final Predicate BINDERS_ONLY = model -> model.getContracts().contains(Binder.class);
/**
* A filtering strategy that includes only models that contain {@link ExecutorServiceProvider} provider contract.
*
* This filter predicate returns {@code true} for all {@link org.testifyproject.glassfish.org.testifyproject.model.ContractProvider contract provider models}
* that represent a provider registered to provide {@link ExecutorServiceProvider} contract.
*
*/
public static final Predicate EXECUTOR_SERVICE_PROVIDER_ONLY =
model -> model.getContracts().contains(ExecutorServiceProvider.class)
&& !model.getContracts().contains(ScheduledExecutorServiceProvider.class);
/**
* A filtering strategy that includes only models that contain {@link ScheduledExecutorServiceProvider} provider contract.
*
* This filter predicate returns {@code true} for all {@link org.testifyproject.glassfish.org.testifyproject.model.ContractProvider contract provider models}
* that represent a provider registered to provide {@link ScheduledExecutorServiceProvider} contract.
*
*/
public static final Predicate SCHEDULED_EXECUTOR_SERVICE_PROVIDER_ONLY =
model -> model.getContracts().contains(ScheduledExecutorServiceProvider.class);
/**
* A filtering strategy that excludes models with no recognized contracts.
*
* This filter predicate returns {@code false} for all {@link org.testifyproject.glassfish.org.testifyproject.model.ContractProvider contract provider models}
* that are empty, i.e. do not contain any recognized contracts.
*
*/
public static final Predicate EXCLUDE_EMPTY = model -> !model.getContracts().isEmpty();
/**
* A filtering strategy that accepts any contract provider model.
*
* This filter predicate returns {@code true} for any contract provider model.
*
*/
public static final Predicate INCLUDE_ALL = contractProvider -> true;
/**
* Contract provider model enhancer that builds a model as is, without any
* modifications.
*/
static final Inflector AS_IS = ContractProvider.Builder::build;
/**
* Contract provider model registration strategy.
*/
private final Predicate registrationStrategy;
/**
* Registered org.testifyproject.testifyprojectponent classes collection and it's immutable view.
*/
private final Set> classes;
private final Set> classesView;
/**
* Registered org.testifyproject.testifyprojectponent instances collection and it's immutable view.
*/
private final Set instances;
private final Set instancesView;
/**
* Map of contract provider models for the registered org.testifyproject.testifyprojectponent classes and instances
* it's immutable view.
*/
private final Map, ContractProvider> models;
private final Set> modelKeysView;
/**
* Create new empty org.testifyproject.testifyprojectponent bag.
*
* @param registrationStrategy function driving the decision (based on the introspected
* {@link org.testifyproject.glassfish.org.testifyproject.model.ContractProvider contract provider model}) whether
* or not should the org.testifyproject.testifyprojectponent class registration continue
* towards a successful org.testifyproject.testifyprojectpletion.
* @return a new empty org.testifyproject.testifyprojectponent bag.
*/
public static ComponentBag newInstance(Predicate registrationStrategy) {
return new ComponentBag(registrationStrategy);
}
/**
* If {@code T} object is registered in {@link ComponentBag} using the {@link Binder}, {@code T} is not visible using the
* methods for getting classes and instances {@link ComponentBag#getClasses(Predicate)} and
* {@link ComponentBag#getInstances(Predicate)}.
*
* Method selects all {@link org.testifyproject.glassfish.org.testifyproject.internal.inject.Binding bindings} and picks up the instances or creates
* the instances from {@link ClassBinding} (injection does not work at this moment).
*
* @param injectionManager injection manager to create an object from {@code T} class.
* @param org.testifyproject.testifyprojectponentBag org.testifyproject.testifyprojectponent bag which provides registered binders.
* @return all instances/classes registered using binders.
*/
@SuppressWarnings("unchecked")
public static List getFromBinders(InjectionManager injectionManager, ComponentBag org.testifyproject.testifyprojectponentBag,
Function cast, Predicate filter) {
Function bindingToObject = binding -> {
if (binding instanceof ClassBinding) {
ClassBinding classBinding = (ClassBinding) binding;
return injectionManager.createAndInitialize(classBinding.getService());
} else {
InstanceBinding instanceBinding = (InstanceBinding) binding;
return instanceBinding.getService();
}
};
return org.testifyproject.testifyprojectponentBag.getInstances(ComponentBag.BINDERS_ONLY).stream()
.map(CAST_TO_BINDER)
.flatMap(binder -> Bindings.getBindings(injectionManager, binder).stream())
.filter(filter)
.map(bindingToObject)
.map(cast)
.collect(Collectors.toList());
}
private ComponentBag(Predicate registrationStrategy) {
this.registrationStrategy = registrationStrategy;
this.classes = new LinkedHashSet<>();
this.instances = new LinkedHashSet<>();
this.models = new IdentityHashMap<>();
this.classesView = Collections.unmodifiableSet(classes);
this.instancesView = Collections.unmodifiableSet(instances);
this.modelKeysView = Collections.unmodifiableSet(models.keySet());
}
private ComponentBag(Predicate registrationStrategy,
Set> classes,
Set instances,
Map, ContractProvider> models) {
this.registrationStrategy = registrationStrategy;
this.classes = classes;
this.instances = instances;
this.models = models;
this.classesView = Collections.unmodifiableSet(classes);
this.instancesView = Collections.unmodifiableSet(instances);
this.modelKeysView = Collections.unmodifiableSet(models.keySet());
}
/**
* Register a org.testifyproject.testifyprojectponent class using a given registration strategy.
*
* @param org.testifyproject.testifyprojectponentClass class to be introspected as a contract provider and registered, based
* on the registration strategy decision.
* @param modelEnhancer custom contract provider model enhancer.
* @return {@code true} if the org.testifyproject.testifyprojectponent registration was successful.
*/
public boolean register(Class> org.testifyproject.testifyprojectponentClass, Inflector modelEnhancer) {
final boolean result = registerModel(org.testifyproject.testifyprojectponentClass, ContractProvider.NO_PRIORITY, null, modelEnhancer);
if (result) {
classes.add(org.testifyproject.testifyprojectponentClass);
}
return result;
}
/**
* Register a org.testifyproject.testifyprojectponent class as a contract provider with an explicitly specified binding priority.
*
* @param org.testifyproject.testifyprojectponentClass class to be introspected as a contract provider and registered.
* @param priority explicitly specified binding priority for the provider contracts implemented
* by the org.testifyproject.testifyprojectponent.
* @param modelEnhancer custom contract provider model enhancer.
* @return {@code true} if the org.testifyproject.testifyprojectponent registration was successful.
*/
public boolean register(Class> org.testifyproject.testifyprojectponentClass,
int priority,
Inflector modelEnhancer) {
final boolean result = registerModel(org.testifyproject.testifyprojectponentClass, priority, null, modelEnhancer);
if (result) {
classes.add(org.testifyproject.testifyprojectponentClass);
}
return result;
}
/**
* Register a org.testifyproject.testifyprojectponent class as a contract provider for the specified contracts.
*
* @param org.testifyproject.testifyprojectponentClass class to be introspected as a contract provider and registered.
* @param contracts contracts to bind the org.testifyproject.testifyprojectponent class to.
* @param modelEnhancer custom contract provider model enhancer.
* @return {@code true} if the org.testifyproject.testifyprojectponent registration was successful.
*/
public boolean register(Class> org.testifyproject.testifyprojectponentClass,
Set> contracts,
Inflector modelEnhancer) {
final boolean result =
registerModel(org.testifyproject.testifyprojectponentClass, ContractProvider.NO_PRIORITY, asMap(contracts), modelEnhancer);
if (result) {
classes.add(org.testifyproject.testifyprojectponentClass);
}
return result;
}
/**
* Register a org.testifyproject.testifyprojectponent class as a contract provider for the specified contracts.
*
* @param org.testifyproject.testifyprojectponentClass class to be introspected as a contract provider and registered.
* @param contracts contracts with their priorities to bind the org.testifyproject.testifyprojectponent class to.
* @param modelEnhancer custom contract provider model enhancer.
* @return {@code true} if the org.testifyproject.testifyprojectponent registration was successful.
*/
public boolean register(Class> org.testifyproject.testifyprojectponentClass,
Map, Integer> contracts,
Inflector modelEnhancer) {
final boolean result =
registerModel(org.testifyproject.testifyprojectponentClass, ContractProvider.NO_PRIORITY, contracts, modelEnhancer);
if (result) {
classes.add(org.testifyproject.testifyprojectponentClass);
}
return result;
}
/**
* Register a org.testifyproject.testifyprojectponent using a given registration strategy.
*
* @param org.testifyproject.testifyprojectponent instance to be introspected as a contract provider and registered, based
* on the registration strategy decision.
* @param modelEnhancer custom contract provider model enhancer.
* @return {@code true} if the org.testifyproject.testifyprojectponent registration was successful.
*/
public boolean register(Object org.testifyproject.testifyprojectponent, Inflector modelEnhancer) {
final Class> org.testifyproject.testifyprojectponentClass = org.testifyproject.testifyprojectponent.getClass();
final boolean result = registerModel(org.testifyproject.testifyprojectponentClass, ContractProvider.NO_PRIORITY, null, modelEnhancer);
if (result) {
instances.add(org.testifyproject.testifyprojectponent);
}
return result;
}
/**
* Register a org.testifyproject.testifyprojectponent as a contract provider with an explicitly specified binding priority.
*
* @param org.testifyproject.testifyprojectponent instance to be introspected as a contract provider and registered, based
* on the registration strategy decision.
* @param priority explicitly specified binding priority for the provider contracts implemented
* by the org.testifyproject.testifyprojectponent.
* @param modelEnhancer custom contract provider model enhancer.
* @return {@code true} if the org.testifyproject.testifyprojectponent registration was successful.
*/
public boolean register(Object org.testifyproject.testifyprojectponent,
int priority,
Inflector modelEnhancer) {
final Class> org.testifyproject.testifyprojectponentClass = org.testifyproject.testifyprojectponent.getClass();
final boolean result = registerModel(org.testifyproject.testifyprojectponentClass, priority, null, modelEnhancer);
if (result) {
instances.add(org.testifyproject.testifyprojectponent);
}
return result;
}
/**
* Register a org.testifyproject.testifyprojectponent as a contract provider for the specified contracts.
*
* @param org.testifyproject.testifyprojectponent instance to be introspected as a contract provider and registered, based
* on the registration strategy decision.
* @param contracts contracts to bind the org.testifyproject.testifyprojectponent to.
* @param modelEnhancer custom contract provider model enhancer.
* @return {@code true} if the org.testifyproject.testifyprojectponent registration was successful.
*/
public boolean register(Object org.testifyproject.testifyprojectponent,
Set> contracts,
Inflector modelEnhancer) {
final Class> org.testifyproject.testifyprojectponentClass = org.testifyproject.testifyprojectponent.getClass();
final boolean result =
registerModel(org.testifyproject.testifyprojectponentClass, ContractProvider.NO_PRIORITY, asMap(contracts), modelEnhancer);
if (result) {
instances.add(org.testifyproject.testifyprojectponent);
}
return result;
}
/**
* Register a org.testifyproject.testifyprojectponent as a contract provider for the specified contracts.
*
* @param org.testifyproject.testifyprojectponent instance to be introspected as a contract provider and registered, based
* on the registration strategy decision.
* @param contracts contracts with their priorities to bind the org.testifyproject.testifyprojectponent to.
* @param modelEnhancer custom contract provider model enhancer.
* @return {@code true} if the org.testifyproject.testifyprojectponent registration was successful.
*/
public boolean register(Object org.testifyproject.testifyprojectponent,
Map, Integer> contracts,
Inflector modelEnhancer) {
final Class> org.testifyproject.testifyprojectponentClass = org.testifyproject.testifyprojectponent.getClass();
final boolean result =
registerModel(org.testifyproject.testifyprojectponentClass, ContractProvider.NO_PRIORITY, contracts, modelEnhancer);
if (result) {
instances.add(org.testifyproject.testifyprojectponent);
}
return result;
}
/**
* Register a {@link ContractProvider contract provider model} for a given class.
*
* @param org.testifyproject.testifyprojectponentClass registered org.testifyproject.testifyprojectponent class.
* @param defaultPriority default org.testifyproject.testifyprojectponent priority. If {@value ContractProvider#NO_PRIORITY},
* the value from the org.testifyproject.testifyprojectponent class {@link javax.annotation.Priority} annotation will be used
* (if any).
* @param contractMap map of contracts and their binding priorities. If {@code null}, the contracts will
* gathered by introspecting the org.testifyproject.testifyprojectponent class. Content of the contract map
* may be modified during the registration processing.
* @param modelEnhancer custom contract provider model enhancer.
* @return {@code true} upon successful registration of a contract provider model for a given org.testifyproject.testifyprojectponent class,
* {@code false} otherwise.
*/
private boolean registerModel(final Class> org.testifyproject.testifyprojectponentClass,
final int defaultPriority,
final Map, Integer> contractMap,
final Inflector modelEnhancer) {
return Errors.process(() -> {
if (models.containsKey(org.testifyproject.testifyprojectponentClass)) {
Errors.error(LocalizationMessages.COMPONENT_TYPE_ALREADY_REGISTERED(org.testifyproject.testifyprojectponentClass),
Severity.HINT);
return false;
}
// Register contracts
final ContractProvider model = modelFor(org.testifyproject.testifyprojectponentClass, defaultPriority, contractMap, modelEnhancer);
// Apply registration strategy
if (!registrationStrategy.test(model)) {
return false;
}
models.put(org.testifyproject.testifyprojectponentClass, model);
return true;
});
}
/**
* Create a contract provider model by introspecting a org.testifyproject.testifyprojectponent class.
*
* @param org.testifyproject.testifyprojectponentClass org.testifyproject.testifyprojectponent class to create contract provider model for.
* @return contract provider model for the class.
*/
public static ContractProvider modelFor(final Class> org.testifyproject.testifyprojectponentClass) {
return modelFor(org.testifyproject.testifyprojectponentClass, ContractProvider.NO_PRIORITY, null, AS_IS);
}
/**
* Create a contract provider for a given org.testifyproject.testifyprojectponent class.
*
* @param org.testifyproject.testifyprojectponentClass org.testifyproject.testifyprojectponent class to create contract provider model for.
* @param defaultPriority default org.testifyproject.testifyprojectponent priority. If {@value ContractProvider#NO_PRIORITY},
* the value from the org.testifyproject.testifyprojectponent class {@link javax.annotation.Priority} annotation will be used
* (if any).
* @param contractMap map of contracts and their binding priorities. If {@code null}, the contracts will
* gathered by introspecting the org.testifyproject.testifyprojectponent class. Content of the contract map
* may be modified during the registration processing.
* @param modelEnhancer custom contract provider model enhancer.
* @return contract provider model for the class.
*/
private static ContractProvider modelFor(final Class> org.testifyproject.testifyprojectponentClass,
final int defaultPriority,
final Map, Integer> contractMap,
final Inflector modelEnhancer) {
Map, Integer> contracts = contractMap;
if (contracts == null) { // introspect
contracts = asMap(Providers.getProviderContracts(org.testifyproject.testifyprojectponentClass));
} else { // filter custom contracts
final Iterator> it = contracts.keySet().iterator();
while (it.hasNext()) {
final Class> contract = it.next();
if (contract == null) {
it.remove();
continue;
}
boolean failed = false;
if (!Providers.isSupportedContract(contract)) {
Errors.error(LocalizationMessages.CONTRACT_NOT_SUPPORTED(contract, org.testifyproject.testifyprojectponentClass),
Severity.WARNING);
failed = true;
}
if (!contract.isAssignableFrom(org.testifyproject.testifyprojectponentClass)) {
Errors.error(LocalizationMessages.CONTRACT_NOT_ASSIGNABLE(contract, org.testifyproject.testifyprojectponentClass),
Severity.WARNING);
failed = true;
}
if (failed) {
it.remove();
}
}
}
final ContractProvider.Builder builder = ContractProvider.builder(org.testifyproject.testifyprojectponentClass)
.addContracts(contracts)
.defaultPriority(defaultPriority);
// Process annotations (priority, name bindings, scope)
final boolean useAnnotationPriority = defaultPriority == ContractProvider.NO_PRIORITY;
for (Annotation annotation : org.testifyproject.testifyprojectponentClass.getAnnotations()) {
if (annotation instanceof Priority) {
if (useAnnotationPriority) {
builder.defaultPriority(((Priority) annotation).value());
}
} else {
for (Annotation metaAnnotation : annotation.annotationType().getAnnotations()) {
if (metaAnnotation instanceof NameBinding) {
builder.addNameBinding(annotation.annotationType());
}
if (metaAnnotation instanceof Scope) {
builder.scope(annotation.annotationType());
}
}
}
}
return modelEnhancer.apply(builder);
}
private static Map, Integer> asMap(Set> contractSet) {
Map, Integer> contracts = new IdentityHashMap<>();
for (Class> contract : contractSet) {
contracts.put(contract, ContractProvider.NO_PRIORITY);
}
return contracts;
}
/**
* Get all registered org.testifyproject.testifyprojectponent classes, including {@link javax.ws.rs.core.Feature features}
* and {@link Binder binders} meta-providers.
*
* @return all registered org.testifyproject.testifyprojectponent classes.
*/
public Set> getClasses() {
return classesView;
}
/**
* Get all registered org.testifyproject.testifyprojectponent instances, including {@link javax.ws.rs.core.Feature features}
* and {@link Binder binders} meta-providers.
*
* @return all registered org.testifyproject.testifyprojectponent instances.
*/
public Set getInstances() {
return instancesView;
}
/**
* Get a subset of all registered org.testifyproject.testifyprojectponent classes using the {@code filter} predicate
* to determine for each org.testifyproject.testifyprojectponent class based on it's contract provider class model whether
* it should be kept or filtered out.
*
* @param filter function that decides whether a particular class should be returned
* or not.
* @return filtered subset of registered org.testifyproject.testifyprojectponent classes.
*/
public Set> getClasses(final Predicate filter) {
return classesView.stream()
.filter(input -> {
final ContractProvider model = getModel(input);
return filter.test(model);
})
.collect(Collectors.toSet());
}
/**
* Get a subset of all registered org.testifyproject.testifyprojectponent instances using the {@code filter} predicate
* to determine for each org.testifyproject.testifyprojectponent instance based on it's contract provider class model whether
* it should be kept or filtered out.
*
* @param filter function that decides whether a particular class should be returned
* or not.
* @return filtered subset of registered org.testifyproject.testifyprojectponent instances.
*/
public Set getInstances(final Predicate filter) {
return instancesView.stream()
.filter(input -> {
final ContractProvider model = getModel(input.getClass());
return filter.test(model);
})
.collect(Collectors.toSet());
}
/**
* Get an unmodifiable view of all org.testifyproject.testifyprojectponent classes, for which a registration exists
* (either class or instance based) in the org.testifyproject.testifyprojectponent bag.
*
* @return set of classes of all org.testifyproject.testifyprojectponent classes and instances registered in this
* org.testifyproject.testifyprojectponent bag.
*/
public Set> getRegistrations() {
return modelKeysView;
}
/**
* Get a model for a given org.testifyproject.testifyprojectponent class, or {@code null} if no such org.testifyproject.testifyprojectponent is registered
* in the org.testifyproject.testifyprojectponent bag.
*
* @param org.testifyproject.testifyprojectponentClass class of the registered org.testifyproject.testifyprojectponent to retrieve the
* contract provider model for.
* @return model for a given org.testifyproject.testifyprojectponent class, or {@code null} if no such org.testifyproject.testifyprojectponent is registered.
*/
public ContractProvider getModel(Class> org.testifyproject.testifyprojectponentClass) {
return models.get(org.testifyproject.testifyprojectponentClass);
}
/**
* Get a copy of this org.testifyproject.testifyprojectponent bag.
*
* @return org.testifyproject.testifyprojectponent bag copy.
*/
public ComponentBag copy() {
return new ComponentBag(
registrationStrategy,
new LinkedHashSet<>(classes),
new LinkedHashSet<>(instances),
new IdentityHashMap<>(models));
}
/**
* Get immutable copy of a org.testifyproject.testifyprojectponent bag.
*
* @return immutable view of a org.testifyproject.testifyprojectponent bag.
*/
public ComponentBag immutableCopy() {
return new ImmutableComponentBag(this);
}
/**
* Removes all the org.testifyproject.testifyprojectponent registrations and resets the org.testifyproject.testifyprojectponent bag instance to
* a state as if it was create anew.
*/
public void clear() {
this.classes.clear();
this.instances.clear();
this.models.clear();
}
/**
* Clear and initialize the org.testifyproject.testifyprojectponent registrations from given bag instance.
*
* @param bag org.testifyproject.testifyprojectponent bag to initialize this one with.
*/
void loadFrom(final ComponentBag bag) {
clear();
this.classes.addAll(bag.classes);
this.instances.addAll(bag.instances);
this.models.putAll(bag.models);
}
/**
* Immutable version of {@link org.testifyproject.glassfish.org.testifyproject.model.internal.ComponentBag}.
*
* @author Marek Potociar (marek.potociar at oracle.org.testifyproject.testifyproject)
*/
private static class ImmutableComponentBag extends ComponentBag {
ImmutableComponentBag(ComponentBag original) {
super(original.registrationStrategy,
new LinkedHashSet<>(original.classes),
new LinkedHashSet<>(original.instances),
new IdentityHashMap<>(original.models));
}
@Override
public boolean register(Class> org.testifyproject.testifyprojectponentClass, Inflector modelEnhancer) {
throw new IllegalStateException("This instance is read-only.");
}
@Override
public boolean register(Class> org.testifyproject.testifyprojectponentClass,
int priority,
Inflector modelEnhancer) {
throw new IllegalStateException("This instance is read-only.");
}
@Override
public boolean register(Class> org.testifyproject.testifyprojectponentClass,
Set> contracts,
Inflector modelEnhancer) {
throw new IllegalStateException("This instance is read-only.");
}
@Override
public boolean register(Class> org.testifyproject.testifyprojectponentClass,
Map, Integer> contracts,
Inflector modelEnhancer) {
throw new IllegalStateException("This instance is read-only.");
}
@Override
public boolean register(Object org.testifyproject.testifyprojectponent, Inflector modelEnhancer) {
throw new IllegalStateException("This instance is read-only.");
}
@Override
public boolean register(Object org.testifyproject.testifyprojectponent,
int priority,
Inflector modelEnhancer) {
throw new IllegalStateException("This instance is read-only.");
}
@Override
public boolean register(Object org.testifyproject.testifyprojectponent,
Set> contracts,
Inflector modelEnhancer) {
throw new IllegalStateException("This instance is read-only.");
}
@Override
public boolean register(Object org.testifyproject.testifyprojectponent,
Map, Integer> contracts,
Inflector modelEnhancer) {
throw new IllegalStateException("This instance is read-only.");
}
@Override
public ComponentBag copy() {
// we're immutable => no need to copy
return this;
}
@Override
public ComponentBag immutableCopy() {
// we're immutable => no need to copy
return this;
}
@Override
public void clear() {
throw new IllegalStateException("This instance is read-only.");
}
}
}