}
LOGGER.debug("Running blueprint container for bundle {} in state {}", bundle.getSymbolicName(), state);
switch (state) {
case Unknown:
readDirectives();
eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.CREATING, getBundle(), getExtenderBundle()));
parser = new Parser();
parser.parse(getResources());
namespaces = parser.getNamespaces();
handlerSet = handlers.getNamespaceHandlers(namespaces, getBundle());
handlerSet.addListener(this);
state = State.WaitForNamespaceHandlers;
break;
case WaitForNamespaceHandlers:
{
List<String> missing = new ArrayList<String>();
List<URI> missingURIs = new ArrayList<URI>();
for (URI ns : namespaces) {
if (handlerSet.getNamespaceHandler(ns) == null) {
missing.add("(&(" + Constants.OBJECTCLASS + "=" + NamespaceHandler.class.getName() + ")(" + NamespaceHandlerRegistryImpl.NAMESPACE + "=" + ns + "))");
missingURIs.add(ns);
}
}
if (missing.size() > 0) {
LOGGER.info("Bundle {} is waiting for namespace handlers {}", getBundle().getSymbolicName(), missingURIs);
eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.GRACE_PERIOD, getBundle(), getExtenderBundle(), missing.toArray(new String[missing.size()])));
return;
}
componentDefinitionRegistry.reset();
componentDefinitionRegistry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintContainer", this));
componentDefinitionRegistry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintBundle", bundle));
componentDefinitionRegistry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintBundleContext", bundleContext));
componentDefinitionRegistry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintConverter", converter));
if (xmlValidation) {
parser.validate(handlerSet.getSchema());
}
parser.populate(handlerSet, componentDefinitionRegistry);
state = State.Populated;
break;
}
case Populated:
getRepository();
trackServiceReferences();
Runnable r = new Runnable() {
public void run() {
synchronized (scheduled) {
if (destroyed.get()) {
return;
}
Throwable t = new TimeoutException();
state = State.Failed;
String[] missingDependecies = getMissingDependencies();
tidyupComponents();
LOGGER.error("Unable to start blueprint container for bundle " + getBundle().getSymbolicName() + " due to unresolved dependencies " + Arrays.asList(missingDependecies), t);
eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.FAILURE, getBundle(), getExtenderBundle(), missingDependecies, t));
}
}
};
timeoutFuture = timer.schedule(r, timeout, TimeUnit.MILLISECONDS);
state = State.WaitForInitialReferences;
break;
case WaitForInitialReferences:
if (waitForDependencies) {
String[] missingDependencies = getMissingDependencies();
if (missingDependencies.length > 0) {
LOGGER.info("Bundle {} is waiting for dependencies {}", getBundle().getSymbolicName(), Arrays.asList(missingDependencies));
eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.GRACE_PERIOD, getBundle(), getExtenderBundle(), missingDependencies));
return;
}
}
state = State.InitialReferencesSatisfied;
break;
case InitialReferencesSatisfied:
processTypeConverters();
processProcessors();
state = State.WaitForInitialReferences2;
break;
case WaitForInitialReferences2:
if (waitForDependencies) {
String[] missingDependencies = getMissingDependencies();
if (missingDependencies.length > 0) {
LOGGER.info("Bundle {} is waiting for dependencies {}", getBundle().getSymbolicName(), Arrays.asList(missingDependencies));
eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.GRACE_PERIOD, getBundle(), getExtenderBundle(), missingDependencies));
return;
}
}
state = State.Create;
break;
case Create:
cancelFutureIfPresent();
registerServices();
instantiateEagerComponents();
// Register the BlueprintContainer in the OSGi registry
int bs = bundle.getState();
if (registration == null && (bs == Bundle.ACTIVE || bs == Bundle.STARTING)) {
Properties props = new Properties();
props.put(BlueprintConstants.CONTAINER_SYMBOLIC_NAME_PROPERTY,
bundle.getSymbolicName());
props.put(BlueprintConstants.CONTAINER_VERSION_PROPERTY,
JavaUtils.getBundleVersion(bundle));
registration = registerService(new String [] { BlueprintContainer.class.getName() }, this, props);
}
eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.CREATED, getBundle(), getExtenderBundle()));
state = State.Created;
break;
case Created:
case Failed:
return;
}
}
} catch (Throwable t) {
state = State.Failed;
cancelFutureIfPresent();
tidyupComponents();
LOGGER.error("Unable to start blueprint container for bundle " + getBundle().getSymbolicName(), t);
eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.FAILURE, getBundle(), getExtenderBundle(), t));
}
}