You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2010/02/23 04:49:58 UTC

svn commit: r915166 [1/2] - in /openejb/trunk/openejb3/container: ./ openejb-junit/ openejb-junit/src/ openejb-junit/src/main/ openejb-junit/src/main/java/ openejb-junit/src/main/java/org/ openejb-junit/src/main/java/org/apache/ openejb-junit/src/main/...

Author: dblevins
Date: Tue Feb 23 03:49:56 2010
New Revision: 915166

URL: http://svn.apache.org/viewvc?rev=915166&view=rev
Log:
Great JUnitRunner by Quintin Beukes, OPENEJB-1078

Added:
    openejb/trunk/openejb3/container/openejb-junit/
    openejb/trunk/openejb3/container/openejb-junit/LICENSE   (with props)
    openejb/trunk/openejb3/container/openejb-junit/NOTICE   (with props)
    openejb/trunk/openejb3/container/openejb-junit/pom.xml   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/
    openejb/trunk/openejb3/container/openejb-junit/src/main/
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/JUnit4Runner.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/OpenEjbRunner.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/ContextConfig.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/Property.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/RunTestAs.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestResource.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestResourceTypes.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestSecurity.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/ContextWrapperStatement.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/OpenEjbTestContext.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/TestContext.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/Util.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/model/
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/model/MultiStatementExecutor.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/security/
    openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/security/TestLoginModule.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/resources/
    openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/
    openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/default-openejb-test-config.properties   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/openejb-test-login.config   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestClassConfigFile.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestClassConfigFileAndProperties.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestClassConfigProperties.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestDualConfigOverride.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEjbBasic.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEjbSecurity.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEjbSecurityRunTestAs.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestMethodConfigFile.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestMethodConfigProperties.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestRunner.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/context/
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/context/ContextWrapperStatementTest.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/context/UtilTest.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/ejbs/
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/ejbs/BasicEjb.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/ejbs/BasicEjbLocal.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/ejbs/SecuredEjb.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/ejbs/SecuredEjbLocal.java   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/resources/
    openejb/trunk/openejb3/container/openejb-junit/src/test/resources/META-INF/
    openejb/trunk/openejb3/container/openejb-junit/src/test/resources/META-INF/ejb-jar.xml   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/resources/META-INF/test-config-method.properties   (with props)
    openejb/trunk/openejb3/container/openejb-junit/src/test/resources/META-INF/test-config.properties   (with props)
Modified:
    openejb/trunk/openejb3/container/pom.xml

Added: openejb/trunk/openejb3/container/openejb-junit/LICENSE
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/LICENSE?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/LICENSE (added)
+++ openejb/trunk/openejb3/container/openejb-junit/LICENSE Tue Feb 23 03:49:56 2010
@@ -0,0 +1,233 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+-------------------------------------------------------------------------
+for container/openejb-core/src/test/java/org/apache/openejb/DependencyVisitor.java:
+
+ Copyright (c) 2000-2005 INRIA, France Telecom
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGE.

Propchange: openejb/trunk/openejb3/container/openejb-junit/LICENSE
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/NOTICE
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/NOTICE?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/NOTICE (added)
+++ openejb/trunk/openejb3/container/openejb-junit/NOTICE Tue Feb 23 03:49:56 2010
@@ -0,0 +1,8 @@
+
+Apache OpenEJB
+Copyright 1999-2008 The Apache OpenEJB development community
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+

Propchange: openejb/trunk/openejb3/container/openejb-junit/NOTICE
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/pom.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/pom.xml?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/pom.xml (added)
+++ openejb/trunk/openejb3/container/openejb-junit/pom.xml Tue Feb 23 03:49:56 2010
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+  <parent>
+    <artifactId>container</artifactId>
+    <groupId>org.apache.openejb</groupId>
+    <version>3.1.3-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>openejb-junit</artifactId>
+  <packaging>jar</packaging>
+  <name>OpenEJB :: Container :: JUnit</name>
+  <build>
+     <plugins>
+        <plugin>
+           <groupId>org.apache.maven.plugins</groupId>
+           <artifactId>maven-compiler-plugin</artifactId>
+           <version>2.0.2</version>
+           <configuration>
+              <source>1.5</source>
+              <target>1.5</target>
+           </configuration>
+        </plugin>
+     </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.openejb</groupId>
+      <artifactId>openejb-core</artifactId>
+      <version>${version}</version>
+    </dependency>
+  </dependencies>
+  <properties>
+    <netbeans.hint.license>openejb</netbeans.hint.license>
+  </properties>
+</project>
+

