http://git-wip-us.apache.org/repos/asf/tomee-tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/custom-injection.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/custom-injection.adoc b/src/main/jbake/content/examples/custom-injection.adoc new file mode 100755 index 0000000..7edf520 --- /dev/null +++ b/src/main/jbake/content/examples/custom-injection.adoc @@ -0,0 +1,256 @@ += Custom Injection +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example custom-injection can be browsed at https://github.com/apache/tomee/tree/master/examples/custom-injection + + +*Help us document this example! Click the blue pencil icon in the upper right to edit this page.* + +== Pickup + + +[source,java] +---- +package org.superbiz.enventries; + + +//START SNIPPET: code + +import java.beans.PropertyEditorManager; + +public enum Pickup { + + HUMBUCKER, + SINGLE_COIL; + + // Here's the little magic where we register the PickupEditor + // which knows how to create this object from a string. + // You can add any of your own Property Editors in the same way. + static { + PropertyEditorManager.registerEditor(Pickup.class, PickupEditor.class); + } +} +---- + + +== PickupEditor + + +[source,java] +---- +package org.superbiz.enventries; + +/** + * With a java.beans.PropertyEditor, you can go way beyond the built-in + * types that OpenEJB supports and can extend dependency injection to + * just about anywhere. + * <p/> + * In the world of electric guitars, two types of pickups are used: humbucking, and single-coil. + * Guitarists often refer to their guitars as HSS, meaning a guitar with 1 humbucker and + * 2 single coil pickups, and so on. This little PropertyEditor supports that shorthand notation. + * + * @version $Revision$ $Date$ + */ +//START SNIPPET: code +public class PickupEditor extends java.beans.PropertyEditorSupport { + + public void setAsText(String text) throws IllegalArgumentException { + text = text.trim(); + + if (text.equalsIgnoreCase("H")) setValue(Pickup.HUMBUCKER); + else if (text.equalsIgnoreCase("S")) setValue(Pickup.SINGLE_COIL); + else throw new IllegalStateException("H and S are the only supported Pickup aliases"); + } +} +---- + + +== Stratocaster + + +[source,java] +---- +package org.superbiz.enventries; + +import javax.annotation.Resource; +import javax.ejb.Stateless; +import java.io.File; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * In addition to the standard env-entry types (String, Integer, Long, Short, Byte, Boolean, Double, Float, Character) + * OpenEJB supports many other types. + */ +//START SNIPPET: code +@Stateless +public class Stratocaster { + + + @Resource(name = "pickups") + private List<Pickup> pickups; + + @Resource(name = "style") + private Style style; + + @Resource(name = "dateCreated") + private Date dateCreated; + + @Resource(name = "guitarStringGuages") + private Map<String, Float> guitarStringGuages; + + @Resource(name = "certificateOfAuthenticity") + private File certificateOfAuthenticity; + + public Date getDateCreated() { + return dateCreated; + } + + /** + * Gets the guage of the electric guitar strings + * used in this guitar. + * + * @param string + * @return + */ + public float getStringGuage(String string) { + return guitarStringGuages.get(string); + } + + public List<Pickup> getPickups() { + return pickups; + } + + public Style getStyle() { + return style; + } + + public File getCertificateOfAuthenticity() { + return certificateOfAuthenticity; + } +} +---- + + +== Style + + +[source,java] +---- +package org.superbiz.enventries; + +/** + * @version $Revision$ $Date$ + */ +//START SNIPPET: code +public enum Style { + + STANDARD, + DELUX, + VINTAGE; +} +---- + + +== StratocasterTest + + +[source,java] +---- +package org.superbiz.enventries; + +import junit.framework.TestCase; + +import javax.ejb.EJB; +import javax.ejb.embeddable.EJBContainer; +import java.io.File; +import java.text.DateFormat; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import static java.util.Arrays.asList; + +/** + * @version $Rev: 1090810 $ $Date: 2011-04-10 07:49:26 -0700 (Sun, 10 Apr 2011) $ + */ +//START SNIPPET: code +public class StratocasterTest extends TestCase { + + @EJB + private Stratocaster strat; + + public void test() throws Exception { + EJBContainer.createEJBContainer().getContext().bind("inject", this); + + Date date = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US).parse("Mar 1, 1962"); + assertEquals("Strat.getDateCreated()", date, strat.getDateCreated()); + + List<Pickup> pickups = asList(Pickup.SINGLE_COIL, Pickup.SINGLE_COIL, Pickup.SINGLE_COIL); + assertEquals("Strat.getPickups()", pickups, strat.getPickups()); + + assertEquals("Strat.getStyle()", Style.VINTAGE, strat.getStyle()); + + assertEquals("Strat.getStringGuage(\"E1\")", 0.052F, strat.getStringGuage("E1")); + assertEquals("Strat.getStringGuage(\"A\")", 0.042F, strat.getStringGuage("A")); + assertEquals("Strat.getStringGuage(\"D\")", 0.030F, strat.getStringGuage("D")); + assertEquals("Strat.getStringGuage(\"G\")", 0.017F, strat.getStringGuage("G")); + assertEquals("Strat.getStringGuage(\"B\")", 0.013F, strat.getStringGuage("B")); + assertEquals("Strat.getStringGuage(\"E\")", 0.010F, strat.getStringGuage("E")); + + File file = new File("/tmp/strat-certificate.txt"); + assertEquals("Strat.getCertificateOfAuthenticity()", file, strat.getCertificateOfAuthenticity()); + + } +} +---- + + += Running + + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.enventries.StratocasterTest +Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06 +http://tomee.apache.org/ +INFO - openejb.home = /Users/dblevins/examples/custom-injection +INFO - openejb.base = /Users/dblevins/examples/custom-injection +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/custom-injection/target/classes +INFO - Beginning load: /Users/dblevins/examples/custom-injection/target/classes +INFO - Configuring enterprise application: /Users/dblevins/examples/custom-injection +WARN - Method 'lookup' is not available for 'javax.annotation.Resource'. Probably using an older Runtime. +INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) +INFO - Auto-creating a container for bean Stratocaster: Container(type=STATELESS, id=Default Stateless Container) +INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) +INFO - Auto-creating a container for bean org.superbiz.enventries.StratocasterTest: Container(type=MANAGED, id=Default Managed Container) +INFO - Enterprise application "/Users/dblevins/examples/custom-injection" loaded. +INFO - Assembling app: /Users/dblevins/examples/custom-injection +INFO - Jndi(name="java:global/custom-injection/Stratocaster!org.superbiz.enventries.Stratocaster") +INFO - Jndi(name="java:global/custom-injection/Stratocaster") +INFO - Jndi(name="java:global/EjbModule1663626738/org.superbiz.enventries.StratocasterTest!org.superbiz.enventries.StratocasterTest") +INFO - Jndi(name="java:global/EjbModule1663626738/org.superbiz.enventries.StratocasterTest") +INFO - Created Ejb(deployment-id=Stratocaster, ejb-name=Stratocaster, container=Default Stateless Container) +INFO - Created Ejb(deployment-id=org.superbiz.enventries.StratocasterTest, ejb-name=org.superbiz.enventries.StratocasterTest, container=Default Managed Container) +INFO - Started Ejb(deployment-id=Stratocaster, ejb-name=Stratocaster, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=org.superbiz.enventries.StratocasterTest, ejb-name=org.superbiz.enventries.StratocasterTest, container=Default Managed Container) +INFO - Deployed Application(path=/Users/dblevins/examples/custom-injection) +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.11 sec + +Results : + +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 +---- + +
http://git-wip-us.apache.org/repos/asf/tomee-tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/datasource-ciphered-password.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/datasource-ciphered-password.adoc b/src/main/jbake/content/examples/datasource-ciphered-password.adoc new file mode 100755 index 0000000..f5584e2 --- /dev/null +++ b/src/main/jbake/content/examples/datasource-ciphered-password.adoc @@ -0,0 +1,228 @@ += DataSource Ciphered Password +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example datasource-ciphered-password can be browsed at https://github.com/apache/tomee/tree/master/examples/datasource-ciphered-password + + += Datasource Ciphered Password example + +This example shows how to use a ciphered password with an OpenEJB datasource. + +It shows how to implement its own encryption too. + += Configuration + +The configuration is simply a datasource configuration with an additionnal parameter +"PasswordCipher" to specify the encryption to use. + +Example using Static3DES encryption: + + properties.setProperty("ProtectedDatasource", "new://Resource?type=DataSource"); + properties.setProperty("ProtectedDatasource.JdbcDriver", "org.hsqldb.jdbcDriver"); + properties.setProperty("ProtectedDatasource.JdbcUrl", "jdbc:hsqldb:mem:protected"); + properties.setProperty("ProtectedDatasource.UserName", "user"); + // the plain text password is "YouLLN3v3rFindM3" + properties.setProperty("ProtectedDatasource.Password", "fEroTNXjaL5SOTyRQ92x3DNVS/ksbtgs"); + properties.setProperty("ProtectedDatasource.PasswordCipher", "Static3DES"); + properties.setProperty("ProtectedDatasource.JtaManaged", "true"); + + += Using its own implementation + +The example implement a reverse encryption which simply reverse the password to encrypt/decrypt. + +The implementation is done with commons-lang library: + + +[source,java] +---- +public static class ReverseEncryption implements PasswordCipher { + @Override public char[] encrypt(String plainPassword) { + return StringUtils.reverse(plainPassword).toCharArray(); + } + + @Override public String decrypt(char[] encryptedPassword) { + return new String(encrypt(new String(encryptedPassword))); + } +} +---- + + + +To be functional it needs the file `META-INF/org.apache.openejb.resource.jdbc.PasswordCipher/reverse`. + +The file name (reverse) define the encryption name to use for the PasswordCipher parameter. + +This file simply contains the implementation class of the encryption. + +Then you simply declare this encryption for your datasource: + + properties.setProperty("ProtectedDatasource", "new://Resource?type=DataSource"); + properties.setProperty("ProtectedDatasource.JdbcDriver", "org.hsqldb.jdbcDriver"); + properties.setProperty("ProtectedDatasource.JdbcUrl", "jdbc:hsqldb:mem:protected"); + properties.setProperty("ProtectedDatasource.UserName", USER); + properties.setProperty("ProtectedDatasource.Password", "3MdniFr3v3NLLuoY"); + properties.setProperty("ProtectedDatasource.PasswordCipher", "reverse"); + properties.setProperty("ProtectedDatasource.JtaManaged", "true"); + += Documentation + +For more information please see the link:http://tomee.apache.org/3.0/datasource-password-encryption.html[documentation] + += Full Test Source + + +[source,java] +---- +package org.superbiz; + +import org.apache.commons.lang.StringUtils; +import org.apache.openejb.resource.jdbc.PasswordCipher; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.annotation.Resource; +import javax.ejb.embeddable.EJBContainer; +import javax.naming.Context; +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; +import java.util.Properties; + +import static junit.framework.Assert.assertNotNull; + +public class DataSourceCipheredExampleTest { + private static final String USER = DataSourceCipheredExampleTest.class.getSimpleName().toUpperCase(); + private static final String PASSWORD = "YouLLN3v3rFindM3"; + private static final String DATASOURCE_URL = "jdbc:hsqldb:mem:protected"; + + @Resource + private DataSource dataSource; + + @BeforeClass + public static void addDatabaseUserWithPassword() throws Exception { + Class.forName("org.hsqldb.jdbcDriver"); + Connection conn = DriverManager.getConnection(DATASOURCE_URL, "sa", ""); + conn.setAutoCommit(true); + Statement st = conn.createStatement(); + st.executeUpdate("CREATE USER " + USER + " PASSWORD '" + PASSWORD + "';"); + st.close(); + conn.commit(); + conn.close(); + } + + @Test + public void accessDatasource() throws Exception { + // define the datasource + Properties properties = new Properties(); + properties.setProperty("ProtectedDatasource", "new://Resource?type=DataSource"); + properties.setProperty("ProtectedDatasource.JdbcDriver", "org.hsqldb.jdbcDriver"); + properties.setProperty("ProtectedDatasource.JdbcUrl", DATASOURCE_URL); + properties.setProperty("ProtectedDatasource.UserName", USER); + properties.setProperty("ProtectedDatasource.Password", "fEroTNXjaL5SOTyRQ92x3DNVS/ksbtgs"); + properties.setProperty("ProtectedDatasource.PasswordCipher", "Static3DES"); + properties.setProperty("ProtectedDatasource.JtaManaged", "true"); + + // start the context and makes junit test injections + EJBContainer container = EJBContainer.createEJBContainer(properties); + Context context = container.getContext(); + context.bind("inject", this); + + // test the datasource + assertNotNull(dataSource); + assertNotNull(dataSource.getConnection()); + + // closing the context + container.close(); + } + + @Test + public void accessDatasourceWithMyImplementation() throws Exception { + // define the datasource + Properties properties = new Properties(); + properties.setProperty("ProtectedDatasource", "new://Resource?type=DataSource"); + properties.setProperty("ProtectedDatasource.JdbcDriver", "org.hsqldb.jdbcDriver"); + properties.setProperty("ProtectedDatasource.JdbcUrl", "jdbc:hsqldb:mem:protected"); + properties.setProperty("ProtectedDatasource.UserName", USER); + properties.setProperty("ProtectedDatasource.Password", "3MdniFr3v3NLLuoY"); + properties.setProperty("ProtectedDatasource.PasswordCipher", "reverse"); + properties.setProperty("ProtectedDatasource.JtaManaged", "true"); + + // start the context and makes junit test injections + EJBContainer container = EJBContainer.createEJBContainer(properties); + Context context = container.getContext(); + context.bind("inject", this); + + // test the datasource + assertNotNull(dataSource); + assertNotNull(dataSource.getConnection()); + + // closing the context + container.close(); + } + + public static class ReverseEncryption implements PasswordCipher { + @Override + public char[] encrypt(String plainPassword) { + return StringUtils.reverse(plainPassword).toCharArray(); + } + + @Override + public String decrypt(char[] encryptedPassword) { + return new String(encrypt(new String(encryptedPassword))); + } + } +} +---- + + += Running + + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.DataSourceCipheredExampleTest +Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06 +http://tomee.apache.org/ +INFO - openejb.home = /Users/dblevins/examples/datasource-ciphered-password +INFO - openejb.base = /Users/dblevins/examples/datasource-ciphered-password +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 - Configuring Service(id=ProtectedDatasource, type=Resource, provider-id=Default JDBC Database) +INFO - Found EjbModule in classpath: /Users/dblevins/examples/datasource-ciphered-password/target/test-classes +INFO - Beginning load: /Users/dblevins/examples/datasource-ciphered-password/target/test-classes +INFO - Configuring enterprise application: /Users/dblevins/examples/datasource-ciphered-password +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 datasource-ciphered-password.Comp: Container(type=MANAGED, id=Default Managed Container) +INFO - Auto-linking resource-ref 'java:comp/env/org.superbiz.DataSourceCipheredExampleTest/dataSource' in bean datasource-ciphered-password.Comp to Resource(id=ProtectedDatasource) +INFO - Auto-linking resource-ref 'java:comp/env/org.superbiz.DataSourceCipheredExampleTest/dataSource' in bean org.superbiz.DataSourceCipheredExampleTest to Resource(id=ProtectedDatasource) +INFO - Enterprise application "/Users/dblevins/examples/datasource-ciphered-password" loaded. +INFO - Assembling app: /Users/dblevins/examples/datasource-ciphered-password +INFO - Jndi(name="java:global/datasource-ciphered-password/datasource-ciphered-password.Comp!org.apache.openejb.BeanContext$Comp") +INFO - Jndi(name="java:global/datasource-ciphered-password/datasource-ciphered-password.Comp") +INFO - Jndi(name="java:global/EjbModule86823325/org.superbiz.DataSourceCipheredExampleTest!org.superbiz.DataSourceCipheredExampleTest") +INFO - Jndi(name="java:global/EjbModule86823325/org.superbiz.DataSourceCipheredExampleTest") +INFO - Created Ejb(deployment-id=datasource-ciphered-password.Comp, ejb-name=datasource-ciphered-password.Comp, container=Default Managed Container) +INFO - Created Ejb(deployment-id=org.superbiz.DataSourceCipheredExampleTest, ejb-name=org.superbiz.DataSourceCipheredExampleTest, container=Default Managed Container) +INFO - Started Ejb(deployment-id=datasource-ciphered-password.Comp, ejb-name=datasource-ciphered-password.Comp, container=Default Managed Container) +INFO - Started Ejb(deployment-id=org.superbiz.DataSourceCipheredExampleTest, ejb-name=org.superbiz.DataSourceCipheredExampleTest, container=Default Managed Container) +INFO - Deployed Application(path=/Users/dblevins/examples/datasource-ciphered-password) +INFO - EJBContainer already initialized. Call ejbContainer.close() to allow reinitialization +Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.331 sec + +Results : + +Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 +---- + + http://git-wip-us.apache.org/repos/asf/tomee-tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/datasource-definition.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/datasource-definition.adoc b/src/main/jbake/content/examples/datasource-definition.adoc new file mode 100755 index 0000000..3931880 --- /dev/null +++ b/src/main/jbake/content/examples/datasource-definition.adoc @@ -0,0 +1,9 @@ += datasource-definition +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example datasource-definition can be browsed at https://github.com/apache/tomee/tree/master/examples/datasource-definition + +No README.md yet, be the first to contribute one! http://git-wip-us.apache.org/repos/asf/tomee-tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/datasource-versioning.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/datasource-versioning.adoc b/src/main/jbake/content/examples/datasource-versioning.adoc new file mode 100755 index 0000000..51b80d8 --- /dev/null +++ b/src/main/jbake/content/examples/datasource-versioning.adoc @@ -0,0 +1,412 @@ += DataSource Versioning +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example datasource-versioning can be browsed at https://github.com/apache/tomee/tree/master/examples/datasource-versioning + + +This example shows you how to use versioned DataSources of the same provider using the classpath attribute. + += Configuration + +The DataSource configuration can be made several ways and here we layout two common methods in the form of unit tests. +Before we start, if you take a peek in the project pom.xml and look for the maven-dependency-plugin usage you will see that we pull in +two completely different driver files for this example. + += AlternateDataSourceTest.java +This test utilizes the Arquillian testing framework. See link:http://tomee.apache.org/arquillian-available-adapters.html[here] for more details. + +The example uses src/test/resources/arquillian.xml and src/test/conf/tomee.xml to define the DataSources. +Note the differing driver version paths, yet still using the same provider (org.apache.derby.jdbc.EmbeddedDriver): + + +[source,xml] +---- +<tomee> + + <Resource id="DatabaseOne" type="DataSource" classpath="${catalina.base}/../../drivers/derby-10.10.1.1.jar"> + JdbcDriver org.apache.derby.jdbc.EmbeddedDriver + JdbcUrl jdbc:derby:databaseOne;create=true + UserName SA + </Resource> + + <Resource id="DatabaseTwo" type="DataSource" classpath="${catalina.base}/../../drivers/derby-10.9.1.0.jar"> + JdbcDriver org.apache.derby.jdbc.EmbeddedDriver + JdbcUrl jdbc:derby:databaseTwo;create=true + UserName SA + </Resource> + +</tomee> +---- + + += Developer Information +When testing within a Maven environment it is also possible to use direct maven coordinates rather than a file link, like so: + + .... + <Resource id="DatabaseOne" type="DataSource" classpath="mvn:org.apache.derby:derby:10.10.1.1"> + .... + + += AlternateDriverJarTest.java + +This test takes an embedded approach and as you can see the driver paths are specified as a DataSource parameter. +Both examples demonstrate the same, in that two driver versions can be loaded and used within the same application. + + +[source,java] +---- +@Configuration +public Properties config() { + + final File drivers = new File(new File("target"), "drivers").getAbsoluteFile(); + + final Properties p = new Properties(); + p.put("openejb.jdbc.datasource-creator", "dbcp-alternative"); + + File file = new File(drivers, "derby-10.10.1.1.jar"); + Assert.assertTrue("Failed to find: " + file, file.exists()); + + p.put("JdbcOne", "new://Resource?type=DataSource&classpath=" + + file.getAbsolutePath().replace("\\", "/")); + p.put("JdbcOne.JdbcDriver", "org.apache.derby.jdbc.EmbeddedDriver"); + p.put("JdbcOne.JdbcUrl", "jdbc:derby:memory:JdbcOne;create=true"); + p.put("JdbcOne.UserName", USER); + p.put("JdbcOne.Password", PASSWORD); + p.put("JdbcOne.JtaManaged", "false"); + + file = new File(drivers, "derby-10.9.1.0.jar"); + Assert.assertTrue("Failed to find: " + file, file.exists()); + + p.put("JdbcTwo", "new://Resource?type=DataSource&classpath=" + + file.getAbsolutePath().replace("\\", "/")); + p.put("JdbcTwo.JdbcDriver", "org.apache.derby.jdbc.EmbeddedDriver"); + p.put("JdbcTwo.JdbcUrl", "jdbc:derby:memory:JdbcTwo;create=true"); + p.put("JdbcTwo.UserName", USER); + p.put("JdbcTwo.Password", PASSWORD); + p.put("JdbcTwo.JtaManaged", "false"); + return p; +} +---- + + += Full Test Source for AlternateDataSourceTest.java + + +[source,java] +---- +package org.superbiz; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.ClassLoaderAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.annotation.Resource; +import javax.ejb.EJB; +import javax.ejb.Stateless; +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; + +@RunWith(Arquillian.class) +public class AlternateDataSourceTest { + + @Deployment + public static WebArchive createDeployment() { + + return ShrinkWrap.create(WebArchive.class, "test.war") + .addClasses(DataSourceTester.class) + .addAsResource(new ClassLoaderAsset("META-INF/ejb-jar.xml"), "META-INF/ejb-jar.xml"); + //We are using src/test/conf/tomee.xml, but this also works - .addAsResource(new ClassLoaderAsset("META-INF/resources.xml"), "META-INF/resources.xml"); + //Or even using a persistence context - .addAsResource(new ClassLoaderAsset("META-INF/persistence.xml"), "META-INF/persistence.xml"); + } + + @EJB + private DataSourceTester tester; + + @Test + public void testDataSourceOne() throws Exception { + Assert.assertEquals("Should be using 10.10.1.1 - (1458268)", "10.10.1.1 - (1458268)", tester.getOne()); + } + + @Test + public void testDataSourceTwo() throws Exception { + Assert.assertEquals("Should be using 10.9.1.0 - (1344872)", "10.9.1.0 - (1344872)", tester.getTwo()); + } + + @Test + public void testDataSourceBoth() throws Exception { + Assert.assertEquals("Should be using 10.10.1.1 - (1458268)|10.9.1.0 - (1344872)", "10.10.1.1 - (1458268)|10.9.1.0 - (1344872)", tester.getBoth()); + } + + @Stateless + public static class DataSourceTester { + + @Resource(name = "DatabaseOne") + DataSource dataSourceOne; + + @Resource(name = "DatabaseTwo") + DataSource dataSourceTwo; + + public String getOne() throws Exception { + return getVersion(dataSourceOne); + } + + public String getTwo() throws Exception { + return getVersion(dataSourceTwo); + } + + public String getBoth() throws Exception { + return getOne() + "|" + getTwo(); + } + + private static String getVersion(final DataSource ds) throws SQLException { + Connection con = null; + try { + con = ds.getConnection(); + final DatabaseMetaData md = con.getMetaData(); + return md.getDriverVersion(); + } finally { + if (con != null) { + con.close(); + } + } + } + } +} +---- + + += Running + + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.AlternateDataSourceTest +Apr 17, 2014 2:19:45 PM org.apache.openejb.arquillian.common.Setup findHome +INFO: Unable to find home in: C:\dev\svn\tomee\examples\datasource-versioning\target\apache-tomee-remote +Apr 17, 2014 2:19:45 PM org.apache.openejb.arquillian.common.MavenCache getArtifact +INFO: Downloading org.apache.openejb:apache-tomee:1.6.1-SNAPSHOT:zip:webprofile please wait... +Apr 17, 2014 2:19:45 PM org.apache.openejb.arquillian.common.Zips unzip +INFO: Extracting 'C:\Users\Andy\.m2\repository\org\apache\openejb\apache-tomee\1.6.1-SNAPSHOT\apache-tomee-1.6.1-SNAPSHOT-webprofile.zip' to 'C:\dev\svn\tomee\examples\datasource-versioning\target\apache-tomee-remote' +Apr 17, 2014 2:19:47 PM org.apache.tomee.arquillian.remote.RemoteTomEEContainer configure +INFO: Downloaded container to: C:\dev\svn\tomee\examples\datasource-versioning\target\apache-tomee-remote\apache-tomee-webprofile-1.6.1-SNAPSHOT +INFO - The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jdk1.7.0_45\jre\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files\SlikSvn\bin;C:\dev\apache-maven-3.2.1\bin;C:\dev\apache-ant-1.9.3\bin;C:\Program Files (x86)\Git\cmd;C:\Program Files (x86)\Git\bin;C:\Program Files\TortoiseGit\bin;C:\Program Files\TortoiseSVN\bin;. +INFO - Initializing ProtocolHandler ["http-bio-55243"] +INFO - Initializing ProtocolHandler ["ajp-bio-55245"] +INFO - Using 'openejb.jdbc.datasource-creator=org.apache.tomee.jdbc.TomEEDataSourceCreator' +INFO - Optional service not installed: org.apache.tomee.webservices.TomeeJaxRsService +INFO - Optional service not installed: org.apache.tomee.webservices.TomeeJaxWsService +INFO - ******************************************************************************** +INFO - OpenEJB http://tomee.apache.org/ +INFO - Startup: Thu Apr 17 14:19:55 CEST 2014 +INFO - Copyright 1999-2013 (C) Apache OpenEJB Project, All Rights Reserved. +INFO - Version: 7.0.0-SNAPSHOT +INFO - Build date: 20140417 +INFO - Build time: 01:37 +INFO - ******************************************************************************** +INFO - openejb.home = C:\dev\svn\tomee\examples\datasource-versioning\target\apache-tomee-remote\apache-tomee-webprofile-1.6.1-SNAPSHOT +INFO - openejb.base = C:\dev\svn\tomee\examples\datasource-versioning\target\apache-tomee-remote\apache-tomee-webprofile-1.6.1-SNAPSHOT +INFO - Created new singletonService org.apache.openejb.cdi.ThreadSingletonServiceImpl@22c2e2dd +INFO - Succeeded in installing singleton service +INFO - openejb configuration file is 'C:\dev\svn\tomee\examples\datasource-versioning\target\apache-tomee-remote\apache-tomee-webprofile-1.6.1-SNAPSHOT\conf\tomee.xml' +INFO - Configuring Service(id=Tomcat Security Service, type=SecurityService, provider-id=Tomcat Security Service) +INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +INFO - Configuring Service(id=DatabaseOne, type=Resource, provider-id=Default JDBC Database) +INFO - Configuring Service(id=DatabaseTwo, type=Resource, provider-id=Default JDBC Database) +INFO - Using 'openejb.system.apps=true' +INFO - Configuring enterprise application: openejb +INFO - Using openejb.deploymentId.format '{ejbName}' +INFO - Auto-deploying ejb openejb/Deployer: EjbDeployment(deployment-id=openejb/Deployer) +INFO - Auto-deploying ejb openejb/ConfigurationInfo: EjbDeployment(deployment-id=openejb/ConfigurationInfo) +INFO - Auto-deploying ejb MEJB: EjbDeployment(deployment-id=MEJB) +INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) +INFO - Auto-creating a container for bean openejb/Deployer: Container(type=STATELESS, id=Default Stateless Container) +INFO - Enterprise application "openejb" loaded. +INFO - Creating TransactionManager(id=Default Transaction Manager) +INFO - Creating SecurityService(id=Tomcat Security Service) +INFO - Creating Resource(id=DatabaseOne) +INFO - Disabling testOnBorrow since no validation query is provided +INFO - Creating Resource(id=DatabaseTwo) +INFO - Disabling testOnBorrow since no validation query is provided +INFO - Creating Container(id=Default Stateless Container) +INFO - Assembling app: openejb +INFO - Using 'openejb.jndiname.format={deploymentId}{interfaceType.openejbLegacyName}' +INFO - Jndi(name=openejb/DeployerBusinessRemote) --> Ejb(deployment-id=openejb/Deployer) +INFO - Jndi(name=global/openejb/openejb/Deployer!org.apache.openejb.assembler.Deployer) --> Ejb(deployment-id=openejb/Deployer) +INFO - Jndi(name=global/openejb/openejb/Deployer) --> Ejb(deployment-id=openejb/Deployer) +INFO - Jndi(name=openejb/ConfigurationInfoBusinessRemote) --> Ejb(deployment-id=openejb/ConfigurationInfo) +INFO - Jndi(name=global/openejb/openejb/ConfigurationInfo!org.apache.openejb.assembler.classic.cmd.ConfigurationInfo) --> Ejb(deployment-id=openejb/ConfigurationInfo) +INFO - Jndi(name=global/openejb/openejb/ConfigurationInfo) --> Ejb(deployment-id=openejb/ConfigurationInfo) +INFO - Jndi(name=MEJB) --> Ejb(deployment-id=MEJB) +INFO - Jndi(name=global/openejb/MEJB!javax.management.j2ee.ManagementHome) --> Ejb(deployment-id=MEJB) +INFO - Jndi(name=global/openejb/MEJB) --> Ejb(deployment-id=MEJB) +INFO - Created Ejb(deployment-id=openejb/Deployer, ejb-name=openejb/Deployer, container=Default Stateless Container) +INFO - Created Ejb(deployment-id=MEJB, ejb-name=MEJB, container=Default Stateless Container) +INFO - Created Ejb(deployment-id=openejb/ConfigurationInfo, ejb-name=openejb/ConfigurationInfo, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=openejb/Deployer, ejb-name=openejb/Deployer, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=MEJB, ejb-name=MEJB, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=openejb/ConfigurationInfo, ejb-name=openejb/ConfigurationInfo, container=Default Stateless Container) +INFO - Deployed MBean(openejb.user.mbeans:application=openejb,group=org.apache.openejb.assembler.monitoring,name=JMXDeployer) +INFO - Deployed Application(path=openejb) +INFO - ** Bound Services ** +INFO - NAME IP PORT +INFO - ------- +INFO - Ready! +INFO - Initialization processed in 7959 ms +INFO - Importing a Tomcat Resource with id 'UserDatabase' of type 'org.apache.catalina.UserDatabase'. +INFO - Creating Resource(id=UserDatabase) +INFO - Starting service Catalina +INFO - Starting Servlet Engine: Apache Tomcat (TomEE)/7.0.53 (1.6.1-SNAPSHOT) +INFO - Starting ProtocolHandler ["http-bio-55243"] +INFO - Starting ProtocolHandler ["ajp-bio-55245"] +INFO - Server startup in 288 ms +WARNING - StandardServer.await: Invalid command '' received +Apr 17, 2014 2:20:04 PM org.apache.openejb.client.EventLogger log +INFO: RemoteInitialContextCreated{providerUri=http://localhost:55243/tomee/ejb} +INFO - Extracting jar: C:\dev\svn\tomee\examples\datasource-versioning\target\arquillian-test-working-dir\0\test.war +INFO - Extracted path: C:\dev\svn\tomee\examples\datasource-versioning\target\arquillian-test-working-dir\0\test +INFO - using default host: localhost +INFO - ------------------------- localhost -> /test +INFO - Using 'openejb.session.manager=org.apache.tomee.catalina.session.QuickSessionManager' +INFO - Configuring enterprise application: C:\dev\svn\tomee\examples\datasource-versioning\target\arquillian-test-working-dir\0\test +INFO - Auto-deploying ejb DataSourceTester: EjbDeployment(deployment-id=DataSourceTester) +INFO - Auto-linking resource-ref 'java:comp/env/DatabaseTwo' in bean DataSourceTester to Resource(id=DatabaseTwo) +INFO - Auto-linking resource-ref 'java:comp/env/DatabaseOne' in bean DataSourceTester to Resource(id=DatabaseOne) +INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) +INFO - Auto-creating a container for bean org.superbiz.AlternateDataSourceTest: Container(type=MANAGED, id=Default Managed Container) +INFO - Creating Container(id=Default Managed Container) +INFO - Using directory C:\dev\svn\tomee\examples\datasource-versioning\target\apache-tomee-remote\apache-tomee-webprofile-1.6.1-SNAPSHOT\temp for stateful session passivation +INFO - Enterprise application "C:\dev\svn\tomee\examples\datasource-versioning\target\arquillian-test-working-dir\0\test" loaded. +INFO - Assembling app: C:\dev\svn\tomee\examples\datasource-versioning\target\arquillian-test-working-dir\0\test +INFO - Jndi(name=DataSourceTesterLocalBean) --> Ejb(deployment-id=DataSourceTester) +INFO - Jndi(name=global/test/DataSourceTester!org.superbiz.AlternateDataSourceTest$DataSourceTester) --> Ejb(deployment-id=DataSourceTester) +INFO - Jndi(name=global/test/DataSourceTester) --> Ejb(deployment-id=DataSourceTester) +INFO - Existing thread singleton service in SystemInstance(): org.apache.openejb.cdi.ThreadSingletonServiceImpl@22c2e2dd +INFO - OpenWebBeans Container is starting... +INFO - Adding OpenWebBeansPlugin : [CdiPlugin] +INFO - All injection points were validated successfully. +INFO - OpenWebBeans Container has started, it took 203 ms. +INFO - Created Ejb(deployment-id=DataSourceTester, ejb-name=DataSourceTester, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=DataSourceTester, ejb-name=DataSourceTester, container=Default Stateless Container) +INFO - Deployed Application(path=C:\dev\svn\tomee\examples\datasource-versioning\target\arquillian-test-working-dir\0\test) +Apr 17, 2014 2:20:11 PM org.apache.openejb.client.EventLogger log +INFO: RemoteInitialContextCreated{providerUri=http://localhost:55243/tomee/ejb} +INFO - Undeploying app: C:\dev\svn\tomee\examples\datasource-versioning\target\arquillian-test-working-dir\0\test +Apr 17, 2014 2:20:13 PM org.apache.openejb.arquillian.common.TomEEContainer undeploy +INFO: cleaning C:\dev\svn\tomee\examples\datasource-versioning\target\arquillian-test-working-dir\0 +Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 30.155 sec +Running org.superbiz.AlternateDriverJarTest +Apr 17, 2014 2:20:13 PM org.apache.openejb.config.ConfigUtils searchForConfiguration +INFO: Cannot find the configuration file [conf/openejb.xml]. Will attempt to create one for the beans deployed. +Apr 17, 2014 2:20:13 PM org.apache.openejb.config.ConfigurationFactory configureService +INFO: Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) +Apr 17, 2014 2:20:13 PM org.apache.openejb.config.ConfigurationFactory configureService +INFO: Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +Apr 17, 2014 2:20:13 PM org.apache.openejb.config.ConfigurationFactory configureService +INFO: Configuring Service(id=JdbcTwo, type=Resource, provider-id=Default JDBC Database) +Apr 17, 2014 2:20:13 PM org.apache.openejb.config.ConfigurationFactory configureService +INFO: Configuring Service(id=JdbcOne, type=Resource, provider-id=Default JDBC Database) +Apr 17, 2014 2:20:13 PM org.apache.openejb.assembler.classic.Assembler createRecipe +INFO: Creating TransactionManager(id=Default Transaction Manager) +Apr 17, 2014 2:20:14 PM org.apache.openejb.assembler.classic.Assembler createRecipe +INFO: Creating SecurityService(id=Default Security Service) +Apr 17, 2014 2:20:14 PM org.apache.openejb.assembler.classic.Assembler createRecipe +INFO: Creating Resource(id=JdbcTwo) +Apr 17, 2014 2:20:15 PM org.apache.openejb.assembler.classic.Assembler createRecipe +INFO: Creating Resource(id=JdbcOne) +Apr 17, 2014 2:20:16 PM org.apache.openejb.config.ConfigurationFactory configureApplication +INFO: Configuring enterprise application: C:\dev\svn\tomee\examples\datasource-versioning\AlternateDriverJarTest +Apr 17, 2014 2:20:16 PM org.apache.openejb.config.ConfigurationFactory configureService +INFO: Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) +Apr 17, 2014 2:20:16 PM org.apache.openejb.config.AutoConfig createContainer +INFO: Auto-creating a container for bean org.superbiz.AlternateDriverJarTest: Container(type=MANAGED, id=Default Managed Container) +Apr 17, 2014 2:20:16 PM org.apache.openejb.assembler.classic.Assembler createRecipe +INFO: Creating Container(id=Default Managed Container) +Apr 17, 2014 2:20:16 PM org.apache.openejb.core.managed.SimplePassivater init +INFO: Using directory C:\Users\Andy\AppData\Local\Temp for stateful session passivation +Apr 17, 2014 2:20:16 PM org.apache.openejb.config.ConfigurationFactory configureService +INFO: Configuring Service(id=Default Singleton Container, type=Container, provider-id=Default Singleton Container) +Apr 17, 2014 2:20:16 PM org.apache.openejb.config.AutoConfig createContainer +INFO: Auto-creating a container for bean JdbcOne: Container(type=SINGLETON, id=Default Singleton Container) +Apr 17, 2014 2:20:16 PM org.apache.openejb.assembler.classic.Assembler createRecipe +INFO: Creating Container(id=Default Singleton Container) +Apr 17, 2014 2:20:16 PM org.apache.openejb.config.AutoConfig processResourceRef +INFO: Auto-linking resource-ref 'java:comp/env/JdbcOne' in bean JdbcOne to Resource(id=JdbcOne) +Apr 17, 2014 2:20:16 PM org.apache.openejb.config.AutoConfig processResourceRef +INFO: Auto-linking resource-ref 'java:comp/env/JdbcTwo' in bean JdbcTwo to Resource(id=JdbcTwo) +Apr 17, 2014 2:20:16 PM org.apache.openejb.config.AppInfoBuilder build +INFO: Enterprise application "C:\dev\svn\tomee\examples\datasource-versioning\AlternateDriverJarTest" loaded. +Apr 17, 2014 2:20:16 PM org.apache.openejb.assembler.classic.Assembler createApplication +INFO: Assembling app: C:\dev\svn\tomee\examples\datasource-versioning\AlternateDriverJarTest +Apr 17, 2014 2:20:16 PM org.apache.openejb.assembler.classic.JndiBuilder bind +INFO: Jndi(name=JdbcOneLocalBean) --> Ejb(deployment-id=JdbcOne) +Apr 17, 2014 2:20:16 PM org.apache.openejb.assembler.classic.JndiBuilder bind +INFO: Jndi(name=global/AlternateDriverJarTest/app/JdbcOne!org.superbiz.AlternateDriverJarTest$JdbcOne) --> Ejb(deployment-id=JdbcOne) +Apr 17, 2014 2:20:16 PM org.apache.openejb.assembler.classic.JndiBuilder bind +INFO: Jndi(name=global/AlternateDriverJarTest/app/JdbcOne) --> Ejb(deployment-id=JdbcOne) +Apr 17, 2014 2:20:16 PM org.apache.openejb.assembler.classic.JndiBuilder bind +INFO: Jndi(name=JdbcTwoLocalBean) --> Ejb(deployment-id=JdbcTwo) +Apr 17, 2014 2:20:16 PM org.apache.openejb.assembler.classic.JndiBuilder bind +INFO: Jndi(name=global/AlternateDriverJarTest/app/JdbcTwo!org.superbiz.AlternateDriverJarTest$JdbcTwo) --> Ejb(deployment-id=JdbcTwo) +Apr 17, 2014 2:20:16 PM org.apache.openejb.assembler.classic.JndiBuilder bind +INFO: Jndi(name=global/AlternateDriverJarTest/app/JdbcTwo) --> Ejb(deployment-id=JdbcTwo) +Apr 17, 2014 2:20:16 PM org.apache.openejb.cdi.CdiBuilder initializeOWB +INFO: Created new singletonService org.apache.openejb.cdi.ThreadSingletonServiceImpl@5ddd4e70 +Apr 17, 2014 2:20:16 PM org.apache.openejb.cdi.CdiBuilder initializeOWB +INFO: Succeeded in installing singleton service +Apr 17, 2014 2:20:17 PM org.apache.openejb.cdi.OpenEJBLifecycle startApplication +INFO: OpenWebBeans Container is starting... +Apr 17, 2014 2:20:17 PM org.apache.webbeans.plugins.PluginLoader startUp +INFO: Adding OpenWebBeansPlugin : [CdiPlugin] +Apr 17, 2014 2:20:17 PM org.apache.webbeans.config.BeansDeployer validateInjectionPoints +INFO: All injection points were validated successfully. +Apr 17, 2014 2:20:17 PM org.apache.openejb.cdi.OpenEJBLifecycle startApplication +INFO: OpenWebBeans Container has started, it took 223 ms. +Apr 17, 2014 2:20:17 PM org.apache.openejb.assembler.classic.Assembler startEjbs +INFO: Created Ejb(deployment-id=JdbcTwo, ejb-name=JdbcTwo, container=Default Singleton Container) +Apr 17, 2014 2:20:17 PM org.apache.openejb.assembler.classic.Assembler startEjbs +INFO: Created Ejb(deployment-id=JdbcOne, ejb-name=JdbcOne, container=Default Singleton Container) +Apr 17, 2014 2:20:17 PM org.apache.openejb.assembler.classic.Assembler startEjbs +INFO: Started Ejb(deployment-id=JdbcTwo, ejb-name=JdbcTwo, container=Default Singleton Container) +Apr 17, 2014 2:20:17 PM org.apache.openejb.assembler.classic.Assembler startEjbs +INFO: Started Ejb(deployment-id=JdbcOne, ejb-name=JdbcOne, container=Default Singleton Container) +Apr 17, 2014 2:20:17 PM org.apache.openejb.assembler.classic.Assembler createApplication +INFO: Deployed Application(path=C:\dev\svn\tomee\examples\datasource-versioning\AlternateDriverJarTest) +Apr 17, 2014 2:20:20 PM org.apache.openejb.assembler.classic.Assembler destroyApplication +INFO: Undeploying app: C:\dev\svn\tomee\examples\datasource-versioning\AlternateDriverJarTest +Apr 17, 2014 2:20:20 PM org.apache.openejb.assembler.classic.Assembler destroyResource +INFO: Closing DataSource: JdbcTwo +Apr 17, 2014 2:20:20 PM org.apache.openejb.assembler.classic.Assembler destroyResource +INFO: Closing DataSource: JdbcOne +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 7.857 sec +INFO - A valid shutdown command was received via the shutdown port. Stopping the Server instance. +INFO - Pausing ProtocolHandler ["http-bio-55243"] +INFO - Pausing ProtocolHandler ["ajp-bio-55245"] +INFO - Stopping service Catalina +INFO - Stopping ProtocolHandler ["http-bio-55243"] +INFO - Stopping ProtocolHandler ["ajp-bio-55245"] +INFO - Stopping server services +INFO - Undeploying app: openejb +INFO - Closing DataSource: DatabaseOne +INFO - Closing DataSource: DatabaseTwo +INFO - Destroying ProtocolHandler ["http-bio-55243"] +INFO - Destroying ProtocolHandler ["ajp-bio-55245"] + +Results : + +Tests run: 4, Failures: 0, Errors: 0, Skipped: 0 +---- + http://git-wip-us.apache.org/repos/asf/tomee-tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/decorators.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/decorators.adoc b/src/main/jbake/content/examples/decorators.adoc new file mode 100755 index 0000000..9181e92 --- /dev/null +++ b/src/main/jbake/content/examples/decorators.adoc @@ -0,0 +1,436 @@ += Decorators +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example decorators can be browsed at https://github.com/apache/tomee/tree/master/examples/decorators + + +*Help us document this example! Click the blue pencil icon in the upper right to edit this page.* + +== 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 + + + +[source] +---- +------------------------------------------------------- + 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 +---- + + http://git-wip-us.apache.org/repos/asf/tomee-tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/deltaspike-configproperty.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/deltaspike-configproperty.adoc b/src/main/jbake/content/examples/deltaspike-configproperty.adoc new file mode 100755 index 0000000..eead15e --- /dev/null +++ b/src/main/jbake/content/examples/deltaspike-configproperty.adoc @@ -0,0 +1,9 @@ += deltaspike-configproperty +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example deltaspike-configproperty can be browsed at https://github.com/apache/tomee/tree/master/examples/deltaspike-configproperty + +No README.md yet, be the first to contribute one! http://git-wip-us.apache.org/repos/asf/tomee-tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/deltaspike-exception-handling.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/deltaspike-exception-handling.adoc b/src/main/jbake/content/examples/deltaspike-exception-handling.adoc new file mode 100755 index 0000000..be450bf --- /dev/null +++ b/src/main/jbake/content/examples/deltaspike-exception-handling.adoc @@ -0,0 +1,9 @@ += deltaspike-exception-handling +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example deltaspike-exception-handling can be browsed at https://github.com/apache/tomee/tree/master/examples/deltaspike-exception-handling + +No README.md yet, be the first to contribute one! http://git-wip-us.apache.org/repos/asf/tomee-tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/deltaspike-fullstack.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/deltaspike-fullstack.adoc b/src/main/jbake/content/examples/deltaspike-fullstack.adoc new file mode 100755 index 0000000..ebcbca6 --- /dev/null +++ b/src/main/jbake/content/examples/deltaspike-fullstack.adoc @@ -0,0 +1,75 @@ += Apache DeltaSpike Demo +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example deltaspike-fullstack can be browsed at https://github.com/apache/tomee/tree/master/examples/deltaspike-fullstack + +Notice: Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. + +<h2>Steps to run the example</h2> + +Build and start the demo: + + mvn clean package tomee:run + +Open: + + http://localhost:8080/ + +This example shows how to improve JSF2/CDI/BV/JPA applications with features provided by Apache DeltaSpike and MyFaces ExtVal. + +<h2>Intro of Apache DeltaSpike and MyFaces ExtVal</h2> + +The Apache DeltaSpike project hosts portable extensions for Contexts and Dependency Injection (CDI - JSR 299). DeltaSpike is a toolbox for your CDI application. Like CDI itself DeltaSpike is focused on type-safety. It is a modularized and extensible framework. So it's easy to choose the needed parts to facilitate the daily work in your project. + +MyFaces Extensions Validator (aka ExtVal) is a JSF centric validation framework which is compatible with JSF 1.x and JSF 2.x. +This example shows how it improves the default integration of Bean-Validation (JSR-303) with JSF2 as well as meta-data based cross-field validation. + + +<h2>Illustrated Features</h2> + +<h3>Apache DeltaSpike</h3> + +<ul> + +[source,xml] +---- +<li><a href="./src/main/java/org/superbiz/deltaspike/view/config/Pages.java" target="_blank">Type-safe view-config</a></li> +<li><a href="./src/main/java/org/superbiz/deltaspike/view/InfoPage.java" target="_blank">Type-safe (custom) view-meta-data</a></li> +<li><a href="./src/main/java/org/superbiz/deltaspike/view/MenuBean.java" target="_blank">Type-safe navigation</a></li> +<li><a href="./src/main/java/org/superbiz/deltaspike/CustomProjectStage.java" target="_blank">Type-safe custom project-stage</a></li> +<li><a href="./src/main/java/org/superbiz/deltaspike/view/UserHolder.java" target="_blank">@WindowScoped</a></li> +<li><a href="./src/main/java/org/superbiz/deltaspike/view/MenuBean.java" target="_blank">Controlling DeltaSpike grouped-conversations with GroupedConversationManager</a></li> +<li><a href="./src/main/java/org/superbiz/deltaspike/view/FeedbackPage.java" target="_blank">@GroupedConversationScoped</a></li> +<li><a href="./src/main/java/org/superbiz/deltaspike/view/FeedbackPage.java" target="_blank">Manual conversation handling</a></li> +<li><a href="./src/main/java/org/superbiz/deltaspike/view/security/LoginAccessDecisionVoter.java" target="_blank">Secured pages (AccessDecisionVoter)</a></li> +<li><a href="./src/main/java/org/superbiz/deltaspike/repository/Repository.java" target="_blank">@Transactional</a></li> +<li><a href="./src/main/java/org/superbiz/deltaspike/view/RegistrationPage.java" target="_blank">I18n (type-safe messages)</a></li> +<li><a href="./src/main/java/org/superbiz/deltaspike/domain/validation/UniqueUserNameValidator.java" target="_blank">Dependency-Injection for JSR303 (BV) constraint-validators</a></li> +<li><a href="./src/main/java/org/superbiz/deltaspike/DebugPhaseListener.java" target="_blank">Dependency-Injection for JSF phase-listeners</a></li> +</ul> + +<h3>Apache MyFaces ExtVal</h3> + +<ul> +<li><a href="./src/main/java/org/superbiz/myfaces/view/RegistrationPage.java" target="_blank">Cross-Field validation (@Equals)</a></li> +<li><a href="./src/main/java/org/superbiz/myfaces/view/RegistrationPage.java" target="_blank">Type-safe group-validation (@BeanValidation) for JSF action-methods</a></li> +</ul> + http://git-wip-us.apache.org/repos/asf/tomee-tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/deltaspike-i18n.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/deltaspike-i18n.adoc b/src/main/jbake/content/examples/deltaspike-i18n.adoc new file mode 100755 index 0000000..18c6dbf --- /dev/null +++ b/src/main/jbake/content/examples/deltaspike-i18n.adoc @@ -0,0 +1,9 @@ += deltaspike-i18n +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example deltaspike-i18n can be browsed at https://github.com/apache/tomee/tree/master/examples/deltaspike-i18n + +No README.md yet, be the first to contribute one! http://git-wip-us.apache.org/repos/asf/tomee-tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/dynamic-dao-implementation.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/dynamic-dao-implementation.adoc b/src/main/jbake/content/examples/dynamic-dao-implementation.adoc new file mode 100755 index 0000000..40b7a96 --- /dev/null +++ b/src/main/jbake/content/examples/dynamic-dao-implementation.adoc @@ -0,0 +1,384 @@ += Dynamic DAO Implementation +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example dynamic-dao-implementation can be browsed at https://github.com/apache/tomee/tree/master/examples/dynamic-dao-implementation + + +Many aspects of Data Access Objects (DAOs) are very repetitive and boiler plate. As a fun and experimental feature, TomEE supports dynamically implementing an interface +that is seen to have standard DAO-style methods. + +The interface has to be annotated with @PersistenceContext to define which EntityManager to use. + +Methods should respect these conventions: + + * void save(Foo foo): persist foo + * Foo update(Foo foo): merge foo + * void delete(Foo foo): remove foo, if foo is detached it tries to attach it + * Collection<Foo>|Foo namedQuery(String name[, Map<String, ?> params, int first, int max]): run the named query called name, params contains bindings, first and max are used for magination. Last three parameters are optionnals + * Collection<Foo>|Foo nativeQuery(String name[, Map<String, ?> params, int first, int max]): run the native query called name, params contains bindings, first and max are used for magination. Last three parameters are optionnals + * Collection<Foo>|Foo query(String value [, Map<String, ?> params, int first, int max]): run the query put as first parameter, params contains bindings, first and max are used for magination. Last three parameters are optionnals + * Collection<Foo> findAll([int first, int max]): find all Foo, parameters are used for pagination + * Collection<Foo> findByBar1AndBar2AndBar3(<bar 1 type> bar1, <bar 2 type> bar2, <bar3 type> bar3 [, int first, int max]): find all Foo with specified field values for bar1, bar2, bar3. + +Dynamic finder can have as much as you want field constraints. For String like is used and for other type equals is used. + += Example + +== User + + +[source,java] +---- +package org.superbiz.dynamic; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; + +@Entity +@NamedQueries({ + @NamedQuery(name = "dynamic-ejb-impl-test.query", query = "SELECT u FROM User AS u WHERE u.name LIKE :name"), + @NamedQuery(name = "dynamic-ejb-impl-test.all", query = "SELECT u FROM User AS u") +}) +public class User { + @Id + @GeneratedValue + private long id; + private String name; + private int age; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } +} +---- + + +== UserDao + + +[source,java] +---- +package org.superbiz.dynamic; + + +import javax.ejb.Stateless; +import javax.persistence.PersistenceContext; +import java.util.Collection; +import java.util.Map; + +@Stateless +@PersistenceContext(name = "dynamic") +public interface UserDao { + User findById(long id); + + Collection<User> findByName(String name); + + Collection<User> findByNameAndAge(String name, int age); + + Collection<User> findAll(); + + Collection<User> findAll(int first, int max); + + Collection<User> namedQuery(String name, Map<String, ?> params, int first, int max); + + Collection<User> namedQuery(String name, int first, int max, Map<String, ?> params); + + Collection<User> namedQuery(String name, Map<String, ?> params); + + Collection<User> namedQuery(String name); + + Collection<User> query(String value, Map<String, ?> params); + + void save(User u); + + void delete(User u); + + User update(User u); +} +---- + + +== persistence.xml + + +[source,xml] +---- +<persistence version="2.0" + xmlns="http://java.sun.com/xml/ns/persistence" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://java.sun.com/xml/ns/persistence + http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> + <persistence-unit name="dynamic" transaction-type="JTA"> + <jta-data-source>jdbc/dynamicDB</jta-data-source> + <class>org.superbiz.dynamic.User</class> + <properties> + <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> + </properties> + </persistence-unit> +</persistence> +---- + + + +== DynamicUserDaoTest + + +[source,java] +---- +package org.superbiz.dynamic; + +import junit.framework.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.ejb.EJBException; +import javax.ejb.Stateless; +import javax.ejb.embeddable.EJBContainer; +import javax.naming.Context; +import javax.persistence.EntityManager; +import javax.persistence.NoResultException; +import javax.persistence.PersistenceContext; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertTrue; + +public class DynamicUserDaoTest { + private static UserDao dao; + private static Util util; + + @BeforeClass + public static void init() throws Exception { + final Properties p = new Properties(); + p.put("jdbc/dynamicDB", "new://Resource?type=DataSource"); + p.put("jdbc/dynamicDB.JdbcDriver", "org.hsqldb.jdbcDriver"); + p.put("jdbc/dynamicDB.JdbcUrl", "jdbc:hsqldb:mem:moviedb"); + p.put("jdbc/dynamicDB.UserName", "sa"); + p.put("jdbc/dynamicDB.Password", ""); + + final Context context = EJBContainer.createEJBContainer(p).getContext(); + dao = (UserDao) context.lookup("java:global/dynamic-dao-implementation/UserDao"); + util = (Util) context.lookup("java:global/dynamic-dao-implementation/Util"); + + util.init(); // init database + } + + @Test + public void simple() { + User user = dao.findById(1); + assertNotNull(user); + assertEquals(1, user.getId()); + } + + @Test + public void findAll() { + Collection<User> users = dao.findAll(); + assertEquals(10, users.size()); + } + + @Test + public void pagination() { + Collection<User> users = dao.findAll(0, 5); + assertEquals(5, users.size()); + + users = dao.findAll(6, 1); + assertEquals(1, users.size()); + assertEquals(7, users.iterator().next().getId()); + } + + @Test + public void persist() { + User u = new User(); + dao.save(u); + assertNotNull(u.getId()); + util.remove(u); + } + + @Test + public void remove() { + User u = new User(); + dao.save(u); + assertNotNull(u.getId()); + dao.delete(u); + try { + dao.findById(u.getId()); + Assert.fail(); + } catch (EJBException ee) { + assertTrue(ee.getCause() instanceof NoResultException); + } + } + + @Test + public void merge() { + User u = new User(); + u.setAge(1); + dao.save(u); + assertEquals(1, u.getAge()); + assertNotNull(u.getId()); + + u.setAge(2); + dao.update(u); + assertEquals(2, u.getAge()); + + dao.delete(u); + } + + @Test + public void oneCriteria() { + Collection<User> users = dao.findByName("foo"); + assertEquals(4, users.size()); + for (User user : users) { + assertEquals("foo", user.getName()); + } + } + + @Test + public void twoCriteria() { + Collection<User> users = dao.findByNameAndAge("bar-1", 1); + assertEquals(1, users.size()); + + User user = users.iterator().next(); + assertEquals("bar-1", user.getName()); + assertEquals(1, user.getAge()); + } + + @Test + public void query() { + Map<String, Object> params = new HashMap<String, Object>(); + params.put("name", "foo"); + + Collection<User> users = dao.namedQuery("dynamic-ejb-impl-test.query", params, 0, 100); + assertEquals(4, users.size()); + + users = dao.namedQuery("dynamic-ejb-impl-test.query", params); + assertEquals(4, users.size()); + + users = dao.namedQuery("dynamic-ejb-impl-test.query", params, 0, 2); + assertEquals(2, users.size()); + + users = dao.namedQuery("dynamic-ejb-impl-test.query", 0, 2, params); + assertEquals(2, users.size()); + + users = dao.namedQuery("dynamic-ejb-impl-test.all"); + assertEquals(10, users.size()); + + params.remove("name"); + params.put("age", 1); + users = dao.query("SELECT u FROM User AS u WHERE u.age = :age", params); + assertEquals(3, users.size()); + } + + @Stateless + public static class Util { + @PersistenceContext + private EntityManager em; + + public void remove(User o) { + em.remove(em.find(User.class, o.getId())); + } + + public void init() { + for (int i = 0; i < 10; i++) { + User u = new User(); + u.setAge(i % 4); + if (i % 3 == 0) { + u.setName("foo"); + } else { + u.setName("bar-" + i); + } + em.persist(u); + } + } + } +} +---- + + += Running + + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.dynamic.DynamicUserDaoTest +Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06 +http://tomee.apache.org/ +INFO - openejb.home = /Users/dblevins/examples/dynamic-dao-implementation +INFO - openejb.base = /Users/dblevins/examples/dynamic-dao-implementation +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 - Configuring Service(id=jdbc/dynamicDB, type=Resource, provider-id=Default JDBC Database) +INFO - Found EjbModule in classpath: /Users/dblevins/examples/dynamic-dao-implementation/target/classes +INFO - Found EjbModule in classpath: /Users/dblevins/examples/dynamic-dao-implementation/target/test-classes +INFO - Beginning load: /Users/dblevins/examples/dynamic-dao-implementation/target/classes +INFO - Beginning load: /Users/dblevins/examples/dynamic-dao-implementation/target/test-classes +INFO - Configuring enterprise application: /Users/dblevins/examples/dynamic-dao-implementation +INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) +INFO - Auto-creating a container for bean UserDao: Container(type=STATELESS, id=Default Stateless Container) +INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) +INFO - Auto-creating a container for bean org.superbiz.dynamic.DynamicUserDaoTest: Container(type=MANAGED, id=Default Managed Container) +INFO - Configuring PersistenceUnit(name=dynamic) +INFO - Auto-creating a Resource with id 'jdbc/dynamicDBNonJta' of type 'DataSource for 'dynamic'. +INFO - Configuring Service(id=jdbc/dynamicDBNonJta, type=Resource, provider-id=jdbc/dynamicDB) +INFO - Adjusting PersistenceUnit dynamic <non-jta-data-source> to Resource ID 'jdbc/dynamicDBNonJta' from 'null' +INFO - Enterprise application "/Users/dblevins/examples/dynamic-dao-implementation" loaded. +INFO - Assembling app: /Users/dblevins/examples/dynamic-dao-implementation +INFO - PersistenceUnit(name=dynamic, provider=org.apache.openjpa.persistence.PersistenceProviderImpl) - provider time 417ms +INFO - Jndi(name="java:global/dynamic-dao-implementation/UserDao!org.superbiz.dynamic.UserDao") +INFO - Jndi(name="java:global/dynamic-dao-implementation/UserDao") +INFO - Jndi(name="java:global/dynamic-dao-implementation/Util!org.superbiz.dynamic.DynamicUserDaoTest$Util") +INFO - Jndi(name="java:global/dynamic-dao-implementation/Util") +INFO - Jndi(name="java:global/EjbModule346613126/org.superbiz.dynamic.DynamicUserDaoTest!org.superbiz.dynamic.DynamicUserDaoTest") +INFO - Jndi(name="java:global/EjbModule346613126/org.superbiz.dynamic.DynamicUserDaoTest") +INFO - Created Ejb(deployment-id=UserDao, ejb-name=UserDao, container=Default Stateless Container) +INFO - Created Ejb(deployment-id=Util, ejb-name=Util, container=Default Stateless Container) +INFO - Created Ejb(deployment-id=org.superbiz.dynamic.DynamicUserDaoTest, ejb-name=org.superbiz.dynamic.DynamicUserDaoTest, container=Default Managed Container) +INFO - Started Ejb(deployment-id=UserDao, ejb-name=UserDao, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=Util, ejb-name=Util, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=org.superbiz.dynamic.DynamicUserDaoTest, ejb-name=org.superbiz.dynamic.DynamicUserDaoTest, container=Default Managed Container) +INFO - Deployed Application(path=/Users/dblevins/examples/dynamic-dao-implementation) +WARN - Meta class "org.superbiz.dynamic.User_" for entity class org.superbiz.dynamic.User can not be registered with following exception "java.security.PrivilegedActionException: java.lang.ClassNotFoundException: org.superbiz.dynamic.User_" +WARN - Query "SELECT u FROM User AS u WHERE u.name LIKE :name" is removed from cache excluded permanently. Query "SELECT u FROM User AS u WHERE u.name LIKE :name" is not cached because it uses pagination.. +Tests run: 9, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.471 sec + +Results : + +Tests run: 9, Failures: 0, Errors: 0, Skipped: 0 +---- + +