blob: c539f8ac071964376be73c420c569ca5b1592eb0 [file] [log] [blame]
= Decorators
:index-group: CDI
:jbake-type: page
:jbake-status: published
== AccessDeniedException
[source,java]
----
package org.superbiz.cdi.decorators;
import javax.ejb.ApplicationException;
/**
* @version $Revision$ $Date$
*/
@ApplicationException
public class AccessDeniedException extends RuntimeException {
public AccessDeniedException(String s) {
super(s);
}
}
----
== Calculator
[source,java]
----
package org.superbiz.cdi.decorators;
/**
* @version $Revision$ $Date$
*/
public interface Calculator {
public int add(int a, int b);
public int subtract(int a, int b);
public int multiply(int a, int b);
public int divide(int a, int b);
public int remainder(int a, int b);
}
----
== CalculatorBean
[source,java]
----
package org.superbiz.cdi.decorators;
import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.enterprise.inject.Produces;
@Stateless
public class CalculatorBean implements Calculator {
@Produces
@Resource
private SessionContext sessionContext;
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
public int multiply(int a, int b) {
return a * b;
}
public int divide(int a, int b) {
return a / b;
}
public int remainder(int a, int b) {
return a % b;
}
}
----
== CalculatorLogging
[source,java]
----
package org.superbiz.cdi.decorators;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;
import java.util.logging.Logger;
@Decorator
public class CalculatorLogging implements Calculator {
private Logger logger = Logger.getLogger("Calculator");
@Inject
@Delegate
private Calculator calculator;
@Override
public int add(int a, int b) {
logger.fine(String.format("add(%s, %s)", a, b));
return calculator.add(a, b);
}
@Override
public int subtract(int a, int b) {
return calculator.subtract(a, b);
}
@Override
public int multiply(int a, int b) {
logger.finest(String.format("multiply(%s, %s)", a, b));
return calculator.multiply(a, b);
}
@Override
public int divide(int a, int b) {
return calculator.divide(a, b);
}
@Override
public int remainder(int a, int b) {
logger.info(String.format("remainder(%s, %s)", a, b));
return calculator.remainder(a, b);
}
}
----
== CalculatorSecurity
[source,java]
----
package org.superbiz.cdi.decorators;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.ejb.SessionContext;
import javax.inject.Inject;
@Decorator
public class CalculatorSecurity implements Calculator {
@Inject
@Delegate
private Calculator calculator;
@Inject
private SessionContext sessionContext;
@Override
public int add(int a, int b) {
return calculator.add(a, b);
}
@Override
public int subtract(int a, int b) {
// Caller must pass a security check to call subtract
if (!sessionContext.isCallerInRole("Manager")) throw new AccessDeniedException(sessionContext.getCallerPrincipal().getName());
return calculator.subtract(a, b);
}
@Override
public int multiply(int a, int b) {
return calculator.multiply(a, b);
}
@Override
public int divide(int a, int b) {
return calculator.divide(a, b);
}
@Override
public int remainder(int a, int b) {
return calculator.remainder(a, b);
}
}
----
== beans.xml
[source,xml]
----
<beans>
<!--
Explicitly declaring decorators is required by the CDI specification.
The order decorators are listed in the xml is the order in which they are invoked.
-->
<decorators>
<class>org.superbiz.cdi.decorators.CalculatorSecurity</class>
<class>org.superbiz.cdi.decorators.CalculatorLogging</class>
</decorators>
</beans>
----
== CalculatorTest
[source,java]
----
package org.superbiz.cdi.decorators;
import junit.framework.TestCase;
import javax.annotation.security.RunAs;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.embeddable.EJBContainer;
import java.util.concurrent.Callable;
public class CalculatorTest extends TestCase {
@EJB
private Calculator calculator;
@EJB
private ManagerBean manager;
/**
* Bootstrap the Embedded EJB Container
*
* @throws Exception
*/
protected void setUp() throws Exception {
EJBContainer.createEJBContainer().getContext().bind("inject", this);
}
/**
* Test Add method
*/
public void testAdd() {
assertEquals(10, calculator.add(4, 6));
}
/**
* Test Subtract method
*/
public void testSubtract() {
try {
calculator.subtract(4, 6);
fail("AccessDeniedException should have been thrown for unauthenticated access");
} catch (AccessDeniedException expected) {
// pass
}
final int result = manager.call(new Callable<Integer>() {
public Integer call() {
return calculator.subtract(4, 6);
}
});
assertEquals(-2, result);
}
/**
* Test Multiply method
*/
public void testMultiply() {
assertEquals(24, calculator.multiply(4, 6));
}
/**
* Test Divide method
*/
public void testDivide() {
assertEquals(2, calculator.divide(12, 6));
}
/**
* Test Remainder method
*/
public void testRemainder() {
assertEquals(4, calculator.remainder(46, 6));
}
@Stateless
@RunAs("Manager")
public static class ManagerBean {
public <V> V call(Callable<V> callable) {
try {
return callable.call();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
----
== Running
----
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.superbiz.cdi.decorators.CalculatorTest
Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06
http://tomee.apache.org/
INFO - openejb.home = /Users/dblevins/examples/decorators
INFO - openejb.base = /Users/dblevins/examples/decorators
INFO - Using 'javax.ejb.embeddable.EJBContainer=true'
INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service)
INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager)
INFO - Found EjbModule in classpath: /Users/dblevins/examples/decorators/target/classes
INFO - Found EjbModule in classpath: /Users/dblevins/examples/decorators/target/test-classes
INFO - Beginning load: /Users/dblevins/examples/decorators/target/classes
INFO - Beginning load: /Users/dblevins/examples/decorators/target/test-classes
INFO - Configuring enterprise application: /Users/dblevins/examples/decorators
WARN - Method 'lookup' is not available for 'javax.annotation.Resource'. Probably using an older Runtime.
INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container)
INFO - Auto-creating a container for bean decorators.Comp: Container(type=MANAGED, id=Default Managed Container)
INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container)
INFO - Auto-creating a container for bean CalculatorBean: Container(type=STATELESS, id=Default Stateless Container)
INFO - Enterprise application "/Users/dblevins/examples/decorators" loaded.
INFO - Assembling app: /Users/dblevins/examples/decorators
INFO - Jndi(name="java:global/decorators/decorators.Comp!org.apache.openejb.BeanContext$Comp")
INFO - Jndi(name="java:global/decorators/decorators.Comp")
INFO - Jndi(name="java:global/decorators/CalculatorBean!org.superbiz.cdi.decorators.Calculator")
INFO - Jndi(name="java:global/decorators/CalculatorBean")
INFO - Jndi(name="java:global/decorators/ManagerBean!org.superbiz.cdi.decorators.CalculatorTest$ManagerBean")
INFO - Jndi(name="java:global/decorators/ManagerBean")
INFO - Jndi(name="java:global/EjbModule628834558/org.superbiz.cdi.decorators.CalculatorTest!org.superbiz.cdi.decorators.CalculatorTest")
INFO - Jndi(name="java:global/EjbModule628834558/org.superbiz.cdi.decorators.CalculatorTest")
INFO - Created Ejb(deployment-id=CalculatorBean, ejb-name=CalculatorBean, container=Default Stateless Container)
INFO - Created Ejb(deployment-id=decorators.Comp, ejb-name=decorators.Comp, container=Default Managed Container)
INFO - Created Ejb(deployment-id=ManagerBean, ejb-name=ManagerBean, container=Default Stateless Container)
INFO - Created Ejb(deployment-id=org.superbiz.cdi.decorators.CalculatorTest, ejb-name=org.superbiz.cdi.decorators.CalculatorTest, container=Default Managed Container)
INFO - Started Ejb(deployment-id=CalculatorBean, ejb-name=CalculatorBean, container=Default Stateless Container)
INFO - Started Ejb(deployment-id=decorators.Comp, ejb-name=decorators.Comp, container=Default Managed Container)
INFO - Started Ejb(deployment-id=ManagerBean, ejb-name=ManagerBean, container=Default Stateless Container)
INFO - Started Ejb(deployment-id=org.superbiz.cdi.decorators.CalculatorTest, ejb-name=org.superbiz.cdi.decorators.CalculatorTest, container=Default Managed Container)
INFO - Deployed Application(path=/Users/dblevins/examples/decorators)
INFO - EJBContainer already initialized. Call ejbContainer.close() to allow reinitialization
Oct 29, 2011 11:41:04 AM org.apache.webbeans.decorator.DelegateHandler invoke
SEVERE: Exception in calling method : [subtract] in decorator class : [org.superbiz.cdi.decorators.CalculatorSecurity]. Look in the log for target checked exception.
org.superbiz.cdi.decorators.AccessDeniedException: guest
at org.superbiz.cdi.decorators.CalculatorSecurity.subtract(CalculatorSecurity.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.webbeans.decorator.DelegateHandler.invoke(DelegateHandler.java:98)
at org.apache.openejb.cdi.CdiInterceptor.invoke(CdiInterceptor.java:127)
at org.apache.openejb.cdi.CdiInterceptor.access$000(CdiInterceptor.java:45)
at org.apache.openejb.cdi.CdiInterceptor$1.call(CdiInterceptor.java:66)
at org.apache.openejb.cdi.CdiInterceptor.aroundInvoke(CdiInterceptor.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163)
at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:130)
at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:226)
at org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:178)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:255)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:235)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:92)
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:284)
at $Proxy44.subtract(Unknown Source)
at org.superbiz.cdi.decorators.CalculatorTest.testSubtract(CalculatorTest.java:59)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
at $Proxy0.invoke(Unknown Source)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
INFO - EJBContainer already initialized. Call ejbContainer.close() to allow reinitialization
INFO - EJBContainer already initialized. Call ejbContainer.close() to allow reinitialization
INFO - EJBContainer already initialized. Call ejbContainer.close() to allow reinitialization
Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.338 sec
Results :
Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
[source,java]
----