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.
/*
* JBoss, Home of Professional Open Source
* Copyright 2012, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* 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.jboss.weld.bootstrap;
import static org.jboss.weld.util.reflection.Reflections.cast;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import javax.enterprise.inject.spi.Bean;
import org.jboss.weld.bean.AbstractBean;
import org.jboss.weld.bean.AbstractClassBean;
import org.jboss.weld.bean.AbstractProducerBean;
import org.jboss.weld.bean.ProducerMethod;
import org.jboss.weld.bean.RIBean;
import org.jboss.weld.bootstrap.api.helpers.AbstractBootstrapService;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.util.Function;
import org.jboss.weld.util.cache.ComputingCache;
import org.jboss.weld.util.cache.ComputingCacheBuilder;
import org.jboss.weld.util.collections.ImmutableMap;
import org.jboss.weld.util.collections.ImmutableSet;
/**
* Holds information about specialized beans.
*
* @author Jozef Hartinger
*
*/
public class SpecializationAndEnablementRegistry extends AbstractBootstrapService {
private class SpecializedBeanResolverForBeanManager implements Function {
@Override
public SpecializedBeanResolver apply(BeanManagerImpl manager) {
return new SpecializedBeanResolver(buildAccessibleBeanDeployerEnvironments(manager));
}
private Set buildAccessibleBeanDeployerEnvironments(BeanManagerImpl manager) {
Set result = new HashSet();
result.add(environmentByManager.get(manager));
buildAccessibleBeanDeployerEnvironments(manager, result);
return result;
}
private void buildAccessibleBeanDeployerEnvironments(BeanManagerImpl manager, Collection result) {
for (BeanManagerImpl accessibleManager : manager.getAccessibleManagers()) {
BeanDeployerEnvironment environment = environmentByManager.get(accessibleManager);
if (!result.contains(environment)) {
result.add(environment);
buildAccessibleBeanDeployerEnvironments(accessibleManager, result);
}
}
}
}
private class BeansSpecializedByBean implements Function, Set extends AbstractBean, ?>>> {
@Override
public Set extends AbstractBean, ?>> apply(Bean> specializingBean) {
Set extends AbstractBean, ?>> result = null;
if (specializingBean instanceof AbstractClassBean>) {
result = apply((AbstractClassBean>) specializingBean);
}
if (specializingBean instanceof ProducerMethod, ?>) {
result = apply((ProducerMethod, ?>) specializingBean);
}
if (result != null) {
if (isEnabledInAnyBeanDeployment(specializingBean)) {
for (AbstractBean, ?> specializedBean : result) {
AtomicLong value = specializedBeansMap.get(specializedBean);
if (value == null) {
value = new AtomicLong(0);
AtomicLong previous = specializedBeansMap.putIfAbsent(specializedBean, value);
if (previous != null) {
value = previous;
}
}
value.incrementAndGet();
}
}
return result;
}
throw new IllegalArgumentException("Unsupported bean type " + specializingBean);
}
private Set> apply(AbstractClassBean> bean) {
return getSpecializedBeanResolver(bean).resolveSpecializedBeans(bean);
}
private Set> apply(ProducerMethod, ?> bean) {
return getSpecializedBeanResolver(bean).resolveSpecializedBeans(bean);
}
private SpecializedBeanResolver getSpecializedBeanResolver(RIBean> bean) {
return specializedBeanResolvers.getValue(bean.getBeanManager());
}
}
private final ComputingCache specializedBeanResolvers;
private final Map environmentByManager = new ConcurrentHashMap();
// maps specializing beans to the set of specialized beans
private final ComputingCache, Set extends AbstractBean, ?>>> specializedBeans;
// fast lookup structure that allows us to figure out if a given bean is specialized in any of the bean deployments
private final ConcurrentHashMap, AtomicLong> specializedBeansMap = new ConcurrentHashMap, AtomicLong>();
public SpecializationAndEnablementRegistry() {
ComputingCacheBuilder cacheBuilder = ComputingCacheBuilder.newBuilder();
this.specializedBeanResolvers = cacheBuilder.build(new SpecializedBeanResolverForBeanManager());
this.specializedBeans = cacheBuilder.build(new BeansSpecializedByBean());
}
/**
* Returns a set of beans specialized by this bean. An empty set is returned if this bean does not specialize another beans.
*/
public Set extends AbstractBean, ?>> resolveSpecializedBeans(Bean> specializingBean) {
if (specializingBean instanceof AbstractClassBean>) {
AbstractClassBean> abstractClassBean = (AbstractClassBean>) specializingBean;
if (abstractClassBean.isSpecializing()) {
return specializedBeans.getValue(specializingBean);
}
}
if (specializingBean instanceof ProducerMethod, ?>) {
ProducerMethod, ?> producerMethod = (ProducerMethod, ?>) specializingBean;
if (producerMethod.isSpecializing()) {
return specializedBeans.getValue(specializingBean);
}
}
return Collections.emptySet();
}
public void vetoSpecializingBean(Bean> bean) {
Set extends AbstractBean, ?>> noLongerSpecializedBeans = specializedBeans.getValueIfPresent(bean);
if (noLongerSpecializedBeans != null) {
specializedBeans.invalidate(bean);
for (AbstractBean, ?> noLongerSpecializedBean : noLongerSpecializedBeans) {
// We should never get null here but just to be sure
AtomicLong count = specializedBeansMap.get(noLongerSpecializedBean);
if (count != null) {
count.decrementAndGet();
}
}
}
}
public boolean isSpecializedInAnyBeanDeployment(Bean> bean) {
AtomicLong count = specializedBeansMap.get(bean);
return count != null && count.longValue() > 0;
}
public boolean isEnabledInAnyBeanDeployment(Bean> bean) {
for (BeanManagerImpl manager : environmentByManager.keySet()) {
if (manager.isBeanEnabled(bean)) {
return true;
}
}
return false;
}
public boolean isCandidateForLifecycleEvent(Bean> bean) {
if (bean instanceof AbstractProducerBean, ?, ?>) {
AbstractProducerBean, ?, ?> producer = cast(bean);
if (!isCandidateForLifecycleEvent(producer.getDeclaringBean())) {
return false;
}
}
return isEnabledInAnyBeanDeployment(bean) && !isSpecializedInAnyBeanDeployment(bean);
}
public void registerEnvironment(BeanManagerImpl manager, BeanDeployerEnvironment environment, boolean additionalBeanArchive) {
if ((specializedBeanResolvers.size() > 0) && !additionalBeanArchive) {
/*
* An environment should not be added after we started resolving specialized beans. However we cannot avoid that completely
* in certain situations e.g. when a bean is added through AfterBeanDiscovery (otherwise a chicken-egg problem emerges between
* determining which beans are enabled which is needed for firing ProcessBean events and resolving specialization of AfterBeanDiscovery-added beans)
*
* As a result beans added through AfterBeanDiscovery cannot be specialized.
*/
throw new IllegalStateException(this.getClass().getName() + ".registerEnvironment() must not be called after specialization resolution begins");
}
if (environment == null) {
throw new IllegalArgumentException("Environment must not be null");
}
this.environmentByManager.put(manager, environment);
}
@Override
public void cleanupAfterBoot() {
specializedBeanResolvers.clear();
environmentByManager.clear();
specializedBeans.clear();
specializedBeansMap.clear();
}
public Set> getBeansSpecializedInAnyDeployment() {
return ImmutableSet.copyOf(specializedBeansMap.keySet());
}
public Map, Long> getBeansSpecializedInAnyDeploymentAsMap() {
Set, AtomicLong>> entrySet = specializedBeansMap.entrySet();
Map, Long> resultingMap = new HashMap<>();
for (Entry, AtomicLong> entry : entrySet) {
resultingMap.put(entry.getKey(), entry.getValue().longValue());
}
return ImmutableMap.copyOf(resultingMap);
}
}