blob: c67a26ec03486590862a200ec5af322df0977df3 [file] [log] [blame]
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.aries.cdi.container.internal.container;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.enterprise.inject.spi.Extension;
import org.apache.aries.cdi.container.internal.container.Op.Mode;
import org.apache.aries.cdi.container.internal.container.Op.Type;
import org.apache.aries.cdi.container.internal.loader.BundleResourcesLoader;
import org.apache.aries.cdi.container.internal.model.ExtendedExtensionDTO;
import org.apache.aries.cdi.container.internal.model.FactoryComponent;
import org.apache.aries.cdi.container.internal.model.SingleComponent;
import org.apache.aries.cdi.container.internal.util.Syncro;
import org.jboss.weld.bootstrap.WeldBootstrap;
import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
import org.jboss.weld.bootstrap.spi.Deployment;
import org.jboss.weld.bootstrap.spi.Metadata;
import org.jboss.weld.util.ServiceLoader;
import org.osgi.service.log.Logger;
public class ContainerBootstrap extends Phase {
public ContainerBootstrap(
ContainerState containerState,
ConfigurationListener.Builder configurationBuilder,
SingleComponent.Builder singleBuilder,
FactoryComponent.Builder factoryBuilder) {
super(containerState, null);
_configurationBuilder = configurationBuilder;
_singleBuilder = singleBuilder;
_factoryBuilder = factoryBuilder;
_log = containerState.containerLogs().getLogger(getClass());
}
@Override
public boolean close() {
try (Syncro syncro = _lock.open()) {
if (_bootstrap != null) {
_log.debug(l -> l.debug("CCR container bootstrap shutdown on {}", _bootstrap));
_bootstrap.shutdown();
_bootstrap = null;
}
return true;
}
catch (Throwable t) {
_log.error(l -> l.error("CCR Failure in container bootstrap shutdown on {}", _bootstrap, t));
return false;
}
}
@Override
public Op closeOp() {
return Op.of(Mode.CLOSE, Type.CONTAINER_BOOTSTRAP, containerState.id());
}
@Override
public boolean open() {
try (Syncro syncro = _lock.open()) {
if (containerState.bundleContext() == null) {
// this bundle was already removed
return false;
}
if (_bootstrap != null) {
return true;
}
if (containerState.containerDTO().components.isEmpty()) {
return false;
}
List<Metadata<Extension>> extensions = new CopyOnWriteArrayList<>();
// Add the internal extensions
extensions.add(
new ExtensionMetadata(
new BundleContextExtension(containerState.bundleContext()),
containerState.id()));
extensions.add(
new ExtensionMetadata(
new RuntimeExtension(containerState, _configurationBuilder, _singleBuilder, _factoryBuilder),
containerState.id()));
extensions.add(
new ExtensionMetadata(
new LoggerExtension(containerState),
containerState.id()));
Thread currentThread = Thread.currentThread();
ClassLoader current = currentThread.getContextClassLoader();
BundleResourcesLoader.Builder builder = new BundleResourcesLoader.Builder(containerState.bundle(), containerState.extenderBundle());
try {
currentThread.setContextClassLoader(containerState.classLoader());
// Add extensions found from the bundle's class loader, such as those in the Bundle-ClassPath
ServiceLoader.load(Extension.class, containerState.classLoader()).forEach(extensions::add);
// Add external extensions
containerState.containerDTO().extensions.stream().map(
ExtendedExtensionDTO.class::cast
).map(
e -> {
builder.add(e.serviceReference.getBundle());
return new ExtensionMetadata(e.extension.getService(), e.template.serviceFilter);
}
).forEach(extensions::add);
_bootstrap = new WeldBootstrap();
BeanDeploymentArchive beanDeploymentArchive = new ContainerDeploymentArchive(
builder.build(),
containerState.id(),
containerState.beansModel().getBeanClassNames(),
containerState.beansModel().getBeansXml());
Deployment deployment = new ContainerDeployment(extensions, beanDeploymentArchive);
_bootstrap.startExtensions(extensions);
_bootstrap.startContainer(containerState.id(), new ContainerEnvironment(), deployment);
_bootstrap.startInitialization();
_bootstrap.deployBeans();
_bootstrap.validateBeans();
_bootstrap.endInitialization();
}
finally {
currentThread.setContextClassLoader(current);
}
return true;
}
}
@Override
public Op openOp() {
return Op.of(Mode.OPEN, Type.CONTAINER_BOOTSTRAP, containerState.id());
}
private volatile WeldBootstrap _bootstrap;
private final ConfigurationListener.Builder _configurationBuilder;
private final FactoryComponent.Builder _factoryBuilder;
private final SingleComponent.Builder _singleBuilder;
private final Syncro _lock = new Syncro(true);
private final Logger _log;
}