Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue: Injection on EJB interceptors is not working #3 #10

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>info.novatec</groupId>
<artifactId>bean-test</artifactId>
<version>0.2-SNAPSHOT</version>
<version>0.3-SNAPSHOT</version>
<name>Bean Testing</name>
<description>Java EE Bean Testing framework</description>
<url>http://blog.novatec-gmbh.de/unit-testing-jee-applications-cdi/</url>
Expand Down
14 changes: 10 additions & 4 deletions src/main/java/info/novatec/beantest/api/BeanProviderHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
*/
public class BeanProviderHelper {

private CdiContainer cdiContainer;
private static final BeanProviderHelper INSTANCE= new BeanProviderHelper();
private CdiContainer cdiContainer;
private static final BeanProviderHelper INSTANCE = new BeanProviderHelper();

public static BeanProviderHelper getInstance() {
return INSTANCE;
Expand All @@ -45,7 +45,6 @@ private void bootstrapCdiContainer() {
cdiContainer = CdiContainerLoader.getCdiContainer();
cdiContainer.boot();
cdiContainer.getContextControl().startContexts();

}


Expand Down Expand Up @@ -84,7 +83,7 @@ public BeanManager getBeanManager() {
* Shuts down the underlying container.
*/
public void shutdown() {
if (cdiContainer != null) {
if (isCdiContainerRunning()) {
try {
fireShutdownEvent();
} finally {
Expand All @@ -95,6 +94,13 @@ public void shutdown() {
}
}

/**
* Checks if the underlying BeanContainer is started and running.
*/
private boolean isCdiContainerRunning() {
return cdiContainer != null && cdiContainer.getBeanManager() != null;
}

/**
* Fires a {@link ContainerShutdown} CDI event before the CDI container shuts down in order to clean up resources (for example an
* EntityManager).
Expand Down
156 changes: 156 additions & 0 deletions src/main/java/info/novatec/beantest/extension/BaseExtension.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* Bean Testing.
*
* 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 info.novatec.beantest.extension;

import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider;
import org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder;
import org.jboss.weld.exceptions.DefinitionException;

import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.enterprise.inject.spi.*;
import javax.inject.Inject;
import javax.persistence.PersistenceContext;
import java.util.ArrayList;
import java.util.List;

/**
* Base CDI Extension to modify bean meta data. Provides altogether with various utility methods the essential bean
* meta data functionality.
* <p>
* <b>Potential new CDI extension should extend BaseExtension and moreover listed in /src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension</b>
* @param <X> the type of the annotated type
* @author Carlos Barragan ([email protected])
* @author Qaiser Abbasi ([email protected])
*/
public abstract class BaseExtension<X> implements Extension {

/**
* Adds the {@link Inject} annotation to the fields and setters of the annotated type if required.
*
* @param annotatedType
* the annotated type whose fields and setters the inject annotation should be added to
* @param builder
* the builder that should be used to add the annotation.
* @see #shouldInjectionAnnotationBeAddedToMember(AnnotatedField) and #shouldInjectionAnnotationBeAddedToMethod(AnnotatedMethod)
*/
protected void addInjectAnnotationOnProcessedType(final AnnotatedType<X> annotatedType, AnnotatedTypeBuilder<X> builder) {
new InjectionPointReplacement<X>(annotatedType, builder).performReplacements();
}

/**
* Creates an AnnotatedTypeBuilder from the provided AnnotatedType
* @param annotatedType the processed bean
* @return AnnotatedTypeBuilder based on annotatedType
*/
protected AnnotatedTypeBuilder<X> createTypeBuilderFrom(AnnotatedType<X> annotatedType) {
return new AnnotatedTypeBuilder<X>().readFromType(annotatedType);
}

/**
* This class is responsible for transforming {@link EJB}, {@link PersistenceContext} or {@link Resource} injection points into correlating {@link Inject} dependency definitions.
* <p>
* Furthermore this class ensures that the processed bean holds valid dependency injection points for its member i.e. the processed bean may hold exclusively field injection points
* or setter injection points for a particular member.
* <p>
* By way of example the {@link InvalidInjectionPointConfigurationEJB} holds an invalid dependency configuration.
* @author Qaiser Abbasi ([email protected])
*
*/
private static class InjectionPointReplacement<X> {

private static final String SETTER_METHOD_PREFIX = "set";

private static final int FIELD_NAME_INDEX = 1;

private static final Inject INJECT_ANNOTATION = AnnotationInstanceProvider.of(Inject.class);

private List<String> processedFieldInjections = new ArrayList<String>();

private final AnnotatedType<X> annotatedType;

private final AnnotatedTypeBuilder<X> builder;

public InjectionPointReplacement(AnnotatedType<X> annotatedType, AnnotatedTypeBuilder<X> builder) {
this.annotatedType = annotatedType;
this.builder = builder;
}

/**
* Returns <code>true</code> if the member is NOT annotated with {@link Inject} and is annotated with one of the following annotations:
* <ul>
* <li> {@link EJB}
* <li> {@link PersistenceContext}
* <li> {@link Resource}
* </ul>
* Otherwise, it returns <code>false</code>.
*
* @param member
* the annotated member whose annotations should be verified
* @return <code>true</code> if the member is NOT annotated with {@link Inject} and is annotated with {@link EJB},
* {@link PersistenceContext} or {@link Resource}
*/
private boolean shouldInjectionAnnotationBeAddedToMember(AnnotatedMember<? super X> member) {
return ! member.isAnnotationPresent(Inject.class) && (member.isAnnotationPresent(Resource.class)
|| member.isAnnotationPresent(EJB.class) || member.isAnnotationPresent(PersistenceContext.class));
}

/**
* This method performs the actual injection point transformation while ensuring that the processed bean comprise a valid dependency configuration.
*/
public void performReplacements() {
for (AnnotatedField<? super X> field : annotatedType.getFields()) {
if (shouldInjectionAnnotationBeAddedToMember(field)) {
builder.addToField(field, INJECT_ANNOTATION);
processedFieldInjections.add(field.getJavaMember().getName());
}
}

for (AnnotatedMethod<? super X> method : annotatedType.getMethods()) {
if (shouldInjectionAnnotationBeAddedToMember(method)) {
validateDependencyConfiguration(method);
builder.addToMethod(method, INJECT_ANNOTATION);
}
}
}

/**
* Check if there is already a processed field injection point for the corresponding member. If so, the setter injection method for the given member is not legal.
* The invalid dependency configuration lead towards to a deployment exception.
* @param method Represent the suffix-name of the corresponding setter injection method in the processed bean.
* @throws DefinitionException Occurs if there is already a processed field for the given member.
*/
private void validateDependencyConfiguration(AnnotatedMethod<? super X> method) {
if(method.getJavaMember().getName().startsWith(SETTER_METHOD_PREFIX)){
String methodSuffixName = method.getJavaMember().getName().split(SETTER_METHOD_PREFIX)[FIELD_NAME_INDEX];
if(isInjectionPointAlreadyProcessed(methodSuffixName)){
throw new DefinitionException(String.format("Invalid dependency definition in declaring class: %s."
+ " Found duplicate injection points for method %s and corresponding field",
annotatedType, method.getJavaMember().getName()));
}
}
}

private boolean isInjectionPointAlreadyProcessed(String methodSuffixName) {
for (String processedField : processedFieldInjections) {
if (processedField.equalsIgnoreCase(methodSuffixName)) {
return true;
}
}
return false;
}
}
}
176 changes: 0 additions & 176 deletions src/main/java/info/novatec/beantest/extension/BeanTestExtension.java

This file was deleted.

Loading