Propchange: openejb/trunk/openejb3/container/openejb-junit/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/JUnit4Runner.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/JUnit4Runner.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/JUnit4Runner.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/JUnit4Runner.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,165 @@
+/**
+ * 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.
+ */
+
+package org.apache.openejb.junit;
+
+import org.apache.openejb.junit.annotations.TestSecurity;
+import org.apache.openejb.junit.context.ContextWrapperStatement;
+import org.apache.openejb.junit.context.TestContext;
+import org.apache.openejb.junit.model.MultiStatementExecutor;
+import org.junit.internal.runners.model.ReflectiveCallable;
+import org.junit.internal.runners.statements.ExpectException;
+import org.junit.internal.runners.statements.Fail;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+
+import javax.ejb.EJBAccessException;
+
+/**
+ * @author quintin
+ */
+public class JUnit4Runner extends BlockJUnit4ClassRunner {
+    private OpenEjbRunner runner;
+
+    public JUnit4Runner(OpenEjbRunner runner, Class<?> testClazz) throws InitializationError {
+        super(testClazz);
+        this.runner = runner;
+    }
+
+    /**
+     * @return the main runner
+     */
+    protected OpenEjbRunner getOpenEjbRunner() {
+        return runner;
+    }
+
+    /**
+     * Prepares a method statement, configuring it for the test context
+     */
+    @Override
+    protected Statement methodBlock(FrameworkMethod method) {
+        // check if either the method/class is annotated with the TestSecurity annotation
+        TestSecurity testSecurity = null;
+        if (method.getMethod().isAnnotationPresent(TestSecurity.class)) {
+            testSecurity = method.getMethod().getAnnotation(TestSecurity.class);
+        } else if (getTestClass().getJavaClass().isAnnotationPresent(TestSecurity.class)) {
+            testSecurity = getTestClass().getJavaClass().getAnnotation(TestSecurity.class);
+        }
+
+        // no security to run as, just create a normal statement
+        if (testSecurity == null ||
+                (testSecurity.authorized().length == 0 && testSecurity.unauthorized().length == 0)) {
+            return createUnsecuredStatement(method);
+        }
+        // security roles specified, create separate statements for them all
+        else {
+            return createSecuredStatementExecutor(method, testSecurity);
+        }
+    }
+
+    /**
+     * Builds a method statement that executes in an unauthenticated context
+     */
+    protected Statement createUnsecuredStatement(FrameworkMethod method) {
+        Object test = newTestInstance();
+
+        Statement statement = methodInvoker(method, test);
+        statement = possiblyExpectingExceptions(method, test, statement);
+        statement = withPotentialTimeout(method, test, statement);
+        statement = withBefores(method, test, statement);
+        statement = withAfters(method, test, statement);
+
+        TestContext context = runner.newTestContext(method.getMethod());
+        return new ContextWrapperStatement(context, statement, test);
+    }
+
+    /**
+     * Create a method statement that executes the test for each of the specified
+     * roles, both doing authorized and unauthorized tests.
+     * <p/>
+     * Unauthorized roles are configured to fail with EJBAccessExceptions.
+     *
+     * @param method
+     * @param testSecurity
+     * @return created statement
+     */
+    private Statement createSecuredStatementExecutor(FrameworkMethod method, TestSecurity testSecurity) {
+        MultiStatementExecutor statementExecutor = new MultiStatementExecutor();
+
+        for (String role : testSecurity.authorized()) {
+            Statement statement = createSecuredStatement(method, role, false);
+            statementExecutor.addStatement(statement);
+        }
+
+        for (String role : testSecurity.unauthorized()) {
+            Statement statement = createSecuredStatement(method, role, true);
+            statementExecutor.addStatement(statement);
+        }
+
+        return statementExecutor;
+    }
+
+    /**
+     * Create a new statement to run with a given role and whether it should fail or not.
+     *
+     * @param method
+     * @param role
+     * @param failWithAccessException
+     * @return statement
+     */
+    private Statement createSecuredStatement(FrameworkMethod method, String role, boolean failWithAccessException) {
+        Object test = newTestInstance();
+
+        Statement statement = methodInvoker(method, test);
+        statement = possiblyExpectingAccessException(statement, failWithAccessException);
+        statement = possiblyExpectingExceptions(method, test, statement); // specified in @Test
+        statement = withPotentialTimeout(method, test, statement);
+        statement = withBefores(method, test, statement);
+        statement = withAfters(method, test, statement);
+
+        TestContext context = runner.newTestContext(method.getMethod(), role);
+        return new ContextWrapperStatement(context, statement, test);
+    }
+
+    protected Statement possiblyExpectingAccessException(Statement next, boolean failWithAccessException) {
+        if (failWithAccessException) {
+            return new ExpectException(next, EJBAccessException.class);
+        } else {
+            return next;
+        }
+    }
+
+    /**
+     * Creates a new test instance
+     *
+     * @return new instance
+     */
+    private Object newTestInstance() {
+        try {
+            return new ReflectiveCallable() {
+                @Override
+                protected Object runReflectiveCall() throws Throwable {
+                    return createTest();
+                }
+            }.run();
+        } catch (Throwable e) {
+            return new Fail(e);
+        }
+    }
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/JUnit4Runner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/OpenEjbRunner.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/OpenEjbRunner.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/OpenEjbRunner.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/OpenEjbRunner.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,167 @@
+/**
+ * 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.
+ */
+/**
+ * TODO: Decide what to do when the user already specifies a login module/configuration to use. We need to either provide a way to authenticate against this, or disable the securityRole option. Discuss with dblevins
+ */
+package org.apache.openejb.junit;
+
+import junit.framework.TestCase;
+import org.apache.openejb.junit.context.OpenEjbTestContext;
+import org.apache.openejb.junit.context.TestContext;
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.InitializationError;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+/**
+ * To make your own runner, extend this class replacing {@link #newTestContext(java.lang.Class) }
+ * and {@link #newTestContext(java.lang.Class, java.lang.reflect.Method) }, which
+ * would return an implementation of {@link TestContext}
+ *
+ * @author quintin
+ */
+public class OpenEjbRunner extends Runner {
+    private Runner delegate;
+
+    /**
+     * Test class
+     */
+    private Class<?> testClazz;
+
+    /**
+     * Stores the TestContext where only the class configuration is used.
+     */
+    private TestContext classTestContext;
+
+    /**
+     * Creates a new runner (called by JUnit)
+     *
+     * @param testClazz
+     * @throws InitializationError
+     */
+    public OpenEjbRunner(Class<?> testClazz) throws InitializationError {
+        try {
+            delegate = getDelegateRunner(testClazz);
+        }
+        catch (Throwable e) {
+            throw new InitializationError(Arrays.asList(e));
+        }
+    }
+
+    /**
+     * Determines, based on the test class which runner we should delegate the
+     * actual JUnit logic to.
+     *
+     * @param testClazz
+     * @return the delegate runner
+     * @throws Throwable NFC! Not like you need to declare you're throwing an Error
+     */
+    protected Runner getDelegateRunner(Class<?> testClazz) throws Throwable {
+        if (TestCase.class.isAssignableFrom(testClazz)) {
+            throw new UnsupportedOperationException("JUnit 3 tests not supported yet.");
+        } else {
+            return new JUnit4Runner(this, testClazz);
+        }
+    }
+
+    /**
+     * @param clazz
+     * @return a new class level context
+     * @see #newTestContext(java.lang.String)
+     */
+    public TestContext newTestContext() {
+        return newTestContext((String) null);
+    }
+
+    /**
+     * This implementation returns a singleton context. Contexts can be reused and aren't
+     * attached to a specific instance, so in cases where none of the test's methods
+     * have their own configurations, we don't need to construct a new context with
+     * every call. This counts even for classes where only some methods have their
+     * own contexts, we still benefit from reuse. In those few cases where there is
+     * only a single method that doesn't have configuration, we might store the
+     * context for no reason, and not free the memory throughout the run, though this
+     * is probably quite rare and doesn't really matter.
+     *
+     * @param clazz
+     * @return a new class level context
+     */
+    public TestContext newTestContext(String roleName) {
+        if (classTestContext == null) {
+            classTestContext = new OpenEjbTestContext(testClazz);
+        }
+        return classTestContext;
+    }
+
+    /**
+     * @param clazz
+     * @param method
+     * @return a new method level context
+     * @see #newTestContext(java.lang.reflect.Method, java.lang.String)
+     */
+    public TestContext newTestContext(Method method) {
+        return newTestContext(method, null);
+    }
+
+    /**
+     * This accepts a null method. Might make it easier to initialize new contexts
+     * from the delegate runner (which calls back here). The cohesion isn't that great
+     * but is the best I could come up with for delegating to both JUnit 3 and 4.
+     * <p/>
+     * The alternative was a context factory - though that introduced a new class and
+     * made extending it more complex as 3 classes are needed - a runner to identify the
+     * factory, a factory and a context. Either that or you need to specify the
+     * factory class in every test.
+     *
+     * @param clazz
+     * @param method
+     * @param role   Role to execute the context in.
+     * @return a new method level context
+     */
+    public TestContext newTestContext(Method method, String roleName) {
+        if (method == null) {
+            return newTestContext(roleName);
+        } else {
+            return new OpenEjbTestContext(method, roleName);
+        }
+    }
+
+    @Override
+    public Description getDescription() {
+        return delegate.getDescription();
+    }
+
+    @Override
+    public void run(RunNotifier runNotifier) {
+        delegate.run(runNotifier);
+    }
+
+    @Override
+    public int testCount() {
+        return delegate.testCount();
+    }
+
+    /**
+     * @return the test class being run by this runner
+     */
+    protected Class<?> getTestClass() {
+        return testClazz;
+    }
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/OpenEjbRunner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/ContextConfig.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/ContextConfig.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/ContextConfig.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/ContextConfig.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,62 @@
+/**
+ * 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.
+ */
+
+package org.apache.openejb.junit.annotations;
+
+import org.apache.openejb.junit.OpenEjbRunner;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * @author quintin
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ContextConfig {
+    /**
+     * Reference to InitialContext configuration resource file. It should be a resource
+     * in the annotated class' classpath. If both a method/class has this value specified,
+     * then the class' file will be loaded first, and thus properties in the method's file
+     * will overwrite those from the class'.
+     * <p/>
+     * If the file is not found a FileNotFoundException will be raised.
+     * <p/>
+     * Using the {@link OpenEjbRunner} runner, this will be a reference to a standard properties file.
+     */
+    String configFile() default "";
+
+    /**
+     * Array of properties. The properties file has precedency in being loaded, so
+     * any properties listed here will overwrite those loaded from the properties file.
+     * <p/>
+     * Again, a Method's properties are loaded after a class' properties, so will
+     * overwrite those from the method.
+     * <p/>
+     * If you specify both a properties file and properties for both a method and a class,
+     * first the class' file and properties will be loaded, then the method's file
+     * and properties, so the precedency is effectively the following:
+     * <ol>
+     * <li>Class properties file
+     * <li>Class properties
+     * <li>Method properties file
+     * <li>Method properties
+     * </ol>
+     * <p/>
+     * If any property's names are null, then the property will simply be ignored.
+     */
+    Property[] properties() default {};
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/ContextConfig.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/Property.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/Property.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/Property.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/Property.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,28 @@
+/**
+ * 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.
+ */
+
+package org.apache.openejb.junit.annotations;
+
+/**
+ * @author quintin
+ */
+public @interface Property {
+    /**
+     * Property in the form "name=value". The cannot not be null
+     */
+    String value();
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/Property.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/RunTestAs.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/RunTestAs.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/RunTestAs.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/RunTestAs.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,38 @@
+/*
+ * Unless otherwise stated, this program in binary or source code
+ * format and any accompanying media/files/resources are
+ * Copyright 2009 Kunye Mining Solutions
+ * 
+ * Contact Details
+ * ------------------------------------------------
+ *   Web Site: http://www.kunye.net
+ *  Telephone: +27 12 807 3590/1
+ *        Fax: +27 12 807 3592
+ *       Cell: +27 82 855 5907
+ *     E-Mail: akruger@kunye.net
+ * 
+ * Postal Address
+ * ------------------------------------------------
+ *  P.O. Box 70032
+ *  Die Wilgers
+ *  Pretoria
+ *  0041
+ */
+package org.apache.openejb.junit.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author quintin
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RunTestAs {
+    /**
+     * Role as which the test should be run
+     */
+    String value();
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/RunTestAs.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestResource.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestResource.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestResource.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestResource.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,32 @@
+/**
+ * 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.
+ */
+
+package org.apache.openejb.junit.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author quintin
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TestResource {
+    String value();
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestResource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestResourceTypes.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestResourceTypes.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestResourceTypes.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestResourceTypes.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,27 @@
+/**
+ * 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.
+ */
+
+package org.apache.openejb.junit.annotations;
+
+/**
+ * @author quintin
+ */
+public interface TestResourceTypes {
+    public static final String CONTEXT_CONFIG = "org.apache.openejb.junit.context-config";
+
+    public static final String INITIALCONTEXT = "org.apache.openejb.junit.initial-context";
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestResourceTypes.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestSecurity.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestSecurity.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestSecurity.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestSecurity.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,45 @@
+/*
+ * Unless otherwise stated, this program in binary or source code
+ * format and any accompanying media/files/resources are
+ * Copyright 2009 Kunye Mining Solutions
+ * 
+ * Contact Details
+ * ------------------------------------------------
+ *   Web Site: http://www.kunye.net
+ *  Telephone: +27 12 807 3590/1
+ *        Fax: +27 12 807 3592
+ *       Cell: +27 82 855 5907
+ *     E-Mail: akruger@kunye.net
+ * 
+ * Postal Address
+ * ------------------------------------------------
+ *  P.O. Box 70032
+ *  Die Wilgers
+ *  Pretoria
+ *  0041
+ */
+package org.apache.openejb.junit.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author quintin
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TestSecurity {
+    public static final String UNAUTHENTICATED = "";
+
+    /**
+     * List of roles for which the test should succeed.
+     */
+    String[] authorized() default {};
+
+    /**
+     * List of roles for which the test should fail with an EJBAccessException
+     */
+    String[] unauthorized() default {};
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/annotations/TestSecurity.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/ContextWrapperStatement.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/ContextWrapperStatement.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/ContextWrapperStatement.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/ContextWrapperStatement.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,43 @@
+/**
+ * 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.
+ */
+
+package org.apache.openejb.junit.context;
+
+import org.junit.runners.model.Statement;
+
+/**
+ * @author quintin
+ */
+public class ContextWrapperStatement extends Statement {
+    private TestContext testContext;
+
+    private Statement junitStatement;
+
+    private Object testObj;
+
+    public ContextWrapperStatement(TestContext testContext, Statement junitStatement, Object testObj) {
+        this.testContext = testContext;
+        this.junitStatement = junitStatement;
+        this.testObj = testObj;
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+        testContext.configureTest(testObj);
+        junitStatement.evaluate();
+    }
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/ContextWrapperStatement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/OpenEjbTestContext.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/OpenEjbTestContext.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/OpenEjbTestContext.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/OpenEjbTestContext.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,394 @@
+/**
+ * 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.
+ */
+
+package org.apache.openejb.junit.context;
+
+import org.apache.openejb.api.LocalClient;
+import org.apache.openejb.junit.annotations.ContextConfig;
+import org.apache.openejb.junit.annotations.Property;
+import org.apache.openejb.junit.annotations.RunTestAs;
+import org.apache.openejb.junit.annotations.TestResource;
+import org.apache.openejb.junit.annotations.TestResourceTypes;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.URLDecoder;
+import java.util.Properties;
+
+/**
+ * To implement your own context, you need to create an implementation of TestContext
+ * which would configure the test when instructed. You can then use whatever method
+ * of configuration you choose.
+ *
+ * @author quintin
+ */
+public class OpenEjbTestContext implements TestContext {
+    protected static final String REALM_PROPERTY_KEY = "openejb.authentication.realmName";
+
+    protected static final String LOGIN_CONFIG_RESOURCE = "/META-INF/openejb-test-login.config";
+
+    protected static final String DEFAULT_CONFIG_FILE_RESOURCE = "/META-INF/default-openejb-test-config.properties";
+
+    /**
+     * Properties object used to initialize InitialContext
+     */
+    protected Properties contextConfig;
+
+    /**
+     * Context's InitialContext
+     */
+    private InitialContext initialContext;
+
+    /**
+     * Test class
+     */
+    private Class<?> clazz;
+
+    /**
+     * Method being run on test
+     */
+    private Method method;
+
+    /**
+     * Security role to execute as
+     */
+    private String securityRole;
+
+    /**
+     * Constructs a context for a class
+     *
+     * @param testClazz
+     */
+    public OpenEjbTestContext(Class clazz) {
+        this(clazz, null);
+    }
+
+    /**
+     * Constructs a context for a method
+     *
+     * @param testClazz
+     * @param method
+     */
+    public OpenEjbTestContext(Method method) {
+        this(method, null);
+    }
+
+    /**
+     * Constructs a context for a class
+     *
+     * @param testClazz
+     */
+    public OpenEjbTestContext(Class clazz, String securityRole) {
+        this.clazz = clazz;
+        this.securityRole = securityRole;
+    }
+
+    /**
+     * Constructs a context for a method
+     *
+     * @param testClazz
+     * @param method
+     */
+    public OpenEjbTestContext(Method method, String securityRole) {
+        this.clazz = method.getDeclaringClass();
+        this.method = method;
+        this.securityRole = securityRole;
+    }
+
+    public void configureTest(Object testObj) {
+        try {
+            if (testObj.getClass().isAnnotationPresent(LocalClient.class)) {
+                getInitialContext().bind("inject", testObj);
+            }
+
+            // perform custom injections
+            performInjections(testObj);
+        }
+        catch (IOException e) {
+            throw new RuntimeException("Failed to load configuration.", e);
+        }
+        catch (NamingException e) {
+            throw new RuntimeException("Failed to configure object.", e);
+        }
+        catch (Exception e) {
+            throw new RuntimeException("Unknown error trying to configure object.", e);
+        }
+    }
+
+    /**
+     * Returns this context's InitialContext, creating it if necessary.
+     *
+     * @return InitialContext for this TestContext
+     * @throws NamingException
+     */
+    protected InitialContext getInitialContext() throws NamingException {
+        if (initialContext == null) {
+            // set the property for security realm RIGHT before we load the InitialContext
+            String loginConfig = OpenEjbTestContext.class.getResource(LOGIN_CONFIG_RESOURCE).toExternalForm();
+            System.setProperty("java.security.auth.login.config", URLDecoder.decode(loginConfig));
+
+            try {
+                Properties config = getContextConfig();
+                initialContext = new InitialContext(config);
+            }
+            catch (IOException e) {
+                throw new NamingException("Failed to load initial context configuration: " + e.getMessage());
+            }
+        }
+
+        return initialContext;
+    }
+
+    /**
+     * Constructs the configuration needed to create the InitialContext. This will
+     * be determined from the class/method supplied to the constructor.
+     *
+     * @return
+     */
+    protected Properties getContextConfig() throws IOException {
+        if (contextConfig != null) {
+            return contextConfig;
+        }
+
+        Properties env = new Properties();
+        boolean loadedConfig = false;
+
+        if (clazz.isAnnotationPresent(ContextConfig.class)) {
+            loadedConfig |= loadConfig(env, clazz.getAnnotation(ContextConfig.class));
+        }
+
+        if (method != null && method.isAnnotationPresent(ContextConfig.class)) {
+            loadedConfig |= loadConfig(env, method.getAnnotation(ContextConfig.class));
+        }
+
+        // no properties loaded, use the "default" configuration
+        if (!loadedConfig) {
+            InputStream in = OpenEjbTestContext.class.getResourceAsStream(DEFAULT_CONFIG_FILE_RESOURCE);
+            if (in == null) {
+                throw new FileNotFoundException("Default configuration file not found. Specify configuration " +
+                        "properties to initialize OpenEJB using @ContextConfig.");
+            }
+            env.load(in);
+
+            // if it's still empty, something bad has happened, and OpenEJB won't initialize. Complain.
+            if (env.size() == 0) {
+                throw new IOException("Context configuration failed to load, so OpenEJB won't load either. Specify configuration " +
+                        "properties for initializing OpenEJB using @ContextConfig.");
+            }
+        }
+
+        configureSecurity(env);
+
+        contextConfig = env;
+        return env;
+    }
+
+    /**
+     * Interprets and loads InitialContext properties from the ContextConfig annotation
+     *
+     * @param env
+     * @param contextConfig
+     * @return true if any properties were loaded
+     */
+    protected boolean loadConfig(Properties env, ContextConfig contextConfig) throws IOException {
+        boolean loadedConfig = false;
+
+        loadedConfig = loadConfigFile(env, contextConfig);
+        loadedConfig |= loadConfigProperties(env, contextConfig);
+
+        return loadedConfig;
+    }
+
+    /**
+     * Loads the direct properties from the annotation configuration into the given Properties object
+     *
+     * @param env
+     * @param contextConfig
+     * @return true if any properties were loaded
+     */
+    protected boolean loadConfigProperties(Properties env, ContextConfig contextConfig) {
+        boolean loadedConfig = false;
+
+        if (contextConfig.properties().length > 0) {
+            for (Property p : contextConfig.properties()) {
+                if (p.value() != null) {
+                    loadedConfig = true;
+                    Util.addProperty(env, p.value());
+                }
+            }
+        }
+
+        return loadedConfig;
+    }
+
+    /**
+     * Loads the configuration file specified in the {@link ContextConfig} annotation
+     * into the specified Properties instance
+     *
+     * @param env
+     * @param contextConfig
+     * @return true if any properties were loaded
+     */
+    protected boolean loadConfigFile(Properties env, ContextConfig contextConfig)
+            throws IOException {
+        // properties file
+        if (contextConfig.configFile().length() > 0) {
+            InputStream in = clazz.getResourceAsStream(contextConfig.configFile());
+            if (in == null) {
+                throw new FileNotFoundException("Cannot find resource '" + contextConfig.configFile() + "' in classpath: " + clazz.getName());
+            }
+            env.load(in);
+
+            return env.size() > 0;
+        }
+
+        return false;
+    }
+
+    /**
+     * Loads the security configuration into the given Properties object
+     *
+     * @param env
+     */
+    protected void configureSecurity(Properties env) {
+        // if a securityRole isn't already configured, use the RunTestAs annotation if available
+        if (securityRole == null) {
+            if (method != null && method.isAnnotationPresent(RunTestAs.class)) {
+                securityRole = method.getAnnotation(RunTestAs.class).value();
+            } else if (clazz.isAnnotationPresent(RunTestAs.class)) {
+                securityRole = clazz.getAnnotation(RunTestAs.class).value();
+            }
+        }
+
+        if (securityRole != null) {
+            env.put(REALM_PROPERTY_KEY, "OpenEjbJunitSecurityRealm");
+            env.put(InitialContext.SECURITY_PRINCIPAL, securityRole);
+            env.put(InitialContext.SECURITY_CREDENTIALS, "[no-password-needed]");
+        }
+    }
+
+    /**
+     * Performs any non-OpenEJB type injections on the test object. It will "prefer"
+     * a setter, and therefore I made it work on private fields as well. So if you
+     * are injecting to a private field and wish to have some control over it, create
+     * a setter according to the JavaBeans idioms.
+     * <p/>
+     * If the setter isn't found OR it fails, then an attempt will be made to set
+     * it directly, and a message will be printed when it fails.
+     */
+    private void performInjections(Object testObj) throws Exception {
+        for (Field field : clazz.getDeclaredFields()) {
+            Object injectValue = getInjectionValue(field);
+
+            // no value determined, try next field
+            if (injectValue == null) {
+                continue;
+            }
+
+            // now inject it through the setter
+            try {
+                Method setterMethod = Util.findSetter(clazz, field, injectValue);
+                if (setterMethod != null) {
+                    setterMethod.invoke(testObj, injectValue);
+                    continue;
+                }
+            }
+            catch (Exception e) {
+                System.err.println("Failed to perform setter injection on: " + clazz.getCanonicalName() + "." + field.getName());
+                e.printStackTrace();
+            }
+
+            // do direct injection
+            try {
+                if (!Modifier.isPublic(field.getModifiers())) {
+                    field.setAccessible(true);
+                }
+
+                field.set(testObj, injectValue);
+            }
+            catch (Exception e) {
+                throw new RuntimeException("Failed to inject on: " + clazz.getCanonicalName() + "." + field.getName(), e);
+            }
+        }
+    }
+
+    /**
+     * Analyzes the field and returns any values which should be injected on it
+     *
+     * @param field
+     * @return reference to value to inject, or null if nothing should be injected
+     */
+    protected Object getInjectionValue(Field field) throws Exception {
+        // determine the value to inject
+        if (field.isAnnotationPresent(TestResource.class)) {
+            TestResource resourceConfig = field.getAnnotation(TestResource.class);
+            String resourceType = resourceConfig.value();
+
+            if (resourceType == null) {
+                throw new IllegalArgumentException("Null TestResource type '" + resourceType +
+                        "' on field: " + clazz.getCanonicalName() + "." + field.getName());
+            } else {
+                if (TestResourceTypes.CONTEXT_CONFIG.equals(resourceType)) {
+                    return getContextConfig();
+                } else if (TestResourceTypes.INITIALCONTEXT.equals(resourceType)) {
+                    return getInitialContext();
+                } else {
+                    return getOtherTestResource(resourceConfig);
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Override to perform custom resource types injection. This method will be called
+     * when whatever value was specified in the {@link TestResource} annotation wasn't
+     * understood by the {@link #performInjections(java.lang.Object) } method. This
+     * method will be called, supplying the annotation, and you can then interpret and
+     * create the value to be injected. By default this method just returns null.
+     * <p/>
+     * You can use this to inject values into annotated fields which contain custom
+     * values in their names.
+     *
+     * @param resourceConfig
+     * @return instance to inject into annotated field.
+     */
+    protected Object getOtherTestResource(TestResource resourceConfig) {
+        return null;
+    }
+
+    /**
+     * @return the test class
+     */
+    protected Class<?> getTestClass() {
+        return clazz;
+    }
+
+    /**
+     * @return the test method for which this context was created
+     */
+    protected Method getTestMethod() {
+        return method;
+    }
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/OpenEjbTestContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/TestContext.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/TestContext.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/TestContext.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/TestContext.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,28 @@
+/**
+ * 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.
+ */
+
+package org.apache.openejb.junit.context;
+
+/**
+ * @author quintin
+ */
+public interface TestContext {
+    /**
+     * Configures a test instance for this context
+     */
+    public void configureTest(Object testObj);
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/TestContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/Util.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/Util.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/Util.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/Util.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,201 @@
+/**
+ * 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.
+ */
+
+package org.apache.openejb.junit.context;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ * @author quintin
+ */
+public class Util {
+    private Util() {
+    }
+
+    /**
+     * @param type
+     * @param instance
+     * @return true if the given object is of the specify type of class
+     */
+    public static boolean isInstance(Class type, Object instance) {
+        if (type.isPrimitive()) {
+            // for primitives the insance can't be null
+            if (instance == null) {
+                return false;
+            }
+
+            // verify instance is the correct wrapper type
+            if (type.equals(boolean.class)) {
+                return instance instanceof Boolean;
+            } else if (type.equals(char.class)) {
+                return instance instanceof Character;
+            } else if (type.equals(byte.class)) {
+                return instance instanceof Byte;
+            } else if (type.equals(short.class)) {
+                return instance instanceof Short;
+            } else if (type.equals(int.class)) {
+                return instance instanceof Integer;
+            } else if (type.equals(long.class)) {
+                return instance instanceof Long;
+            } else if (type.equals(float.class)) {
+                return instance instanceof Float;
+            } else if (type.equals(double.class)) {
+                return instance instanceof Double;
+            } else {
+                throw new AssertionError("Invalid primitve type: " + type);
+            }
+        }
+
+        return instance == null || type.isInstance(instance);
+    }
+
+    /**
+     * Parses an @Property value and adds it to the specified Hashtable
+     *
+     * @param env
+     * @param value
+     */
+    public static void addProperty(Hashtable env, String property) {
+        if (property == null || property.length() == 0) {
+            throw new IllegalArgumentException("No property specified.");
+        }
+
+        if (property.charAt(0) == '=') {
+            throw new IllegalArgumentException("Invalid property has no name: " + property);
+        }
+
+        String name, value;
+
+        property = property.trim();
+
+        int esp = property.indexOf('=');
+        if (esp < 0) {
+            name = property;
+            value = "";
+        } else {
+            name = property.substring(0, esp).trim();
+
+            if (property.length() > esp) {
+                value = property.substring(esp + 1).trim();
+            } else {
+                value = "";
+            }
+        }
+
+        env.put(name, value);
+    }
+
+    /**
+     * Finds the setter method for a given field in the test class
+     *
+     * @param allowStatic
+     * @param typeClass
+     * @param propertyName
+     * @param propertyValue
+     * @return setter Method or NULL if not found
+     */
+    public static Method findSetter(Class<?> testClazz, Field field, Object propertyValue) {
+        String propertyName = field.getName();
+        boolean isStatic = Modifier.isStatic(field.getModifiers());
+
+        String setterName = "set" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
+
+        List<Method> methods = new ArrayList<Method>(Arrays.asList(testClazz.getMethods()));
+        methods.addAll(Arrays.asList(testClazz.getDeclaredMethods()));
+        Method unpreferredValidMethod = null;
+        for (Method clazzMethod : methods) {
+            if (clazzMethod.getName().equals(setterName)) {
+                if (clazzMethod.getParameterTypes().length == 0) {
+                    continue;
+                }
+
+                if (clazzMethod.getParameterTypes().length > 1) {
+                    continue;
+                }
+
+                if (clazzMethod.getReturnType() != Void.TYPE) {
+                    continue;
+                }
+
+                if (Modifier.isAbstract(clazzMethod.getModifiers())) {
+                    continue;
+                }
+
+                Class methodParameterType = clazzMethod.getParameterTypes()[0];
+                if (methodParameterType.isPrimitive() && propertyValue == null) {
+                    continue;
+                }
+
+                // Method is static, but field isn't. Can't work
+                if (!isStatic && Modifier.isStatic(clazzMethod.getModifiers())) {
+                    continue;
+                }
+
+                if (!Modifier.isPublic(clazzMethod.getModifiers())) {
+                    clazzMethod.setAccessible(true);
+                }
+
+                if (!isInstance(methodParameterType, propertyValue)) {
+                    continue;
+                }
+                // not necessarily the BEST match
+                else if (methodParameterType != propertyValue.getClass()) {
+                    if (unpreferredValidMethod == null) {
+                        unpreferredValidMethod = clazzMethod;
+                    } else {
+                        unpreferredValidMethod = getMostSpecificMethod(unpreferredValidMethod, clazzMethod);
+                    }
+                    continue;
+                }
+
+                return clazzMethod;
+            }
+        }
+
+        return unpreferredValidMethod;
+    }
+
+    /**
+     * Returns the most specific of the 2 methods. When calling this method both should
+     * already match as valid calls, so the most specific will be the one where subtype
+     * relation holds against the other.
+     * <p/>
+     * We also assume that the only difference between the method signatures is the type
+     * of it's first argument, and thus that their first arguments can't be of the
+     * same type.
+     *
+     * @param unpreferredValidMethod
+     * @param clazzMethod
+     * @return most specific method
+     */
+    public static Method getMostSpecificMethod(Method method1, Method method2) {
+        Class<?> class1 = method1.getParameterTypes()[0];
+        Class<?> class2 = method2.getParameterTypes()[0];
+
+        if (class1.isAssignableFrom(class2)) {
+            return method2;
+        } else {
+            return method1;
+        }
+    }
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/context/Util.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/model/MultiStatementExecutor.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/model/MultiStatementExecutor.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/model/MultiStatementExecutor.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/model/MultiStatementExecutor.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,44 @@
+/**
+ * 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.
+ */
+package org.apache.openejb.junit.model;
+
+import org.junit.runners.model.Statement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author quintin
+ */
+public class MultiStatementExecutor extends Statement {
+    private List<Statement> statements = new ArrayList<Statement>();
+
+    public MultiStatementExecutor() {
+
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+        for (Statement statement : statements) {
+            statement.evaluate();
+        }
+    }
+
+    public void addStatement(Statement statement) {
+        statements.add(statement);
+    }
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/model/MultiStatementExecutor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/security/TestLoginModule.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/security/TestLoginModule.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/security/TestLoginModule.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/security/TestLoginModule.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,94 @@
+/**
+ * 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.
+ */
+
+package org.apache.openejb.junit.security;
+
+import org.apache.openejb.core.security.jaas.GroupPrincipal;
+import org.apache.openejb.core.security.jaas.UserPrincipal;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This is used to "emulate" a login for the "securityRole" option in the JUnit runner.
+ * The TestContext should set the {@link Context#SECURITY_PRINCIPAL } {@link InitialContext} property
+ * to the rolename it wants to "RunAs", and this login module will do the result.
+ *
+ * @author quintin
+ */
+public class TestLoginModule implements LoginModule {
+    private Subject subject;
+
+    private CallbackHandler callbackHandler;
+
+    private String user;
+
+    private Set principals = new HashSet();
+
+    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
+        this.subject = subject;
+        this.callbackHandler = callbackHandler;
+    }
+
+    public boolean login() throws LoginException {
+        Callback[] callbacks = new Callback[2];
+
+        callbacks[0] = new NameCallback("Username:");
+        callbacks[1] = new PasswordCallback("Password:", false);
+        try {
+            callbackHandler.handle(callbacks);
+        }
+        catch (Exception e) {
+            throw new LoginException("Failed to perform emulated login: " + e.getMessage());
+        }
+
+        user = ((NameCallback) callbacks[0]).getName();
+
+        return true;
+    }
+
+    public boolean commit() throws LoginException {
+        principals.add(new UserPrincipal(user));
+        principals.add(new GroupPrincipal(user));
+
+        subject.getPrincipals().addAll(principals);
+
+        user = null;
+        return true;
+    }
+
+    public boolean abort() throws LoginException {
+        user = null;
+        return true;
+    }
+
+    public boolean logout() throws LoginException {
+        subject.getPrincipals().removeAll(principals);
+        principals.clear();
+        return true;
+    }
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/security/TestLoginModule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/default-openejb-test-config.properties
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/default-openejb-test-config.properties?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/default-openejb-test-config.properties (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/default-openejb-test-config.properties Tue Feb 23 03:49:56 2010
@@ -0,0 +1,2 @@
+java.naming.factory.initial=org.apache.openejb.client.LocalInitialContextFactory
+org.apache.openejb.junit.default-config=true
\ No newline at end of file

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/default-openejb-test-config.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/openejb-test-login.config
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/openejb-test-login.config?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/openejb-test-login.config (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/openejb-test-login.config Tue Feb 23 03:49:56 2010
@@ -0,0 +1,3 @@
+OpenEjbJunitSecurityRealm {
+    org.apache.openejb.junit.security.TestLoginModule required;
+};

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/main/resources/META-INF/openejb-test-login.config
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestClassConfigFile.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestClassConfigFile.java?rev=915166&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestClassConfigFile.java (added)
+++ openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestClassConfigFile.java Tue Feb 23 03:49:56 2010
@@ -0,0 +1,55 @@
+/**
+ * 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.
+ */
+
+package org.apache.openejb.junit;
+
+import org.apache.openejb.junit.annotations.ContextConfig;
+import org.apache.openejb.junit.annotations.TestResource;
+import org.apache.openejb.junit.annotations.TestResourceTypes;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Hashtable;
+
+/**
+ * @author quintin
+ */
+@RunWith(OpenEjbRunner.class)
+@ContextConfig(
+        configFile = "/META-INF/test-config.properties"
+)
+public class TestClassConfigFile {
+    @TestResource(TestResourceTypes.CONTEXT_CONFIG)
+    private Hashtable<String, String> contextConfig;
+
+    public TestClassConfigFile() {
+    }
+
+    @Test
+    public void testConfig() {
+        assertNotNull(contextConfig);
+
+        checkProperty("junit.test-property", "Test String");
+    }
+
+    private void checkProperty(String key, String expected) {
+        String value = contextConfig.get(key);
+        assertEquals(expected, value);
+    }
+}

Propchange: openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestClassConfigFile.java
------------------------------------------------------------------------------
    svn:eol-style = native