| = 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] |
| ---- |