import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
import org.apache.aries.blueprint.di.AbstractRecipe;
import org.apache.aries.blueprint.di.ExecutionContext;
import org.apache.aries.blueprint.di.Recipe;
* @author Thomas Pantelis
*/
abstract class AbstractDependentComponentFactoryMetadata implements DependentComponentFactoryMetadata {
- private final Logger log = LoggerFactory.getLogger(getClass());
+ final Logger log = LoggerFactory.getLogger(getClass());
private final String id;
private final AtomicBoolean started = new AtomicBoolean();
private final AtomicBoolean satisfied = new AtomicBoolean();
private final AtomicBoolean restarting = new AtomicBoolean();
+ @GuardedBy("serviceRecipes")
private final List<StaticServiceReferenceRecipe> serviceRecipes = new ArrayList<>();
private volatile ExtendedBlueprintContainer container;
private volatile SatisfactionCallback satisfactionCallback;
private volatile String failureMessage;
private volatile Throwable failureCause;
- private volatile String dependendencyDesc;
+ private volatile String dependencyDesc;
+ @GuardedBy("serviceRecipes")
+ private boolean stoppedServiceRecipes;
- protected AbstractDependentComponentFactoryMetadata(String id) {
+ protected AbstractDependentComponentFactoryMetadata(final String id) {
this.id = Preconditions.checkNotNull(id);
}
@Override
public String getDependencyDescriptor() {
- return dependendencyDesc;
+ return dependencyDesc;
}
@Override
return satisfied.get();
}
- protected void setFailureMessage(String failureMessage) {
+ protected void setFailureMessage(final String failureMessage) {
setFailure(failureMessage, null);
}
- protected void setFailure(String failureMessage, Throwable failureCause) {
+ protected void setFailure(final String failureMessage, final Throwable failureCause) {
this.failureMessage = failureMessage;
this.failureCause = failureCause;
}
- protected void setDependendencyDesc(String dependendencyDesc) {
- this.dependendencyDesc = dependendencyDesc;
+ protected void setDependencyDesc(final String dependencyDesc) {
+ this.dependencyDesc = dependencyDesc;
}
protected final ExtendedBlueprintContainer container() {
}
}
- protected void retrieveService(String name, Class<?> interfaceClass, Consumer<Object> onServiceRetrieved) {
+ protected void retrieveService(final String name, final Class<?> interfaceClass,
+ final Consumer<Object> onServiceRetrieved) {
retrieveService(name, interfaceClass.getName(), onServiceRetrieved);
}
- protected void retrieveService(String name, String interfaceName, Consumer<Object> onServiceRetrieved) {
- StaticServiceReferenceRecipe recipe = new StaticServiceReferenceRecipe(getId() + "-" + name,
- container, interfaceName);
- setDependendencyDesc(recipe.getOsgiFilter());
- serviceRecipes.add(recipe);
+ protected void retrieveService(final String name, final String interfaceName,
+ final Consumer<Object> onServiceRetrieved) {
+ synchronized (serviceRecipes) {
+ if (stoppedServiceRecipes) {
+ return;
+ }
+
+ StaticServiceReferenceRecipe recipe = new StaticServiceReferenceRecipe(getId() + "-" + name,
+ container, interfaceName);
+ setDependencyDesc(recipe.getOsgiFilter());
+ serviceRecipes.add(recipe);
- recipe.startTracking(onServiceRetrieved);
+ recipe.startTracking(onServiceRetrieved);
+ }
}
protected final String logName() {
}
@Override
- public void init(ExtendedBlueprintContainer newContainer) {
+ public void init(final ExtendedBlueprintContainer newContainer) {
this.container = newContainer;
log.debug("{}: In init", logName());
}
@Override
- public void destroy(Object instance) {
+ public void destroy(final Object instance) {
log.debug("{}: In destroy", logName());
stopServiceRecipes();
}
private void stopServiceRecipes() {
- for (StaticServiceReferenceRecipe recipe: serviceRecipes) {
- recipe.stop();
- }
+ synchronized (serviceRecipes) {
+ stoppedServiceRecipes = true;
+ for (StaticServiceReferenceRecipe recipe: serviceRecipes) {
+ recipe.stop();
+ }
- serviceRecipes.clear();
+ serviceRecipes.clear();
+ }
}
protected void restartContainer() {
@SuppressWarnings("unchecked")
@Nullable
- protected <T> T getOSGiService(Class<T> serviceInterface) {
+ protected <T> T getOSGiService(final Class<T> serviceInterface) {
try {
ServiceReference<T> serviceReference =
container().getBundleContext().getServiceReference(serviceInterface);
}
return service;
- } catch (IllegalStateException e) {
+ } catch (final IllegalStateException e) {
// This is thrown if the BundleContext is no longer valid which is possible on shutdown so we
// log as debug.
log.debug("{}: Error obtaining {}", logName(), serviceInterface.getSimpleName(), e);