Skip to content

Commit

Permalink
WELD-1766 Differentiate between caching and non-caching client proxies
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelk authored and jharting committed Nov 6, 2014
1 parent 3b3b658 commit b44d9a0
Show file tree
Hide file tree
Showing 8 changed files with 291 additions and 3 deletions.
Expand Up @@ -135,7 +135,7 @@ public T create(BeanInstance beanInstance) {
@Override
protected void addFields(final ClassFile proxyClassType, List<DeferredBytecode> initialValueBytecode) {
super.addFields(proxyClassType, initialValueBytecode);
if (CACHEABLE_SCOPES.contains(getBean().getScope())) {
if (useCache()) {
try {
proxyClassType.addField(AccessFlag.TRANSIENT | AccessFlag.PRIVATE, CACHE_FIELD, LJAVA_LANG_THREAD_LOCAL);
initialValueBytecode.add(new DeferredBytecode() {
Expand Down Expand Up @@ -205,7 +205,7 @@ protected void createForwardingMethodBody(ClassMethod classMethod, MethodInforma

final Class<? extends Annotation> scope = getBean().getScope();

if (CACHEABLE_SCOPES.contains(scope)) {
if (useCache()) {
loadCacheableBeanInstance(classMethod.getClassFile(), methodInfo, b);
} else {
loadBeanInstance(classMethod.getClassFile(), methodInfo, b);
Expand Down Expand Up @@ -353,7 +353,10 @@ protected void generateEqualsMethod(ClassFile proxyClassType) {

@Override
protected String getProxyNameSuffix() {
return CLIENT_PROXY_SUFFIX;
return (useCache() ? "Caching" : "") + CLIENT_PROXY_SUFFIX;
}

private boolean useCache() {
return CACHEABLE_SCOPES.contains(getBean().getScope());
}
}
@@ -0,0 +1,87 @@
/*
* 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.tests.proxy.weld1766;

import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.Contextual;
import javax.enterprise.context.spi.CreationalContext;
import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static org.junit.Assert.assertTrue;

public class CustomContext implements Context {

private boolean active = false;

private static class Instance {
private final Object instance;
private final CreationalContext<?> ctx;

public Instance(Object instance, CreationalContext<?> ctx) {
this.instance = instance;
this.ctx = ctx;
}
}

private final Map<Contextual<?>, Instance> storage = new ConcurrentHashMap<Contextual<?>, Instance>();

@Override
public Class<? extends Annotation> getScope() {
return CustomScoped.class;
}

@Override
public <T> T get(Contextual<T> contextual, CreationalContext<T> creationalContext) {
T instance = get(contextual);
if (instance == null) {
storage.put(contextual, new Instance(contextual.create(creationalContext), creationalContext));
instance = get(contextual);
}
return instance;
}

@Override
@SuppressWarnings("unchecked")
public <T> T get(Contextual<T> contextual) {
Instance instance = storage.get(contextual);
if (instance != null) {
return (T) instance.instance;
}
return null;
}

@Override
public boolean isActive() {
return active;
}

public void activate() {
active = true;
}

public void deactivate() {
active = false;
for (Map.Entry<Contextual<?>, Instance> contextualInstanceEntry : storage.entrySet()) {
Contextual contextual = contextualInstanceEntry.getKey();
Instance instance = contextualInstanceEntry.getValue();
contextual.destroy(instance.instance, instance.ctx);
}
storage.clear();
}
}
@@ -0,0 +1,35 @@
/*
* 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.tests.proxy.weld1766;

import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.Extension;

public class CustomScopeExtension implements Extension {

private final CustomContext context = new CustomContext();

void registerContext(@Observes AfterBeanDiscovery event) {
event.addContext(context);
}

public CustomContext getContext() {
return context;
}

}
@@ -0,0 +1,33 @@
/*
* 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.tests.proxy.weld1766;

import javax.enterprise.context.NormalScope;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@NormalScope(passivating = true)
@Inherited
@Target({ TYPE, METHOD, FIELD })
@Retention(RUNTIME)
public @interface CustomScoped {

}
@@ -0,0 +1,87 @@
/*
* 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.tests.proxy.weld1766;

import junit.framework.Assert;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.BeanArchive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.junit.Test;
import org.junit.runner.RunWith;

import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Extension;
import javax.inject.Inject;

/**
* Tests for https://issues.jboss.org/browse/CDI-9999
*
* @author Marcel Kolsteren
*
*/
@RunWith(Arquillian.class)
public class ProducerProxyTest {

@Deployment
public static Archive<?> getDeployment() {
return ShrinkWrap.create(BeanArchive.class).addPackage(ProducerProxyTest.class.getPackage())
.addAsServiceProvider(Extension.class, CustomScopeExtension.class);
}

@Inject
private BeanManager manager;

@Inject
@Qualifier1
private TestComponent requestScopedComponent;

@Inject
@Qualifier2
private TestComponent customScopedComponent;

@Produces
@Qualifier1
@RequestScoped
public TestComponent produceRequestScopedComponent() {
return new TestComponent();
}

@Produces
@Qualifier2
@CustomScoped
public TestComponent produceCustomScopedComponent() {
return new TestComponent();
}

@Inject
private CustomScopeExtension customScopeExtension;

@Test
public void testCustomScopedComponent() {
customScopeExtension.getContext().activate();
customScopedComponent.setValue("test");
customScopeExtension.getContext().deactivate();

customScopeExtension.getContext().activate();
Assert.assertNull(customScopedComponent.getValue());
customScopeExtension.getContext().deactivate();
}
}
@@ -0,0 +1,14 @@
package org.jboss.weld.tests.proxy.weld1766;

import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ METHOD, FIELD, PARAMETER, TYPE })
public @interface Qualifier1 {
}
@@ -0,0 +1,14 @@
package org.jboss.weld.tests.proxy.weld1766;

import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ METHOD, FIELD, PARAMETER, TYPE })
public @interface Qualifier2 {
}
@@ -0,0 +1,15 @@
package org.jboss.weld.tests.proxy.weld1766;

import java.io.Serializable;

public class TestComponent implements Serializable {
private String value;

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}
}

0 comments on commit b44d9a0

Please sign in to comment.