/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.batchee.container.cdi;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.AfterDeploymentValidation;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.BeforeBeanDiscovery;
import javax.enterprise.inject.spi.BeforeShutdown;
import javax.enterprise.inject.spi.Extension;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
// excepted beforeBeanDiscovery() all is forked from DeltaSpike - we don't want to depend from it here
public class BatchCDIInjectionExtension implements Extension {
private static BatchCDIInjectionExtension bmpSingleton = null;
private volatile Map<ClassLoader, BeanManagerInfo> bmInfos = new ConcurrentHashMap<ClassLoader, BeanManagerInfo>();
void beforeBeanDiscovery(final @Observes BeforeBeanDiscovery bbd, BeanManager bm) {
bbd.addAnnotatedType(bm.createAnnotatedType(BatchProducerBean.class));
}
public void setBeanManager(final @Observes AfterBeanDiscovery afterBeanDiscovery, final BeanManager beanManager) {
// bean manager holder
if (bmpSingleton == null) {
bmpSingleton = this;
}
final BeanManagerInfo bmi = getBeanManagerInfo(loader());
bmi.loadTimeBm = beanManager;
}
public void cleanupFinalBeanManagers(final @Observes AfterDeploymentValidation adv) {
for (final BeanManagerInfo bmi : bmpSingleton.bmInfos.values()) {
bmi.finalBm = null;
}
}
public void cleanupStoredBeanManagerOnShutdown(final @Observes BeforeShutdown beforeShutdown) {
bmpSingleton.bmInfos.remove(loader());
}
private static ClassLoader loader() {
return Thread.currentThread().getContextClassLoader();
}
public static BatchCDIInjectionExtension getInstance() {
return bmpSingleton;
}
public BeanManager getBeanManager() {
final BeanManagerInfo bmi = getBeanManagerInfo(loader());
BeanManager result = bmi.finalBm;
if (result == null && bmi.cdi == null) {
synchronized (this) {
result = resolveBeanManagerViaJndi();
if (result == null) {
result = bmi.loadTimeBm;
}
if (result == null) {
bmi.cdi = false;
return null;
}
bmi.cdi = true;
bmi.finalBm = result;
}
}
return result;
}
private static BeanManager resolveBeanManagerViaJndi() {
try {
return BeanManager.class.cast(new InitialContext().lookup("java:comp/BeanManager"));
} catch (final NamingException e) {
return null;
}
}
private BeanManagerInfo getBeanManagerInfo(final ClassLoader cl) {
BeanManagerInfo bmi = bmpSingleton.bmInfos.get(cl);
if (bmi == null) {
synchronized (this) {
bmi = bmpSingleton.bmInfos.get(cl);
if (bmi == null) {
bmi = new BeanManagerInfo();
bmpSingleton.bmInfos.put(cl, bmi);
}
}
}
return bmi;
}
private static class BeanManagerInfo {
private BeanManager loadTimeBm = null;
private BeanManager finalBm = null;
private Boolean cdi = null;
}
}