Skip to content

Commit

Permalink
WELDX-135 update default bean implementation
Browse files Browse the repository at this point in the history
- Default beans may now have observers and producers

Default beans are now implemented in a similar way to generic
beans, a synthetic qualifier is added to all default beans and
a forwarding bean is re-added later if the default bean needs
to be installed.
  • Loading branch information
stuartwdouglas authored and pmuir committed Sep 22, 2010
1 parent c3052e0 commit 8f094eb
Show file tree
Hide file tree
Showing 28 changed files with 1,583 additions and 123 deletions.
@@ -0,0 +1,125 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2010, 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.extensions.defaultbean;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;

import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.PassivationCapable;

import org.jboss.weld.extensions.bean.ForwardingBean;

/**
* A helper class for implementing default bean functionality
*
* @author Stuart Douglas
*
*/
abstract class AbstactDefaultBean<T> extends ForwardingBean<T> implements PassivationCapable
{

private final Bean<T> delegate;
private final Set<Annotation> qualifiers;
private final Set<Type> types;
private final BeanManager beanManager;
private final Type declaringBeanType;

protected AbstactDefaultBean(Bean<T> delegate, Type declaringBeanType, Set<Type> types, Set<Annotation> qualifiers, BeanManager beanManager)
{
this.delegate = delegate;
this.beanManager = beanManager;
this.qualifiers = new HashSet<Annotation>(qualifiers);
this.types = new HashSet<Type>(types);
this.declaringBeanType = declaringBeanType;
}

protected BeanManager getBeanManager()
{
return beanManager;
}

@Override
protected Bean<T> delegate()
{
return delegate;
}

protected Type getDeclaringBeanType()
{
return declaringBeanType;
}

@Override
public Set<Annotation> getQualifiers()
{
return qualifiers;
}

public String getId()
{
if (delegate instanceof PassivationCapable)
{
return DefaultBean.class.getName() + "-" + ((PassivationCapable) delegate).getId();
}
return DefaultBean.class.getName() + "-" + types.toString() + "-QUALIFIERS-" + delegate.getQualifiers().toString();
}

@Override
public String toString()
{
return "Default Bean with types " + types + " and qualifiers " + qualifiers;
}

@Override
public int hashCode()
{
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((qualifiers == null) ? 0 : qualifiers.hashCode());
result = prime * result + ((types == null) ? 0 : types.hashCode());
return result;
}

@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (getClass() != obj.getClass())
return false;
AbstactDefaultBean other = (AbstactDefaultBean) obj;
if (qualifiers == null)
{
if (other.qualifiers != null)
return false;
}
else if (!qualifiers.equals(other.qualifiers))
return false;
if (types == null)
{
if (other.types != null)
return false;
}
else if (!types.equals(other.types))
return false;
return delegate.equals(other.delegate);
}
}
@@ -0,0 +1,76 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2010, 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.extensions.defaultbean;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Set;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;

import org.jboss.weld.extensions.bean.Beans;

/**
* A helper class for implementing producer methods and fields on default beans
*
* @author Stuart Douglas
*
*/
abstract class AbstractDefaultProducerBean<T> extends AbstactDefaultBean<T>
{

private static final Annotation[] NO_QUALIFIERS = {};

private final Type declaringBeanType;
private final Annotation[] declaringBeanQualifiers;

protected AbstractDefaultProducerBean(Bean<T> delegate, Type declaringBeanType, Set<Type> types, Set<Annotation> qualifiers, Set<Annotation> declaringBeanQualifiers, BeanManager beanManager)
{
super(delegate, declaringBeanType, types, qualifiers, beanManager);
this.declaringBeanType = delegate.getBeanClass();
this.declaringBeanQualifiers = declaringBeanQualifiers.toArray(NO_QUALIFIERS);
}

protected Annotation[] getDeclaringBeanQualifiers()
{
return declaringBeanQualifiers.clone();
}

protected Type getDeclaringBeanType()
{
return declaringBeanType;
}

protected abstract T getValue(Object receiver, CreationalContext<T> creationalContext);

@Override
public T create(CreationalContext<T> creationalContext)
{
Object receiver = getReceiver(creationalContext);
T instance = getValue(receiver, creationalContext);
Beans.checkReturnValue(instance, this, null, getBeanManager());
return instance;
}

protected Object getReceiver(CreationalContext<T> creationalContext)
{
Bean<?> declaringBean = getBeanManager().resolve(getBeanManager().getBeans(getDeclaringBeanType(), declaringBeanQualifiers));
return getBeanManager().getReference(declaringBean, declaringBean.getBeanClass(), creationalContext);
}
}
Expand Up @@ -28,12 +28,17 @@
/**
* Annotation that signifies that a bean should only be registered if no other
* instance with the same type and qualifiers is registered. The bean only has
* the type specified in the type() attribute.
* the type specified in the value() attribute and java.lang.Object.
*
* A default bean must be a Managed Bean.
* Managed beans, producer methods and producer fields can all be made into
* default beans.
*
* If a managed bean is declared to be a default bean then all producers methods
* and fields on the bean are also considered to be default beans. In this case
* if the @DefaultBean annotation is not explicitly specified then the default
* bean type is considered to be the type returned by getGenericTypeReturnType
* for a method and getGenericType for a field.
*
* IMPORTANT: Producers, Disposes and Observes on the bean class will not be
* registered, and will not work
*
* In some ways this is similar to the functionality provided by
* {@link Alternative} however there are some important distinctions
Expand All @@ -44,22 +49,22 @@
* </ul>
*
* It is also important to note that beans registered in the
* {@link AfterBeanDiscovery} event may not been see by this extension
* {@link AfterBeanDiscovery} event may not been see by this extension.
*
* @author Stuart Douglas
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Target( { ElementType.TYPE, ElementType.METHOD, ElementType.FIELD })
@Documented
public @interface DefaultBean
{
/**
* The type of the bean. If another bean is found with this type and the same
* qualifiers this bean will not be installed.
*
* This bean will only be installed with the type specified here, not
* This bean will only be installed with the type specified here
*
*/
public Class<?> type();
public Class<?> value();
}

This file was deleted.

0 comments on commit 8f094eb

Please sign in to comment.