From eed639ccf7fd95e0b31caf61787126e69592f207 Mon Sep 17 00:00:00 2001 From: ramkumar Date: Tue, 2 Dec 2008 11:17:24 +0000 Subject: Branch for 1.4 git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@722428 13f79535-47bb-0310-9956-ffa450edef68 --- .../modules/implementation-spring/LICENSE | 205 +++++++ .../modules/implementation-spring/NOTICE | 6 + .../modules/implementation-spring/pom.xml | 119 ++++ .../spring/SCAApplicationContext.java | 53 ++ .../spring/SCANamespaceHandlerResolver.java | 53 ++ .../spring/SCAParentApplicationContext.java | 271 +++++++++ .../implementation/spring/ScaNamespaceHandler.java | 38 ++ .../spring/ScaPropertyBeanDefinitionParser.java | 35 ++ .../spring/ScaReferenceBeanDefinitionParser.java | 36 ++ .../spring/ScaServiceBeanDefinitionParser.java | 36 ++ .../spring/SpringBeanNotFoundException.java | 39 ++ .../spring/SpringImplementation.java | 192 ++++++ .../spring/SpringImplementationProcessor.java | 230 +++++++ .../spring/SpringImplementationProvider.java | 119 ++++ .../SpringImplementationProviderFactory.java | 89 +++ .../spring/SpringInvocationException.java | 40 ++ .../sca/implementation/spring/SpringInvoker.java | 127 ++++ .../spring/SpringOperationNotFoundException.java | 40 ++ .../spring/SpringPropertyValueObjectFactory.java | 45 ++ .../ComponentNameAnnotationProcessor.java | 151 +++++ .../processor/ConstructorAnnotationProcessor.java | 119 ++++ .../processor/InitDestroyAnnotationProcessor.java | 72 +++ .../processor/PropertyAnnotationProcessor.java | 220 +++++++ .../processor/ReferenceAnnotationProcessor.java | 186 ++++++ .../sca/implementation/spring/xml/Constants.java | 64 ++ .../spring/xml/SpringBeanElement.java | 67 +++ .../spring/xml/SpringBeanIntrospector.java | 147 +++++ .../spring/xml/SpringConstructorArgElement.java | 60 ++ .../spring/xml/SpringPropertyElement.java | 61 ++ .../spring/xml/SpringSCAPropertyElement.java | 52 ++ .../spring/xml/SpringSCAPropertyElement.java.orig | 44 ++ .../spring/xml/SpringSCAReferenceElement.java | 54 ++ .../spring/xml/SpringSCAServiceElement.java | 64 ++ .../spring/xml/SpringXMLComponentTypeLoader.java | 659 +++++++++++++++++++++ ...ca.contribution.processor.StAXArtifactProcessor | 19 + ...cany.sca.provider.ImplementationProviderFactory | 19 + .../src/main/resources/META-INF/spring.handlers | 1 + .../src/main/resources/META-INF/spring.schemas | 1 + .../impl-spring-validation-messages.properties | 23 + .../org/springframework/sca/xml/spring-sca.xsd | 99 ++++ .../spring/itests/AbstractSCATestCase.java | 55 ++ .../helloworld/AbstractHelloWorldTestCase.java | 43 ++ .../spring/itests/helloworld/HelloWorld.java | 35 ++ .../spring/itests/helloworld/HelloWorldImpl.java | 38 ++ .../spring/itests/helloworld/HelloWorldProxy.java | 42 ++ .../helloworld/SpringContextAccessTestCase.java | 35 ++ .../SpringExplicitHelloWorldTestCase.java | 34 ++ .../SpringExplicitReferenceTestCase.java | 39 ++ .../helloworld/SpringHelloWorldTestCase.java | 32 + .../SpringImplicitReferenceTestCase.java | 42 ++ .../helloworld/SpringImportHelloWorldTestCase.java | 32 + .../helloworld/SpringSCAPropertyTestCase.java | 39 ++ .../spring/itests/mock/TestBean.java | 31 + .../spring/itests/mock/TestBeanImpl.java | 42 ++ .../spring/itests/mock/TestContextAccessBean.java | 77 +++ .../spring/itests/mock/TestHelloWorldBean.java | 39 ++ .../spring/itests/mock/TestReference.java | 27 + .../spring/itests/mock/TestReferenceBean.java | 57 ++ .../spring/itests/mock/TestSCAPropertyBean.java | 55 ++ .../META-INF/sca/SpringContextAccess-context.xml | 31 + .../sca/SpringExplicitHelloWorld-context.xml | 39 ++ .../sca/SpringExplicitReference-context.xml | 33 ++ .../sca/SpringHelloWorld-Imported-context.xml | 31 + .../META-INF/sca/SpringHelloWorld-context.xml | 31 + .../sca/SpringImplicitReference-context.xml | 34 ++ .../sca/SpringImportHelloWorld-context.xml | 29 + .../META-INF/sca/testReferenceContext.xml | 33 ++ .../resources/META-INF/sca/testServiceContext.xml | 31 + .../SpringHelloWorld-Imported-context.xml | 31 + .../helloworld/SpringContextAccess.composite | 35 ++ .../helloworld/SpringExplicitHelloWorld.composite | 33 ++ .../helloworld/SpringExplicitReference.composite | 32 + .../itests/helloworld/SpringHelloWorld.composite | 32 + .../helloworld/SpringImplicitReference.composite | 39 ++ .../helloworld/SpringImportHelloWorld.composite | 32 + .../itests/helloworld/SpringSCAProperty.composite | 39 ++ .../src/test/resources/spring/META-INF/MANIFEST.MF | 3 + .../META-INF/spring/SpringSCAProperty-context.xml | 34 ++ .../src/test/resources/test.xml | 27 + 79 files changed, 5378 insertions(+) create mode 100644 branches/sca-java-1.4/modules/implementation-spring/LICENSE create mode 100644 branches/sca-java-1.4/modules/implementation-spring/NOTICE create mode 100644 branches/sca-java-1.4/modules/implementation-spring/pom.xml create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SCAApplicationContext.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SCANamespaceHandlerResolver.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SCAParentApplicationContext.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaNamespaceHandler.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaPropertyBeanDefinitionParser.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaReferenceBeanDefinitionParser.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaServiceBeanDefinitionParser.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringBeanNotFoundException.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementation.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationProcessor.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationProvider.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationProviderFactory.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringInvocationException.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringInvoker.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringOperationNotFoundException.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringPropertyValueObjectFactory.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentNameAnnotationProcessor.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ConstructorAnnotationProcessor.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/InitDestroyAnnotationProcessor.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyAnnotationProcessor.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ReferenceAnnotationProcessor.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/Constants.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringBeanElement.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringBeanIntrospector.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringConstructorArgElement.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringPropertyElement.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAPropertyElement.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAPropertyElement.java.orig create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAReferenceElement.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAServiceElement.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringXMLComponentTypeLoader.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/spring.handlers create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/spring.schemas create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/resources/impl-spring-validation-messages.properties create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/main/resources/org/springframework/sca/xml/spring-sca.xsd create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/AbstractSCATestCase.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/AbstractHelloWorldTestCase.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/HelloWorld.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/HelloWorldImpl.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/HelloWorldProxy.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringContextAccessTestCase.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitHelloWorldTestCase.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitReferenceTestCase.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringHelloWorldTestCase.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImplicitReferenceTestCase.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImportHelloWorldTestCase.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringSCAPropertyTestCase.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestBean.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestBeanImpl.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestContextAccessBean.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestHelloWorldBean.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestReference.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestReferenceBean.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestSCAPropertyBean.java create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringContextAccess-context.xml create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringExplicitHelloWorld-context.xml create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringExplicitReference-context.xml create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringHelloWorld-Imported-context.xml create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringHelloWorld-context.xml create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringImplicitReference-context.xml create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringImportHelloWorld-context.xml create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/testReferenceContext.xml create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/testServiceContext.xml create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/SpringHelloWorld-Imported-context.xml create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringContextAccess.composite create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitHelloWorld.composite create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitReference.composite create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringHelloWorld.composite create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImplicitReference.composite create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImportHelloWorld.composite create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringSCAProperty.composite create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/spring/META-INF/MANIFEST.MF create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/spring/META-INF/spring/SpringSCAProperty-context.xml create mode 100644 branches/sca-java-1.4/modules/implementation-spring/src/test/resources/test.xml (limited to 'branches/sca-java-1.4/modules/implementation-spring') diff --git a/branches/sca-java-1.4/modules/implementation-spring/LICENSE b/branches/sca-java-1.4/modules/implementation-spring/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/LICENSE @@ -0,0 +1,205 @@ + + 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. + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/NOTICE b/branches/sca-java-1.4/modules/implementation-spring/NOTICE new file mode 100644 index 0000000000..fdfa0e9faa --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/NOTICE @@ -0,0 +1,6 @@ +${pom.name} +Copyright (c) 2005 - 2008 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/branches/sca-java-1.4/modules/implementation-spring/pom.xml b/branches/sca-java-1.4/modules/implementation-spring/pom.xml new file mode 100644 index 0000000000..eaaa73a708 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/pom.xml @@ -0,0 +1,119 @@ + + + + 4.0.0 + + org.apache.tuscany.sca + tuscany-modules + 1.4-SNAPSHOT + ../pom.xml + + tuscany-implementation-spring + Apache Tuscany SCA Spring Framework Implementation Extension + + + + org.apache.tuscany.sca + tuscany-assembly + 1.4-SNAPSHOT + + + org.apache.tuscany.sca + tuscany-core + 1.4-SNAPSHOT + + + org.apache.tuscany.sca + tuscany-interface + 1.4-SNAPSHOT + + + org.apache.tuscany.sca + tuscany-assembly-xml + 1.4-SNAPSHOT + + + org.apache.tuscany.sca + tuscany-contribution-impl + 1.4-SNAPSHOT + + + org.apache.tuscany.sca + tuscany-sca-api + 1.4-SNAPSHOT + + + org.apache.tuscany.sca + tuscany-databinding + 1.4-SNAPSHOT + + + org.apache.tuscany.sca + tuscany-implementation-java-runtime + 1.4-SNAPSHOT + + + + org.apache.tuscany.sca + tuscany-host-embedded + 1.4-SNAPSHOT + + + + + org.springframework + spring-core + 2.5.5 + + + + org.springframework + spring-beans + 2.5.5 + + + + org.springframework + spring-context + 2.5.5 + + + + + + + + + org.apache.felix + maven-bundle-plugin + + + + ${tuscany.version} + org.apache.tuscany.sca.implementation.spring + ${pom.name} + org.apache.tuscany.sca.implementation.spring* + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SCAApplicationContext.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SCAApplicationContext.java new file mode 100644 index 0000000000..b550fc3229 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SCAApplicationContext.java @@ -0,0 +1,53 @@ +/* + * 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.tuscany.sca.implementation.spring; + +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.AbstractXmlApplicationContext; +import org.springframework.core.io.Resource; + +/** + * An ApplicationContext specialization that registers namespace + * handlers for SCA elements - in particular the , and + * elements which are provided as SCA extensions to the Spring + * application context schema + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class SCAApplicationContext extends AbstractXmlApplicationContext { + public static final String APP_CONTEXT_PROP = "org.springframework.sca.application.context"; + private Resource appXml; + + public SCAApplicationContext(ApplicationContext parent, Resource appXml) { + super(parent); + this.appXml = appXml; + //refresh(); + } + + @Override + protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) { + ClassLoader cl = getClassLoader(); + beanDefinitionReader.setNamespaceHandlerResolver(new SCANamespaceHandlerResolver(cl)); + } + + @Override + protected Resource[] getConfigResources() { + return new Resource[] {appXml}; + } +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SCANamespaceHandlerResolver.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SCANamespaceHandlerResolver.java new file mode 100644 index 0000000000..32f575fe46 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SCANamespaceHandlerResolver.java @@ -0,0 +1,53 @@ +/* + * 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.tuscany.sca.implementation.spring; + +import org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver; +import org.springframework.beans.factory.xml.NamespaceHandler; + +/** + * Overrides the default Spring namespace resolver to automatically register + * {@link ScaNamespaceHandler} instead of requiring a value to be supplied in a + * Spring configuration + * + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class SCANamespaceHandlerResolver extends DefaultNamespaceHandlerResolver { + private static final String SCA_NAMESPACE = "http://www.springframework.org/schema/sca"; + + private ScaNamespaceHandler handler; + + public SCANamespaceHandlerResolver(ClassLoader classLoader) { + super(classLoader); + handler = new ScaNamespaceHandler(/*componentType*/); + } + + public SCANamespaceHandlerResolver(String handlerMappingsLocation, ClassLoader classLoader) { + super(classLoader, handlerMappingsLocation); + handler = new ScaNamespaceHandler(/*componentType*/); + } + + @Override + public NamespaceHandler resolve(String namespaceUri) { + if (SCA_NAMESPACE.equals(namespaceUri)) { + return handler; + } + return super.resolve(namespaceUri); + } +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SCAParentApplicationContext.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SCAParentApplicationContext.java new file mode 100644 index 0000000000..d419d6db68 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SCAParentApplicationContext.java @@ -0,0 +1,271 @@ +/* + * 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.tuscany.sca.implementation.spring; + +import java.io.IOException; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.apache.tuscany.sca.assembly.ComponentProperty; +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.core.factory.ObjectFactory; +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.MessageSourceResolvable; +import org.springframework.context.NoSuchMessageException; +import org.springframework.core.io.Resource; + +/** + * A Spring ParentApplicationContext for a given Spring Implementation + * + * The Parent application context is responsible for handling those entities within a Spring + * application context that actually belong to SCA rather than to Spring. The principal things + * are Properties and References. These may be present either through explicit + * and elements in the application context or they may be implicit through + * unresolved Spring bean elements. In either case, it is the Parent application + * context that must provide Spring beans that correspond to the property or reference, as derived + * from the SCA composite in which the Spring application context is an implementation. + * + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +class SCAParentApplicationContext implements ApplicationContext { + + // The Spring implementation for which this is the parent application context + private SpringImplementation implementation; + private RuntimeComponent component; + private JavaPropertyValueObjectFactory propertyFactory; + + private static final String[] EMPTY_ARRAY = new String[0]; + + public SCAParentApplicationContext(RuntimeComponent component, + SpringImplementation implementation, + ProxyFactory proxyService, + JavaPropertyValueObjectFactory propertyValueObjectFactory) { + this.implementation = implementation; + this.component = component; + this.propertyFactory = propertyValueObjectFactory; + } // end constructor + + public Object getBean(String name) throws BeansException { + return getBean(name, (Class) null); + } + + /** + * Get a Bean for a reference or for a property. + * + * @param name - the name of the Bean required + * @param requiredType - the required type of the Bean (either a Java class or a Java interface) + * @return Object - a Bean which matches the requested bean + */ + public Object getBean(String name, Class requiredType) throws BeansException { + System.out.println("Spring parent context - getBean called for name: " + name); + // The expectation is that the requested Bean is either a reference or a property + // from the Spring context + for (Reference reference : implementation.getReferences()) { + if (reference.getName().equals(name)) { + // Extract the Java interface for the reference (it can't be any other interface type + // for a Spring application context) + if (requiredType == null) { + JavaInterface javaInterface = (JavaInterface)reference.getInterfaceContract().getInterface(); + requiredType = javaInterface.getJavaClass(); + } + // Create and return the proxy for the reference + return getService(requiredType, reference.getName()); + } // end if + } // end for + + // For a property, get the name and the required Java type and create a Bean + // of that type with the value inserted. + for (Property property : implementation.getProperties()) { + if (property.getName().equals(name)) { + if (requiredType == null) { + // The following code only deals with a subset of types and was superceded + // by the information from the implementation (which uses Classes as found + // in the Spring implementation itself. + //requiredType = JavaXMLMapper.getJavaType( property.getXSDType() ); + requiredType = implementation.getPropertyClass(name); + } + return getPropertyBean(requiredType, property.getName()); + } // end if + } // end for + throw new NoSuchBeanDefinitionException("Unable to find Bean with name " + name); + + } // end method getBean( String, Class ) + + public Object getBean(String name, Object[] args) throws BeansException { + return getBean(name, ((Class)null)); + } + + /** + * Creates a proxy Bean for a reference + * @param the Business interface type for the reference + * @param businessInterface - the business interface as a Class + * @param referenceName - the name of the Reference + * @return an Bean of the type defined by + */ + private B getService(Class businessInterface, String referenceName) { + return component.getComponentContext().getService(businessInterface, referenceName); + } + + /** + * Method to create a Java Bean for a Property value + * @param the class type of the Bean + * @param requiredType - a Class object for the required type + * @param name - the Property name + * @return - a Bean of the specified property, with value set + */ + private B getPropertyBean(Class requiredType, String name) { + B propertyObject = null; + // Get the component's list of properties + List props = component.getProperties(); + for (ComponentProperty prop : props) { + if (prop.getName().equals(name)) { + // On finding the property, create a factory for it and create a Bean using + // the factory + ObjectFactory factory = propertyFactory.createValueFactory(prop, prop.getValue(), requiredType); + propertyObject = (B)factory.getInstance(); + } // end if + } // end for + + return propertyObject; + } + + public boolean containsBean(String name) { + // TODO + System.out.println("Spring parent context - containsBean called for name: " + name); + return false; + } + + public boolean isSingleton(String name) throws NoSuchBeanDefinitionException { + // TODO + return false; + } + + public boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException { + throw new UnsupportedOperationException(); + } + + public Class getType(String name) throws NoSuchBeanDefinitionException { + return null; + } + + public String[] getAliases(String name) throws NoSuchBeanDefinitionException { + return EMPTY_ARRAY; + } + + public ApplicationContext getParent() { + return null; + } + + public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException { + return null; + } + + public String getId() { + return this.toString(); + } + + public String getDisplayName() { + return implementation.getURI(); + } + + public long getStartupDate() { + return 0; + } + + public boolean containsBeanDefinition(String beanName) { + return false; + } + + public int getBeanDefinitionCount() { + return 0; + } + + public String[] getBeanDefinitionNames() { + return new String[0]; + } + + public String[] getBeanNamesForType(Class type) { + return new String[0]; + } + + public String[] getBeanNamesForType(Class type, boolean includePrototypes, boolean includeFactoryBeans) { + return new String[0]; + } + + public Map getBeansOfType(Class type) throws BeansException { + return null; + } + + public Map getBeansOfType(Class type, boolean includePrototypes, boolean includeFactoryBeans) throws BeansException { + return null; + } + + public boolean isPrototype(String theString) { + return false; + } + + public BeanFactory getParentBeanFactory() { + return null; + } + + public boolean containsLocalBean(String name) { + return false; + } + + public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) { + return null; + } + + public String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException { + return null; + } + + public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException { + return null; + } + + public void publishEvent(ApplicationEvent event) { + + } + + public Resource[] getResources(String locationPattern) throws IOException { + return new Resource[0]; + } + + public Resource getResource(String location) { + return null; + } + + public ClassLoader getClassLoader() { + // REVIEW: this is almost certainly flawed, but it's not clear how the SCA runtime's + // resource loading mechanism is exposed right now. + return this.getClass().getClassLoader(); + } +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaNamespaceHandler.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaNamespaceHandler.java new file mode 100644 index 0000000000..45f00ce1af --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaNamespaceHandler.java @@ -0,0 +1,38 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.tuscany.sca.implementation.spring; + +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + +/** + * Handler for the <sca:> namespace in an application context + * + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class ScaNamespaceHandler extends NamespaceHandlerSupport { + + public ScaNamespaceHandler() { + init(); + } + + public final void init() { + registerBeanDefinitionParser("reference", new ScaReferenceBeanDefinitionParser()); + registerBeanDefinitionParser("service", new ScaServiceBeanDefinitionParser()); + registerBeanDefinitionParser("property", new ScaPropertyBeanDefinitionParser()); + } + +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaPropertyBeanDefinitionParser.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaPropertyBeanDefinitionParser.java new file mode 100644 index 0000000000..dc532ce20d --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaPropertyBeanDefinitionParser.java @@ -0,0 +1,35 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.tuscany.sca.implementation.spring; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.w3c.dom.Element; + +/** + * Parser for the <sca:reference> element + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class ScaPropertyBeanDefinitionParser implements BeanDefinitionParser { + + public BeanDefinition parse(Element element, ParserContext parserContext) { + // do nothing, this is handled by Tuscany + return null; + } + +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaReferenceBeanDefinitionParser.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaReferenceBeanDefinitionParser.java new file mode 100644 index 0000000000..1dd44cd752 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaReferenceBeanDefinitionParser.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.tuscany.sca.implementation.spring; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.w3c.dom.Element; + +/** + * Parser for the <sca:reference> element + * + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class ScaReferenceBeanDefinitionParser implements BeanDefinitionParser { + + public BeanDefinition parse(Element element, ParserContext parserContext) { + // do nothing, this is handled by Tuscany + return null; + } + +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaServiceBeanDefinitionParser.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaServiceBeanDefinitionParser.java new file mode 100644 index 0000000000..9dadcd2f49 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/ScaServiceBeanDefinitionParser.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.tuscany.sca.implementation.spring; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.w3c.dom.Element; + +/** + * Parser for the <sca:service/> element + * + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class ScaServiceBeanDefinitionParser implements BeanDefinitionParser { + + public BeanDefinition parse(Element element, ParserContext parserContext) { + // do nothing, handled by Tuscany + return null; + } + +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringBeanNotFoundException.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringBeanNotFoundException.java new file mode 100644 index 0000000000..35df76fabc --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringBeanNotFoundException.java @@ -0,0 +1,39 @@ +/* + * 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.tuscany.sca.implementation.spring; + +/** + * @version $Rev$ $Date$ + */ +public class SpringBeanNotFoundException extends Exception { + + private static final long serialVersionUID = -1157790036638157553L; + + public SpringBeanNotFoundException(String msg) { + super(msg); + } + + public SpringBeanNotFoundException(Throwable e) { + super(e); + } + + public SpringBeanNotFoundException(String msg, Throwable e) { + super(msg,e); + } +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementation.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementation.java new file mode 100644 index 0000000000..e4f62d3bb2 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementation.java @@ -0,0 +1,192 @@ +/* + * 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.tuscany.sca.implementation.spring; + +import java.lang.reflect.Method; +import java.util.Hashtable; +import java.util.List; + +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.assembly.Extensible; +import org.apache.tuscany.sca.assembly.Implementation; +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.assembly.Service; +import org.apache.tuscany.sca.assembly.impl.ImplementationImpl; +import org.apache.tuscany.sca.implementation.java.impl.JavaConstructorImpl; +import org.apache.tuscany.sca.implementation.spring.xml.SpringBeanElement; +import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; +import org.springframework.core.io.Resource; + +/** + * Represents a Spring implementation. + * + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class SpringImplementation extends ImplementationImpl implements Implementation, Extensible { + + // The location attribute which points to the Spring application-context XML file + private String location; + // The application-context file as a Spring Resource + private Resource resource; + private ComponentType componentType; + // Mapping of Services to Beans + private Hashtable serviceMap; + // Mapping of property names to Java class + private Hashtable propertyMap; + private List policyHandlerClassNames = null; + + // Method marked with @Init annotation + private Method initMethod = null; + // Method marked with @Destroy annotation + private Method destroyMethod = null; + // Method marked with @Constructor annotation + private JavaConstructorImpl constructorDefinition = null; + + protected SpringImplementation() { + this.location = null; + this.resource = null; + setUnresolved(true); + serviceMap = new Hashtable(); + propertyMap = new Hashtable(); + } // end method SpringImplementation + + /* Returns the location attribute for this Spring implementation */ + public String getLocation() { + return location; + } + + /** + * Sets the location attribute for this Spring implementation + * location - a URI to the Spring application-context file + */ + public void setLocation(String location) { + this.location = location; + return; + } + + public void setResource(Resource resource) { + this.resource = resource; + } + + public Resource getResource() { + return resource; + } + + public JavaConstructorImpl getConstructor() { + return constructorDefinition; + } + + public void setConstructor(JavaConstructorImpl definition) { + this.constructorDefinition = definition; + } + + public Method getInitMethod() { + return initMethod; + } + + public void setInitMethod(Method initMethod) { + this.initMethod = initMethod; + } + + public Method getDestroyMethod() { + return destroyMethod; + } + + public void setDestroyMethod(Method destroyMethod) { + this.destroyMethod = destroyMethod; + } + + /* + * Returns the componentType for this Spring implementation + */ + public ComponentType getComponentType() { + return componentType; + } + + /* + * Sets the componentType for this Spring implementation + */ + public void setComponentType(ComponentType componentType) { + this.componentType = componentType; + } + + @Override + public List getServices() { + return componentType.getServices(); + } + + @Override + public List getReferences() { + return componentType.getReferences(); + } + + @Override + public List getProperties() { + return componentType.getProperties(); + } + + /** + * Returns the Spring Bean which implements a particular service + * @param service the service + * @return the bean which implements the service, as a SpringBeanElement + */ + public SpringBeanElement getBeanFromService(Service service) { + SpringBeanElement theBean = serviceMap.get(service.getName()); + return theBean; + } + + /** + * Sets the mapping from a service to the Spring Bean that implements the service + * @param service the service + * @param theBean a SpringBeanElement for the Bean implementing the service + */ + public void setBeanForService(Service service, SpringBeanElement theBean) { + serviceMap.put(service.getName(), theBean); + } + + /** + * Add a mapping from a SCA property name to a Java class for the property + * @param propertyName + * @param propertyClass + */ + public void setPropertyClass(String propertyName, Class propertyClass) { + if (propertyName == null || propertyClass == null) + return; + propertyMap.put(propertyName, propertyClass); + return; + } // end method setPropertyClass + + /** + * Gets the Java Class for an SCA property + * @param propertyName - the property name + * @return - a Class object for the type of the property + */ + public Class getPropertyClass(String propertyName) { + return propertyMap.get(propertyName); + } // end method getPropertyClass + + public List getPolicyHandlerClassNames() { + return policyHandlerClassNames; + } + + public void setPolicyHandlerClassNames(List policyHandlerClassNames) { + this.policyHandlerClassNames = policyHandlerClassNames; + } // end method setPolicyHandlerClassNames +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationProcessor.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationProcessor.java new file mode 100644 index 0000000000..546006e504 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationProcessor.java @@ -0,0 +1,230 @@ +/* + * 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.tuscany.sca.implementation.spring; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.assembly.xml.Constants; +import org.apache.tuscany.sca.assembly.xml.PolicyAttachPointProcessor; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +import org.apache.tuscany.sca.contribution.service.ContributionWriteException; +import org.apache.tuscany.sca.implementation.spring.xml.SpringXMLComponentTypeLoader; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.policy.PolicyFactory; + +/** + * SpringArtifactProcessor is responsible for processing the XML of an + * element in an SCA SCDL file. + * + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class SpringImplementationProcessor implements StAXArtifactProcessor { + + private static final String LOCATION = "location"; + private static final String IMPLEMENTATION_SPRING = "implementation.spring"; + private static final QName IMPLEMENTATION_SPRING_QNAME = new QName(Constants.SCA10_NS, IMPLEMENTATION_SPRING); + private static final String MSG_LOCATION_MISSING = "Reading implementation.spring - location attribute missing"; + + private AssemblyFactory assemblyFactory; + private JavaInterfaceFactory javaFactory; + private PolicyFactory policyFactory; + private PolicyAttachPointProcessor policyProcessor; + private Monitor monitor; + + public SpringImplementationProcessor(ModelFactoryExtensionPoint modelFactories, Monitor monitor) { + this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); + this.javaFactory = modelFactories.getFactory(JavaInterfaceFactory.class); + this.policyFactory = modelFactories.getFactory(PolicyFactory.class); + this.policyProcessor = new PolicyAttachPointProcessor(policyFactory); + this.monitor = monitor; + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "impl-spring-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "impl-spring-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + /* + * Read the XML and parse out the attributes. + * + * has a single required attribute: + * "location" - which is the target URI of of an archive file or a directory that contains the Spring + * application context files. + * If the resource identified by the location attribute is an archive file, then the file + * META-INF/MANIFEST.MF is read from the archive. + * If the location URI identifies a directory, then META-INF/MANIFEST.MF must exist + * underneath that directory. + * If the manifest file contains a header "Spring-Context" of the format: + * Spring-Context ::= path ( ';' path )* + * + * Where path is a relative path with respect to the location URI, then the set of paths + * specified in the header identify the context configuration files. + * If there is no MANIFEST.MF file or no Spring-Context header within that file, + * then the default behaviour is to build an application context using all the *.xml files + * in the METAINF/spring directory. + */ + public SpringImplementation read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException { + + // Create the Spring implementation + SpringImplementation springImplementation = null; + + // Read the location attribute for the spring implementation + String springLocation = reader.getAttributeValue(null, LOCATION); + if (springLocation != null) { + springImplementation = new SpringImplementation(); + springImplementation.setLocation(springLocation); + springImplementation.setUnresolved(true); + processComponentType(springImplementation); + } else { + error("LocationAttributeMissing", reader); + //throw new ContributionReadException(MSG_LOCATION_MISSING); + } + + // Read policies + policyProcessor.readPolicies(springImplementation, reader); + + // Skip to end element + while (reader.hasNext()) { + if (reader.next() == END_ELEMENT && IMPLEMENTATION_SPRING_QNAME.equals(reader.getName())) { + break; + } + } // end while + + return springImplementation; + } // end read + + /* + * Handles the component type for the Spring implementation + * @param springImplementation - a Spring implementation. The component type information + * is created for this implementation + * + */ + private void processComponentType(SpringImplementation springImplementation) { + + // Create a ComponentType and mark it unresolved + ComponentType componentType = assemblyFactory.createComponentType(); + componentType.setUnresolved(true); + springImplementation.setComponentType(componentType); + } // end processComponentType + + /* + * Write out the XML representation of the Spring implementation + * + */ + public void write(SpringImplementation springImplementation, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException { + + // Write + policyProcessor.writePolicyPrefixes(springImplementation, writer); + writer.writeStartElement(Constants.SCA10_NS, IMPLEMENTATION_SPRING); + policyProcessor.writePolicyAttributes(springImplementation, writer); + + if (springImplementation.getLocation() != null) { + writer.writeAttribute(LOCATION, springImplementation.getLocation()); + } + + writer.writeEndElement(); + + } // end write + + /** + * Resolves the Spring implementation - loads the Spring application-context XML and + * derives the spring implementation componentType from it + */ + public void resolve(SpringImplementation springImplementation, ModelResolver resolver) + throws ContributionResolveException { + + if (springImplementation == null) + return; + + /* Load the Spring component type by reading the Spring application context */ + SpringXMLComponentTypeLoader springLoader = + new SpringXMLComponentTypeLoader(assemblyFactory, javaFactory, policyFactory); + try { + // Load the Spring Implementation information from its application context file... + springLoader.load(springImplementation); + } catch (ContributionReadException e) { + ContributionResolveException ce = new ContributionResolveException(e); + error("ContributionResolveException", resolver, ce); + throw ce; + } + + ComponentType ct = springImplementation.getComponentType(); + if (ct.isUnresolved()) { + // If the introspection fails to resolve, try to find a side file... + ComponentType componentType = resolver.resolveModel(ComponentType.class, ct); + if (componentType.isUnresolved()) { + error("UnableToResolveComponentType", resolver); + //throw new ContributionResolveException("SpringArtifactProcessor: unable to resolve componentType for Spring component"); + } else { + springImplementation.setComponentType(componentType); + springImplementation.setUnresolved(false); + } + + } // end if + + } // end method resolve + + public QName getArtifactType() { + return IMPLEMENTATION_SPRING_QNAME; + } + + public Class getModelType() { + return SpringImplementation.class; + } + +} // end class SpringArtifactProcessor diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationProvider.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationProvider.java new file mode 100644 index 0000000000..4717df2056 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationProvider.java @@ -0,0 +1,119 @@ +/* + * 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.tuscany.sca.implementation.spring; + +import java.util.List; + +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; +import org.apache.tuscany.sca.provider.ImplementationProvider; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; +import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.GenericApplicationContext; +import org.apache.tuscany.sca.implementation.spring.processor.InitDestroyAnnotationProcessor; +import org.apache.tuscany.sca.implementation.spring.processor.ReferenceAnnotationProcessor; +import org.apache.tuscany.sca.implementation.spring.processor.PropertyAnnotationProcessor; +import org.apache.tuscany.sca.implementation.spring.processor.ConstructorAnnotationProcessor; +import org.apache.tuscany.sca.implementation.spring.processor.ComponentNameAnnotationProcessor; +import org.springframework.beans.factory.config.BeanPostProcessor; + +// TODO - create a working version of this class... +/** + * A provider class for runtime Spring implementation instances + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class SpringImplementationProvider implements ImplementationProvider { + private RuntimeComponent component; + + // A Spring application context object + private AbstractApplicationContext springContext; + + private SpringImplementation implementation; + + /** + * Constructor for the provider - takes a component definition and a Spring implementation + * description + * @param component - the component in the assembly + * @param implementation - the implementation + */ + public SpringImplementationProvider(RuntimeComponent component, + SpringImplementation implementation, + ProxyFactory proxyService, + JavaPropertyValueObjectFactory propertyValueObjectFactory, + List policyHandlerClassNames) { + super(); + this.implementation = implementation; + this.component = component; + this.implementation.setPolicyHandlerClassNames(policyHandlerClassNames); + + SCAParentApplicationContext scaParentContext = + new SCAParentApplicationContext(component, implementation, proxyService, propertyValueObjectFactory); + //springContext = new SCAApplicationContext(scaParentContext, implementation.getResource()); + + XmlBeanFactory beanFactory = new XmlBeanFactory(implementation.getResource()); + BeanPostProcessor initDestroyProcessor = new InitDestroyAnnotationProcessor(); + beanFactory.addBeanPostProcessor(initDestroyProcessor); + BeanPostProcessor referenceProcessor = new ReferenceAnnotationProcessor(component); + beanFactory.addBeanPostProcessor(referenceProcessor); + BeanPostProcessor propertyProcessor = new PropertyAnnotationProcessor(propertyValueObjectFactory, component); + beanFactory.addBeanPostProcessor(propertyProcessor); + BeanPostProcessor componentNameProcessor = new ComponentNameAnnotationProcessor(component); + beanFactory.addBeanPostProcessor(componentNameProcessor); + BeanPostProcessor constructorProcessor = new ConstructorAnnotationProcessor(); + beanFactory.addBeanPostProcessor(constructorProcessor); + springContext = new GenericApplicationContext(beanFactory, scaParentContext); + + } // end constructor + + public Invoker createInvoker(RuntimeComponentService service, Operation operation) { + return new SpringInvoker(component, springContext, service, operation); + } + + public boolean supportsOneWayInvocation() { + return false; + } + + /** + * Start this Spring implementation instance + */ + public void start() { + // Do refresh here to ensure that Spring Beans are not touched before the SCA config process + // is complete... + springContext.refresh(); + springContext.start(); + // System.out.println("SpringImplementationProvider: Spring context started"); + } // end method start() + + /** + * Stop this implementation instance + */ + public void stop() { + // TODO - complete + springContext.close(); + springContext.stop(); + //System.out.println("SpringImplementationProvider: Spring context stopped"); + } // end method stop + +} // end class SpringImplementationProvider diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationProviderFactory.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationProviderFactory.java new file mode 100644 index 0000000000..1789b5a4e0 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringImplementationProviderFactory.java @@ -0,0 +1,89 @@ +/* + * 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.tuscany.sca.implementation.spring; + +import java.util.List; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.invocation.ExtensibleProxyFactory; +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.core.invocation.ProxyFactoryExtensionPoint; +import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.databinding.TransformerExtensionPoint; +import org.apache.tuscany.sca.databinding.impl.MediatorImpl; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.policy.util.PolicyHandlerDefinitionsLoader; +import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; +import org.apache.tuscany.sca.provider.ImplementationProvider; +import org.apache.tuscany.sca.provider.ImplementationProviderFactory; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * ImplementationProviderFactory for Spring implementation type + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + * + */ +public class SpringImplementationProviderFactory implements ImplementationProviderFactory { + + private ProxyFactory proxyFactory; + private JavaPropertyValueObjectFactory propertyFactory; + private List policyHandlerClassNames = null; + + /** + * Simple constructor + * + */ + public SpringImplementationProviderFactory(ExtensionPointRegistry extensionPoints) { + super(); + + ProxyFactoryExtensionPoint proxyFactories = extensionPoints.getExtensionPoint(ProxyFactoryExtensionPoint.class); + proxyFactory = new ExtensibleProxyFactory(proxyFactories); + + // TODO: could the runtime have a default PropertyValueObjectFactory? + DataBindingExtensionPoint dataBindings = extensionPoints.getExtensionPoint(DataBindingExtensionPoint.class); + TransformerExtensionPoint transformers = extensionPoints.getExtensionPoint(TransformerExtensionPoint.class); + MediatorImpl mediator = new MediatorImpl(dataBindings, transformers); + propertyFactory = new JavaPropertyValueObjectFactory(mediator); + + policyHandlerClassNames = PolicyHandlerDefinitionsLoader.loadPolicyHandlerClassnames(); + } + + /** + * Returns a SpringImplementationProvider for a given component and Spring implementation + * @param component the component for which implementation instances are required + * @param implementation the Spring implementation with details of the component + * implementation + * @return the SpringImplementationProvider for the specified component + */ + public ImplementationProvider createImplementationProvider(RuntimeComponent component, + SpringImplementation implementation) { + return new SpringImplementationProvider(component, + implementation, + proxyFactory, + propertyFactory, + policyHandlerClassNames); + } + + /** + * Returns the class of the Spring implementation + */ + public Class getModelType() { + return SpringImplementation.class; + } +} // end class SpringImplementationProviderFactory diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringInvocationException.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringInvocationException.java new file mode 100644 index 0000000000..410525a054 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringInvocationException.java @@ -0,0 +1,40 @@ +/* + * 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.tuscany.sca.implementation.spring; + +/** + * @version $Rev$ $Date$ + */ +public class SpringInvocationException extends Exception { + + private static final long serialVersionUID = -1157790036638157513L; + + public SpringInvocationException(String msg) { + super(msg); + } + + public SpringInvocationException(Throwable e) { + super(e); + } + + public SpringInvocationException(String msg,Throwable e) { + super(msg,e); + } + +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringInvoker.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringInvoker.java new file mode 100644 index 0000000000..5eeb802727 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringInvoker.java @@ -0,0 +1,127 @@ +/* + * 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.tuscany.sca.implementation.spring; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tuscany.sca.implementation.spring.xml.SpringBeanElement; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; +import org.springframework.beans.BeansException; +import org.springframework.context.support.AbstractApplicationContext; + +/** + * Initial implementation of a Spring bean invoker + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class SpringInvoker implements Invoker { + + private Method theMethod = null; + private Object bean; + private SpringBeanElement beanElement; + private boolean badInvoker = false; + + private AbstractApplicationContext springContext; + private Operation operation; + + /** + * SpringInvoker constructor + * @param component - the Spring component to invoke + * @param service - the service to invoke + * @param operation - the operation to invoke + */ + public SpringInvoker(RuntimeComponent component, + AbstractApplicationContext springContext, + RuntimeComponentService service, + Operation operation) { + + this.springContext = springContext; + this.operation = operation; + + // From the component and the service, identify the Spring Bean which is the target + SpringImplementation theImplementation = (SpringImplementation)component.getImplementation(); + beanElement = theImplementation.getBeanFromService(service.getService()); + + if (beanElement == null) { + badInvoker = true; + return; + } + + } // end constructor SpringInvoker + + // Lazy-load the method to avoid timing problems with the Spring Context + private void setupMethod() throws SpringInvocationException{ + try { + bean = springContext.getBean(beanElement.getId()); + Class beanClass = bean.getClass(); + theMethod = JavaInterfaceUtil.findMethod(beanClass, operation); + //System.out.println("SpringInvoker - found method " + theMethod.getName() ); + } catch (BeansException e) { + throw new SpringInvocationException(e); + } catch (NoSuchMethodException e) { + throw new SpringInvocationException(e); + } + } + + private Object doInvoke(Object payload) throws SpringInvocationException { + if (theMethod == null) + setupMethod(); + + if (badInvoker) + throw new SpringInvocationException("Spring invoker incorrectly configured"); + // Invoke the method on the Spring bean using the payload, returning the results + try { + Object ret; + + if (payload != null && !payload.getClass().isArray()) { + ret = theMethod.invoke(bean, payload); + } else { + ret = theMethod.invoke(bean, (Object[])payload); + } + return ret; + } catch (InvocationTargetException e) { + throw new SpringInvocationException("Spring invoker invoke method '"+ theMethod.getName()+"' error.",e); + } catch (Exception e) { + throw new SpringInvocationException("Spring invoker invoke method '"+ theMethod.getName()+"' error.",e); + } + + } // end method doInvoke + + /** + * @param msg the message to invoke on the target bean + */ + public Message invoke(Message msg) { + try { + Object resp = doInvoke(msg.getBody()); + msg.setBody(resp); + } catch (SpringInvocationException e) { + msg.setFaultBody(e.getCause()); + }catch (Throwable e) { + msg.setFaultBody(e); + } + //System.out.println("Spring Invoker - invoke called"); + return msg; + } // end method invoke + +} // end class SpringInvoker diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringOperationNotFoundException.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringOperationNotFoundException.java new file mode 100644 index 0000000000..b34b1ee0b1 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringOperationNotFoundException.java @@ -0,0 +1,40 @@ +/* + * 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.tuscany.sca.implementation.spring; + +/** + * @version $Rev$ $Date$ + */ +public class SpringOperationNotFoundException extends Exception { + + private static final long serialVersionUID = -1157790036638157554L; + + public SpringOperationNotFoundException(String msg) { + super(msg); + } + + public SpringOperationNotFoundException(Throwable e) { + super(e); + } + + public SpringOperationNotFoundException(String msg,Throwable e) { + super(msg,e); + } + +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringPropertyValueObjectFactory.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringPropertyValueObjectFactory.java new file mode 100644 index 0000000000..3f98180498 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/SpringPropertyValueObjectFactory.java @@ -0,0 +1,45 @@ +/* + * 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.tuscany.sca.implementation.spring; + +import org.apache.tuscany.sca.databinding.Mediator; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; + +/** + * + * Factory class for PropertyValueObjects for Spring implementations + * + * 6th May 2007: Chosen a very simple design for this class - since Spring implementations are a form + * of Java POJO, the simple design chosen for this class is to re-use the PropertyValueObjectFactory + * implementation from the base implementation-java-runtime package of Tuscany SCA Java, since the + * same properties are going to be rendered in the same way to simple Tuscany POJOs and to Spring + * Bean POJOs. Mike Edwards + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class SpringPropertyValueObjectFactory extends JavaPropertyValueObjectFactory { + + /** + * Constructor simply defers to the superclass, along with the complete implementation... + */ + public SpringPropertyValueObjectFactory(Mediator mediator) { + super(mediator); + } // end constructor JavaPropertyValueObjectFactory(Mediator mediator) + +} // end class SpringPropertyValueObjectFactory diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentNameAnnotationProcessor.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentNameAnnotationProcessor.java new file mode 100644 index 0000000000..cd0567f461 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentNameAnnotationProcessor.java @@ -0,0 +1,151 @@ +/* + * 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.tuscany.sca.implementation.spring.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.beans.PropertyDescriptor; +import java.lang.annotation.Annotation; + +import org.springframework.util.Assert; +import org.springframework.beans.BeanUtils; +import org.springframework.util.ReflectionUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.factory.config.BeanPostProcessor; + +import org.osoa.sca.annotations.ComponentName; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +public class ComponentNameAnnotationProcessor implements BeanPostProcessor { + + private Class componentNameAnnotationType = ComponentName.class; + + private RuntimeComponent component; + + public ComponentNameAnnotationProcessor (RuntimeComponent component) { + this.component = component; + } + + /** + * Gets componentName annotation type. + */ + protected Class getComponentNameAnnotationType() { + return this.componentNameAnnotationType; + } + + /** + * Sets componentName annotation type. + */ + public void setComponentNameAnnotationType(Class componentNameAnnotationType) { + Assert.notNull(componentNameAnnotationType, "'componentNameAnnotationType' type must not be null."); + this.componentNameAnnotationType = componentNameAnnotationType; + } + + /** + * This method is used to execute before a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + processAnnotation(bean); + return bean; + } + + /** + * This method is used to execute after a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + /** + *

Processes a beans fields for injection if it has a {@link Reference} annotation.

+ */ + protected void processAnnotation(final Object bean) { + + final Class clazz = bean.getClass(); + + ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() { + public void doWith(Field field) { + Annotation annotation = field.getAnnotation(getComponentNameAnnotationType()); + + if (annotation != null) { + if (Modifier.isStatic(field.getModifiers())) { + throw new IllegalStateException("ComponentName annotation is not supported on static fields"); + } + + if (Modifier.isPrivate(field.getModifiers())) { + throw new IllegalStateException("ComponentName annotation is not supported on private fields"); + } + + ReflectionUtils.makeAccessible(field); + + if (field.getType().getName().equals("java.lang.String")) { + Object nameObj = component.getName(); + if (nameObj != null) + ReflectionUtils.setField(field, bean, nameObj); + } else { + throw new IllegalStateException("ComponentName annotation is supported only on java.lang.String field type."); + } + } + } + }); + + ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() { + public void doWith(Method method) { + Annotation annotation = method.getAnnotation(getComponentNameAnnotationType()); + + if (annotation != null) { + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("ComponentName annotation is not supported on static methods"); + } + + if (Modifier.isPrivate(method.getModifiers())) { + throw new IllegalStateException("ComponentName annotation is not supported on private methods"); + } + + if (method.getParameterTypes().length == 0) { + throw new IllegalStateException("ComponentName annotation requires at least one argument: " + method); + } + + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); + + if (pd.getPropertyType().getName().equals("java.lang.String")) { + Object nameObj = component.getName(); + if (nameObj != null) { + try { + pd.getWriteMethod().invoke(bean, new Object[] { nameObj }); + } catch (Throwable e) { + throw new FatalBeanException("Problem injecting reference: " + e.getMessage(), e); + } + } + } else { + throw new IllegalStateException("ComponentName annotation is supported only on java.lang.String field type."); + } + } + } + }); + } +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ConstructorAnnotationProcessor.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ConstructorAnnotationProcessor.java new file mode 100644 index 0000000000..4dadf37189 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ConstructorAnnotationProcessor.java @@ -0,0 +1,119 @@ +/* + * 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.tuscany.sca.implementation.spring.processor; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Constructor; +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.List; + +import org.springframework.util.Assert; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; +import org.springframework.beans.factory.annotation.Autowired; + +public class ConstructorAnnotationProcessor extends InstantiationAwareBeanPostProcessorAdapter { + + private Class constructorAnnotationType + = org.osoa.sca.annotations.Constructor.class; + + private Class autowiredAnnotationType = Autowired.class; + + public ConstructorAnnotationProcessor () { + // Default constructor. + } + + /** + * Set the 'autowired' annotation type, to be used on constructors, fields, + * setter methods and arbitrary config methods. + */ + public void setAutowiredAnnotationType(Class autowiredAnnotationType) { + Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null"); + this.autowiredAnnotationType = autowiredAnnotationType; + } + + /** + * Return the 'autowired' annotation type. + */ + protected Class getAutowiredAnnotationType() { + return this.autowiredAnnotationType; + } + + /** + * Return the 'constructor' annotation type. + */ + protected Class getConstructorAnnotationType() { + return this.constructorAnnotationType; + } + + /** + * Sets the 'constructor' annotation type. + */ + public void setConstructorAnnotationType(Class constructorAnnotationType) { + Assert.notNull(constructorAnnotationType, "'constructorAnnotationType' type must not be null."); + this.constructorAnnotationType = constructorAnnotationType; + } + + /** + * This method is used to execute before a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + /** + * This method is used to execute after a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + public Constructor[] determineCandidateConstructors(Class beanClass, String beanName) throws BeansException { + /*Constructor[] declaredConstructors = beanClass.getDeclaredConstructors(); + Method[] declaredMethods = beanClass.getDeclaredMethods(); + List candidates = new ArrayList(declaredConstructors.length); + + for (int i = 0; i < declaredMethods.length; i++) { + Method method = declaredMethods[i]; + Annotation annotation = method.getAnnotation(getConstructorAnnotationType()); + if (annotation != null) { + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("Constructor annotation is not supported on static methods"); + } + + if (candidates.size() == 1) { + throw new IllegalStateException("Only one method is allowed to have constructor annotation in a bean: " + method); + } + + candidates.add(method); + } + } + + return (Constructor[]) candidates.toArray(new Constructor[candidates.size()]);*/ + return null; + } +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/InitDestroyAnnotationProcessor.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/InitDestroyAnnotationProcessor.java new file mode 100644 index 0000000000..44737bf9d1 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/InitDestroyAnnotationProcessor.java @@ -0,0 +1,72 @@ +/* + * 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.tuscany.sca.implementation.spring.processor; + +import java.lang.annotation.Annotation; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Destroy; +import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor; +import org.springframework.util.Assert; + +public class InitDestroyAnnotationProcessor extends InitDestroyAnnotationBeanPostProcessor { + + private static final long serialVersionUID = 0; + + private Class initAnnotationType = Init.class; + + private Class destroyAnnotationType = Destroy.class; + + /** + * Gets init annotation type. + */ + protected Class getInitAnnotationType() { + return this.initAnnotationType; + } + + /** + * Sets init annotation type. + */ + /*public void setInitAnnotationType(Class initAnnotationType) { + Assert.notNull(initAnnotationType, "Init annotation type must not be null."); + this.initAnnotationType = initAnnotationType; + }*/ + + /** + * Gets destroy annotation type. + */ + protected Class getDestroyAnnotationType() { + return this.destroyAnnotationType; + } + + /** + * Sets destroy annotation type. + */ + /*public void setDestroyAnnotationType(Class destroyAnnotationType) { + Assert.notNull(destroyAnnotationType, "Destroy annotation type must not be null."); + this.destroyAnnotationType = destroyAnnotationType; + }*/ + + public InitDestroyAnnotationProcessor () { + // Set the @Init annotation type + setInitAnnotationType(initAnnotationType); + + // Set the @Destroy annotation type + setDestroyAnnotationType(destroyAnnotationType); + } +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyAnnotationProcessor.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyAnnotationProcessor.java new file mode 100644 index 0000000000..d8755c58f4 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyAnnotationProcessor.java @@ -0,0 +1,220 @@ +/* + * 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.tuscany.sca.implementation.spring.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.beans.PropertyDescriptor; +import java.lang.annotation.Annotation; +import java.util.List; + +import org.springframework.util.Assert; +import org.springframework.beans.BeanUtils; +import org.springframework.util.ReflectionUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.factory.config.BeanPostProcessor; + +import org.osoa.sca.annotations.Property; +import org.apache.tuscany.sca.assembly.ComponentProperty; +import org.apache.tuscany.sca.core.factory.ObjectFactory; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +public class PropertyAnnotationProcessor implements BeanPostProcessor { + + private Class propertyAnnotationType = Property.class; + + private RuntimeComponent component; + + private JavaPropertyValueObjectFactory propertyFactory; + + public PropertyAnnotationProcessor (JavaPropertyValueObjectFactory propertyFactory, + RuntimeComponent component) { + this.propertyFactory = propertyFactory; + this.component = component; + } + + /** + * Gets property annotation type. + */ + protected Class getPropertyAnnotationType() { + return this.propertyAnnotationType; + } + + /** + * Sets property annotation type. + */ + public void setPropertyAnnotationType(Class propertyAnnotationType) { + Assert.notNull(propertyAnnotationType, "'propertyAnnotationType' type must not be null."); + this.propertyAnnotationType = propertyAnnotationType; + } + + /** + * This method is used to execute before a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + processAnnotation(bean); + return bean; + } + + /** + * This method is used to execute after a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + /** + *

Processes a beans fields for injection if it has a {@link Property} annotation.

+ */ + protected void processAnnotation(final Object bean) { + + final Class clazz = bean.getClass(); + + ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() { + public void doWith(Method method) { + //Annotation annotation = method.getAnnotation(getPropertyAnnotationType()); + Property annotation = (Property) method.getAnnotation(getPropertyAnnotationType()); + + if (annotation != null) { + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("Property annotation is not supported on static methods"); + } + + if (Modifier.isPrivate(method.getModifiers())) { + throw new IllegalStateException("Property annotation is not supported on private methods"); + } + + if (method.getParameterTypes().length == 0) { + throw new IllegalStateException("Property annotation requires at least one argument: " + method); + } + + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); + if (pd != null) { + String propName = annotation.name(); + if ("".equals(propName)) { + injectProperty(bean, pd, getPropertyObj(pd.getPropertyType(), pd.getName())); + } else { + injectProperty(bean, pd, getPropertyObj(pd.getPropertyType(), propName)); + } + } + } + } + }); + + ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() { + public void doWith(Field field) { + //Annotation annotation = field.getAnnotation(getPropertyAnnotationType()); + Property annotation = (Property) field.getAnnotation(getPropertyAnnotationType()); + + if (annotation != null) { + if (Modifier.isStatic(field.getModifiers())) { + throw new IllegalStateException("Property annotation is not supported on static fields"); + } + + if (Modifier.isPrivate(field.getModifiers())) { + throw new IllegalStateException("Property annotation is not supported on private fields"); + } + + ReflectionUtils.makeAccessible(field); + + Object propertyObj = null; + String propName = annotation.name(); + if ("".equals(propName)) { + propertyObj = getPropertyObj(field.getType(), field.getName()); + } else { + propertyObj = getPropertyObj(field.getType(), propName); + } + + if (propertyObj != null) + ReflectionUtils.setField(field, bean, propertyObj); + } + } + }); + } + + /** + * Processes a property descriptor to inject a service. + */ + public Object getPropertyObj(Class requiredType, String name) { + + Object propertyObj = null; + + List props = component.getProperties(); + for (ComponentProperty prop : props) { + if (prop.getName().equals(name)) { + // On finding the property, create a factory for it and create a Bean using + // the factory + ObjectFactory factory = propertyFactory.createValueFactory(prop, prop.getValue(), requiredType); + propertyObj = factory.getInstance(); + } // end if + } // end for + + return propertyObj; + } + + + public void injectProperty(Object bean, PropertyDescriptor pd, Object propertyObj) { + + if (propertyObj != null) { + try { + pd.getWriteMethod().invoke(bean, new Object[] { propertyObj }); + } catch (Throwable e) { + throw new FatalBeanException("Problem injecting property: " + e.getMessage(), e); + } + } + } + + /** + * Processes a property descriptor to inject a service. + */ + /*public void injectMethod(Object bean, Method method) { + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); + + if (pd != null) { + Object propertyObj = null; + + List props = component.getProperties(); + for (ComponentProperty prop : props) { + if (prop.getName().equals(pd.getName())) { + // On finding the property, create a factory for it and create a Bean using + // the factory + ObjectFactory factory = propertyFactory.createValueFactory(prop, prop.getValue(), pd.getPropertyType()); + propertyObj = factory.getInstance(); + } // end if + } // end for + + if (propertyObj != null) { + try { + pd.getWriteMethod().invoke(bean, new Object[] { propertyObj }); + } catch (Throwable e) { + throw new FatalBeanException("Problem injecting property: " + e.getMessage(), e); + } + } + } + }*/ +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ReferenceAnnotationProcessor.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ReferenceAnnotationProcessor.java new file mode 100644 index 0000000000..52f8ac3684 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ReferenceAnnotationProcessor.java @@ -0,0 +1,186 @@ +/* + * 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.tuscany.sca.implementation.spring.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.beans.PropertyDescriptor; +import java.lang.annotation.Annotation; + +import org.springframework.util.Assert; +import org.springframework.beans.BeanUtils; +import org.springframework.util.ReflectionUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.factory.config.BeanPostProcessor; + +import org.osoa.sca.annotations.Reference; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +public class ReferenceAnnotationProcessor implements BeanPostProcessor { + + private Class referenceAnnotationType = Reference.class; + + private RuntimeComponent component; + + public ReferenceAnnotationProcessor (RuntimeComponent component) { + this.component = component; + } + + /** + * Gets referece annotation type. + */ + protected Class getReferenceAnnotationType() { + return this.referenceAnnotationType; + } + + /** + * Sets referece annotation type. + */ + public void setReferenceAnnotationType(Class referenceAnnotationType) { + Assert.notNull(referenceAnnotationType, "'referenceAnnotationType' type must not be null."); + this.referenceAnnotationType = referenceAnnotationType; + } + + /** + * This method is used to execute before a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + processAnnotation(bean); + return bean; + } + + /** + * This method is used to execute after a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + /** + *

Processes a beans fields for injection if it has a {@link Reference} annotation.

+ */ + protected void processAnnotation(final Object bean) { + + final Class clazz = bean.getClass(); + + ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() { + public void doWith(Method method) { + //Annotation annotation = method.getAnnotation(getReferenceAnnotationType()); + Reference annotation = (Reference) method.getAnnotation(getReferenceAnnotationType()); + + if (annotation != null) { + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("Reference annotation is not supported on static methods"); + } + + if (Modifier.isPrivate(method.getModifiers())) { + throw new IllegalStateException("Reference annotation is not supported on private methods"); + } + + if (method.getParameterTypes().length == 0) { + throw new IllegalStateException("Reference annotation requires at least one argument: " + method); + } + + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); + if (pd != null) { + String refName = annotation.name(); + if ("".equals(refName)) { + injectReference(bean, pd, pd.getName()); + } else { + injectReference(bean, pd, refName); + } + } + } + } + }); + + ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() { + public void doWith(Field field) { + //Annotation annotation = field.getAnnotation(getReferenceAnnotationType()); + Reference annotation = (Reference) field.getAnnotation(getReferenceAnnotationType()); + + if (annotation != null) { + if (Modifier.isStatic(field.getModifiers())) { + throw new IllegalStateException("Reference annotation is not supported on static fields"); + } + + if (Modifier.isPrivate(field.getModifiers())) { + throw new IllegalStateException("Reference annotation is not supported on private fields"); + } + + ReflectionUtils.makeAccessible(field); + + Object referenceObj = null; + String refName = annotation.name(); + if ("".equals(refName)) { + referenceObj = component.getComponentContext().getService(field.getType(), field.getName()); + } else { + referenceObj = component.getComponentContext().getService(field.getType(), refName); + } + + if (referenceObj != null) + ReflectionUtils.setField(field, bean, referenceObj); + } + } + }); + } + + /** + * Processes a property descriptor to inject a service. + */ + public void injectReference(Object bean, PropertyDescriptor pd, String name) { + + Object referenceObj = component.getComponentContext().getService(pd.getPropertyType(), name); + + if (referenceObj != null) { + try { + pd.getWriteMethod().invoke(bean, new Object[] { referenceObj }); + } catch (Throwable e) { + throw new FatalBeanException("Problem injecting reference: " + e.getMessage(), e); + } + } + } + + /** + * Processes a property descriptor to inject a service. + */ + /*public void injectMethod(Object bean, Method method) { + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); + + if (pd != null) { + Object referenceObj = component.getComponentContext().getService(pd.getPropertyType(), pd.getName()); + + if (referenceObj != null) { + try { + pd.getWriteMethod().invoke(bean, new Object[] { referenceObj }); + } catch (Throwable e) { + throw new FatalBeanException("Problem injecting reference: " + e.getMessage(), e); + } + } + } + }*/ +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/Constants.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/Constants.java new file mode 100644 index 0000000000..92f980fdfe --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/Constants.java @@ -0,0 +1,64 @@ +/* + * 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.tuscany.sca.implementation.spring.xml; + +import javax.xml.namespace.QName; + +/** + * Constants used in Spring Application Context XML files. + */ +public interface Constants { + + String SCA_NS = "http://www.springframework.org/schema/sca"; + String SPRING_NS = "http://www.springframework.org/schema/beans"; + + String PROPERTY = "property"; + QName SCAPROPERTY_ELEMENT = new QName(SCA_NS, PROPERTY); + QName PROPERTY_ELEMENT = new QName(SPRING_NS, PROPERTY); + + String SERVICE = "service"; + QName SERVICE_ELEMENT = new QName(SCA_NS, SERVICE); + + String REFERENCE = "reference"; + QName REFERENCE_ELEMENT = new QName(SCA_NS, REFERENCE); + + String BEANS = "beans"; + QName BEANS_ELEMENT = new QName(SPRING_NS, BEANS); + + String IMPORT = "import"; + QName IMPORT_ELEMENT = new QName(SPRING_NS, IMPORT); + + String BEAN = "bean"; + QName BEAN_ELEMENT = new QName(SPRING_NS, BEAN); + + String CONSTRUCTORARG = "constructor-arg"; + QName CONSTRUCTORARG_ELEMENT = new QName(SPRING_NS, CONSTRUCTORARG); + + String LIST = "list"; + QName LIST_ELEMENT = new QName(SPRING_NS, LIST); + + String VALUE = "value"; + QName VALUE_ELEMENT = new QName(SPRING_NS, VALUE); + + String REF = "ref"; + QName REF_ELEMENT = new QName(SPRING_NS, REF); + + String APPLICATION_CONTEXT = "application-context.xml"; +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringBeanElement.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringBeanElement.java new file mode 100644 index 0000000000..f9a9fee58f --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringBeanElement.java @@ -0,0 +1,67 @@ +/* + * 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.tuscany.sca.implementation.spring.xml; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a element in a Spring application-context + * - this has id and className attributes + * - plus zero or more property elements as children + * + * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ + */ +public class SpringBeanElement { + + private String id; + private String className; + private List properties = new ArrayList(); + private List constructorargs = new ArrayList(); + + public SpringBeanElement(String id, String className) { + this.id = id; + this.className = className; + } + + public String getClassName() { + return className; + } + + public String getId() { + return id; + } + + public List getProperties() { + return properties; + } + + public void addProperty(SpringPropertyElement property) { + properties.add(property); + } + + public List getCustructorArgs() { + return constructorargs; + } + + public void addCustructorArgs(SpringConstructorArgElement args) { + constructorargs.add(args); + } + +} // end class SpringBeanElement diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringBeanIntrospector.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringBeanIntrospector.java new file mode 100644 index 0000000000..3e526cd20e --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringBeanIntrospector.java @@ -0,0 +1,147 @@ +/* + * 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.tuscany.sca.implementation.spring.xml; + +import java.util.Map; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +import org.apache.tuscany.sca.implementation.java.DefaultJavaImplementationFactory; +import org.apache.tuscany.sca.implementation.java.IntrospectionException; +import org.apache.tuscany.sca.implementation.java.JavaImplementation; +import org.apache.tuscany.sca.implementation.java.JavaImplementationFactory; +import org.apache.tuscany.sca.implementation.java.impl.JavaElementImpl; +import org.apache.tuscany.sca.implementation.java.introspect.JavaClassVisitor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.AllowsPassByReferenceProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.BaseJavaClassVisitor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ComponentNameProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ConstructorProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ContextProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ConversationProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.DestroyProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.EagerInitProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.HeuristicPojoProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.InitProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.PolicyProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.PropertyProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ReferenceProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ResourceProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ScopeProcessor; +import org.apache.tuscany.sca.implementation.java.introspect.impl.ServiceProcessor; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; +import org.apache.tuscany.sca.policy.PolicyFactory; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; + +/** + * Provides introspection functions for Spring beans + * This version leans heavily on the implementation-java classes + * + * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ + */ +public class SpringBeanIntrospector { + + private JavaImplementationFactory javaImplementationFactory; + + /** + * The constructor sets up the various visitor elements that will be used to introspect + * the Spring bean and extract SCA information. + * + * @param assemblyFactory The Assembly Factory to use + * @param javaFactory The Java Interface Factory to use + * @param policyFactory The Policy Factory to use. + */ + public SpringBeanIntrospector(AssemblyFactory assemblyFactory, + JavaInterfaceFactory javaFactory, + PolicyFactory policyFactory) { + + javaImplementationFactory = new DefaultJavaImplementationFactory(); + + // Create the list of class visitors + BaseJavaClassVisitor[] extensions = + new BaseJavaClassVisitor[] { + new ConstructorProcessor(assemblyFactory), + new AllowsPassByReferenceProcessor(assemblyFactory), + new ComponentNameProcessor(assemblyFactory), + new ContextProcessor(assemblyFactory), + new ConversationProcessor(assemblyFactory), + new DestroyProcessor(assemblyFactory), + new EagerInitProcessor(assemblyFactory), + new InitProcessor(assemblyFactory), + new PropertyProcessor(assemblyFactory), + new ReferenceProcessor(assemblyFactory, javaFactory), + new ResourceProcessor(assemblyFactory), + new ScopeProcessor(assemblyFactory), + new ServiceProcessor(assemblyFactory, javaFactory), + new HeuristicPojoProcessor(assemblyFactory, javaFactory), + new PolicyProcessor(assemblyFactory, policyFactory)}; + for (JavaClassVisitor extension : extensions) { + javaImplementationFactory.addClassVisitor(extension); + } + + } // end constructor + + /** + * Introspect a Spring Bean and extract the features important to SCA + * @param beanClass the Spring Bean class to introspect + * @param componentType the componentType that is filled in through the introspection + * process (assumed empty on invocation, filled on return + * @return a Map of property names to JavaElementImpl + * @throws ContributionResolveException - if there was a problem resolving the + * Spring Bean or its componentType + * + */ + public Map introspectBean(Class beanClass, ComponentType componentType, + SpringImplementation springImplementation) throws ContributionResolveException + { + if (componentType == null) + throw new ContributionResolveException("Introspect Spring bean: supplied componentType is null"); + + // Create a Java implementation ready for the introspection + JavaImplementation javaImplementation = javaImplementationFactory.createJavaImplementation(); + + try { + // Introspect the bean...the results of the introspection are placed into the Java implementation + javaImplementationFactory.createJavaImplementation(javaImplementation, beanClass); + + // Extract the services, references & properties found through introspection + // put the services, references and properties into the component type + componentType.getServices().addAll(javaImplementation.getServices()); + componentType.getReferences().addAll(javaImplementation.getReferences()); + componentType.getProperties().addAll(javaImplementation.getProperties()); + + springImplementation.setInitMethod(javaImplementation.getInitMethod()); + springImplementation.setDestroyMethod(javaImplementation.getDestroyMethod()); + springImplementation.setConstructor(javaImplementation.getConstructor()); + + } catch (IntrospectionException e) { + throw new ContributionResolveException(e); + } // end try + + //List services = javaImplementation.getServices(); + //for (Service service : services) { + //String name = service.getName(); + //System.out.println("Spring Bean: found service with name: " + name); + //} // end for + + return javaImplementation.getPropertyMembers(); + + } // end method introspectBean + +} // end class SpringBeanIntrospector diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringConstructorArgElement.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringConstructorArgElement.java new file mode 100644 index 0000000000..57f4a26ba3 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringConstructorArgElement.java @@ -0,0 +1,60 @@ +/* + * 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.tuscany.sca.implementation.spring.xml; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a element in a Spring application-context + * - this has ref attribute + * + * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ + */ +public class SpringConstructorArgElement { + + private String ref; + private String type; + private List values = new ArrayList(); + + public SpringConstructorArgElement(String ref, String type) { + this.ref = ref; + this.type = type; + } + + public String getType() { + return this.type; + } + + public String getRef() { + return this.ref; + } + + public void setRef(String ref) { + this.ref = ref; + } + + public List getValues() { + return this.values; + } + + public void addValue(String value) { + this.values.add(value); + } +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringPropertyElement.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringPropertyElement.java new file mode 100644 index 0000000000..39e1286f32 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringPropertyElement.java @@ -0,0 +1,61 @@ +/* + * 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.tuscany.sca.implementation.spring.xml; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a element in a Spring application-context + * - this has name and ref attributes + * + * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ + */ +public class SpringPropertyElement { + + private String name; + private String ref; + private List values = new ArrayList(); + + public SpringPropertyElement(String name, String ref) { + this.name = name; + this.ref = ref; + } + + public String getName() { + return name; + } + + public String getRef() { + return ref; + } + + public void setRef(String ref) { + this.ref = ref; + } + + public List getProperties() { + return values; + } + + public void addProperty(String value) { + values.add(value); + } + +} // end class SpringPropertyElement diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAPropertyElement.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAPropertyElement.java new file mode 100644 index 0000000000..2f37ab6504 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAPropertyElement.java @@ -0,0 +1,52 @@ +/* + * 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.tuscany.sca.implementation.spring.xml; + +/** + * Represents an element in a Spring application-context + * - this has name and type attributes + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class SpringSCAPropertyElement { + + private String name; + private String type; + + public SpringSCAPropertyElement(String name, String type) { + this.name = name; + this.type = type; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return type; + } + +} // end class SpringPropertyElement diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAPropertyElement.java.orig b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAPropertyElement.java.orig new file mode 100644 index 0000000000..19874ad35d --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAPropertyElement.java.orig @@ -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.tuscany.sca.implementation.spring.xml; + +/** + * Represents an element in a Spring application-context + * - this has name and type attributes + * @version $Rev: 511195 $ $Date: 2007-02-24 02:29:46 +0000 (Sat, 24 Feb 2007) $ + */ +public class SpringSCAPropertyElement { + + private String name; + private String type; + + public SpringSCAPropertyElement(String name, String type) { + this.name = name; + this.type = type; + } + + public String getName() { + return name; + } + + public String getType() { + return type; + } + +} // end class SpringPropertyElement diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAReferenceElement.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAReferenceElement.java new file mode 100644 index 0000000000..b3f45415fd --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAReferenceElement.java @@ -0,0 +1,54 @@ +/* + * 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.tuscany.sca.implementation.spring.xml; + +/** + * Represents a element in a Spring application-context + * - this has id and className attributes + * - plus zero or more property elements as children + * + * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ + */ +public class SpringSCAReferenceElement { + + private String name; + private String type; + + public SpringSCAReferenceElement(String name, String type) { + this.name = name; + this.type = type; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return type; + } + +} // end class SpringSCAReferenceElement diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAServiceElement.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAServiceElement.java new file mode 100644 index 0000000000..2eb5686270 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringSCAServiceElement.java @@ -0,0 +1,64 @@ +/* + * 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.tuscany.sca.implementation.spring.xml; + +/** + * Represents a element in a Spring application-context + * - this has id and className attributes + * - plus zero or more property elements as children + * + * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ + */ +public class SpringSCAServiceElement { + + private String name; + private String type; + private String target; + + public SpringSCAServiceElement(String name, String type, String target) { + this.name = name; + this.type = type; + this.target = target; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public void setTarget(String target) { + this.target = target; + } + + public String getTarget() { + return target; + } + +} // end class SpringSCAServiceElement diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringXMLComponentTypeLoader.java b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringXMLComponentTypeLoader.java new file mode 100644 index 0000000000..214faf7198 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/java/org/apache/tuscany/sca/implementation/spring/xml/SpringXMLComponentTypeLoader.java @@ -0,0 +1,659 @@ +/* + * 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.tuscany.sca.implementation.spring.xml; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.Manifest; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.assembly.Multiplicity; +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.assembly.Service; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +import org.apache.tuscany.sca.implementation.java.impl.JavaElementImpl; +import org.apache.tuscany.sca.implementation.spring.SpringImplementation; +import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; +import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper; +import org.apache.tuscany.sca.policy.PolicyFactory; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; + +/** + * Introspects a Spring XML application-context configuration file to create + * component type information. + * + * + * @version $Rev: 512919 $ $Date: 2007-02-28 19:32:56 +0000 (Wed, 28 Feb 2007) $ + */ +public class SpringXMLComponentTypeLoader { + + private AssemblyFactory assemblyFactory; + private JavaInterfaceFactory javaFactory; + private ClassLoader cl; + + private SpringBeanIntrospector beanIntrospector; + + public SpringXMLComponentTypeLoader(AssemblyFactory assemblyFactory, + JavaInterfaceFactory javaFactory, + PolicyFactory policyFactory) { + super(); + this.assemblyFactory = assemblyFactory; + this.javaFactory = javaFactory; + beanIntrospector = + new SpringBeanIntrospector(assemblyFactory, javaFactory, policyFactory); + } + + protected Class getImplementationClass() { + return SpringImplementation.class; + } + + /** + * Base method which loads the component type from the application-context attached to the + * Spring implementation + * + */ + public void load(SpringImplementation implementation) throws ContributionReadException { + //System.out.println("Spring TypeLoader - load method start"); + ComponentType componentType = implementation.getComponentType(); + /* Check that there is a component type object already set */ + if (componentType == null) { + throw new ContributionReadException("SpringXMLLoader load: implementation has no ComponentType object"); + } + if (componentType.isUnresolved()) { + /* Fetch the location of the application-context file from the implementation */ + loadFromXML(implementation); + if (!componentType.isUnresolved()) + implementation.setUnresolved(false); + } // end if + //System.out.println("Spring TypeLoader - load method complete"); + } // end method load + + /** + * Method which fills out the component type for a Spring implementation by reading the + * Spring application-context.xml file. + * + * @param implementation SpringImplementation into which to load the component type information + * @throws ContributionReadException Failed to read the contribution + */ + private void loadFromXML(SpringImplementation implementation) throws ContributionReadException { + XMLStreamReader reader; + List beans = new ArrayList(); + List services = new ArrayList(); + List references = new ArrayList(); + List scaproperties = new ArrayList(); + + Resource resource; + + String location = implementation.getLocation(); + + try { + // FIXME - is the ContextClassLoader the right place to start the search? + cl = Thread.currentThread().getContextClassLoader(); + + resource = getApplicationContextResource(location, cl); + implementation.setResource(resource); + // The URI is used to uniquely identify the Implementation + implementation.setURI(resource.getURL().toString()); + // FIXME - need a better way to handle the XMLInputFactory than allocating a new one every time + XMLInputFactory xmlFactory = XMLInputFactory.newInstance(); + reader = xmlFactory.createXMLStreamReader(resource.getInputStream()); + + // System.out.println("Spring TypeLoader - starting to read context file"); + readBeanDefinition(reader, beans, services, references, scaproperties); + + } catch (IOException e) { + throw new ContributionReadException(e); + } catch (XMLStreamException e) { + throw new ContributionReadException(e); + } + + /* At this point, the complete application-context.xml file has been read and its contents */ + /* stored in the lists of beans, services, references. These are now used to generate */ + /* the implied componentType for the application context */ + generateComponentType(implementation, beans, services, references, scaproperties); + + return; + } // end method loadFromXML + + /** + * Method which returns the XMLStreamReader for the Spring application-context.xml file + * specified in the location attribute + */ + private XMLStreamReader getApplicationContextReader (String location) throws ContributionReadException { + + try { + // FIXME - is the ContextClassLoader the right place to start the search? + cl = Thread.currentThread().getContextClassLoader(); + Resource resource = getApplicationContextResource(location, cl); + // FIXME - need a better way to handle the XMLInputFactory than allocating a new one every time + XMLInputFactory xmlFactory = XMLInputFactory.newInstance(); + XMLStreamReader reader = xmlFactory.createXMLStreamReader(resource.getInputStream()); + return reader; + } catch (IOException e) { + throw new ContributionReadException(e); + } catch (XMLStreamException e) { + throw new ContributionReadException(e); + } + } + + /** + * Method which reads the bean definitions from Spring application-context.xml file and identifies + * the defined beans, properties, services and references + */ + private void readBeanDefinition(XMLStreamReader reader, + List beans, + List services, + List references, + List scaproperties) throws ContributionReadException { + + SpringBeanElement bean = null; + SpringPropertyElement property = null; + SpringConstructorArgElement constructorArg = null; + + try { + boolean completed = false; + while (!completed) { + switch (reader.next()) { + case START_ELEMENT: + QName qname = reader.getName(); + //System.out.println("Spring TypeLoader - found element with name: " + qname.toString()); + if (Constants.IMPORT_ELEMENT.equals(qname)) { + //FIXME - put the sequence of code below which gets the ireader into a subsidiary method + String location = reader.getAttributeValue(null, "resource"); + if (location != null) { + XMLStreamReader ireader = getApplicationContextReader(location); + // Read the bean definition for the identified imported resource + readBeanDefinition(ireader, beans, services, references, scaproperties); + } + } else if (Constants.SERVICE_ELEMENT.equals(qname)) { + SpringSCAServiceElement service = + new SpringSCAServiceElement(reader.getAttributeValue(null, "name"), reader + .getAttributeValue(null, "type"), reader.getAttributeValue(null, "target")); + services.add(service); + } else if (Constants.REFERENCE_ELEMENT.equals(qname)) { + SpringSCAReferenceElement reference = + new SpringSCAReferenceElement(reader.getAttributeValue(null, "name"), reader + .getAttributeValue(null, "type")); + references.add(reference); + } else if (Constants.SCAPROPERTY_ELEMENT.equals(qname)) { + SpringSCAPropertyElement scaproperty = + new SpringSCAPropertyElement(reader.getAttributeValue(null, "name"), reader + .getAttributeValue(null, "type")); + scaproperties.add(scaproperty); + } else if (Constants.BEAN_ELEMENT.equals(qname)) { + bean = new SpringBeanElement(reader.getAttributeValue(null, "id"), reader + .getAttributeValue(null, "class")); + //beans.add(bean); + } else if (Constants.PROPERTY_ELEMENT.equals(qname)) { + property = new SpringPropertyElement(reader.getAttributeValue(null, "name"), reader + .getAttributeValue(null, "ref")); + //bean.addProperty(property); + } else if (Constants.CONSTRUCTORARG_ELEMENT.equals(qname)) { + constructorArg = new SpringConstructorArgElement(reader.getAttributeValue(null, "ref"), + reader.getAttributeValue(null, "type")); + } else if (Constants.REF_ELEMENT.equals(qname)) { + String ref = reader.getAttributeValue(null, "bean"); + // Check if the parent element is a property + if (property != null) property.setRef(ref); + // Check if the parent element is a constructor-arg + if (constructorArg != null) constructorArg.setRef(ref); + } else if (Constants.VALUE_ELEMENT.equals(qname)) { + String value = reader.getElementText(); + // Check if the parent element is a constructor-arg + if (constructorArg != null) { + constructorArg.addValue(value); + // Identify the XML resource specified for the constructor-arg element + if ((value.indexOf(".xml") != -1)) { + if ((bean.getClassName().indexOf(".ClassPathXmlApplicationContext") != -1) || + (bean.getClassName().indexOf(".FileSystemXmlApplicationContext") != -1)) { + XMLStreamReader creader = getApplicationContextReader(value); + // Read the bean definition for the constructor-arg resources + readBeanDefinition(creader, beans, services, references, scaproperties); + } + } + } + } // end if + break; + case END_ELEMENT: + if (Constants.BEANS_ELEMENT.equals(reader.getName())) { + //System.out.println("Spring TypeLoader - finished read of context file"); + completed = true; + break; + } else if (Constants.BEAN_ELEMENT.equals(reader.getName())) { + beans.add(bean); + bean = null; + } else if (Constants.PROPERTY_ELEMENT.equals(reader.getName())) { + bean.addProperty(property); + property = null; + } else if (Constants.CONSTRUCTORARG_ELEMENT.equals(reader.getName())) { + bean.addCustructorArgs(constructorArg); + constructorArg = null; + } // end if + } // end switch + } // end while + } catch (XMLStreamException e) { + throw new ContributionReadException(e); + } + } + + /** + * Generates the Spring implementation component type from the configuration contained in the + * lists of beans, services, references and scaproperties derived from the application context + */ + private void generateComponentType(SpringImplementation implementation, + List beans, + List services, + List references, + List scaproperties) throws ContributionReadException { + /* + * 1. Each service becomes a service in the component type + * 2. Each reference becomes a reference in the component type + * 3. IF there are no explicit service elements, each bean becomes a service + * 4. Each bean property which is a reference not pointing at another bean in the + * application context becomes a reference unless it is pointing at one of the references + * 5. Each scaproperty becomes a property in the component type + * 6. Each bean property which is not a reference and which is not pointing + * at another bean in the application context becomes a property in the component type + */ + + ComponentType componentType = implementation.getComponentType(); + + try { + // Deal with the services first.... + Iterator its = services.iterator(); + while (its.hasNext()) { + SpringSCAServiceElement serviceElement = its.next(); + Class interfaze = cl.loadClass(serviceElement.getType()); + Service theService = createService(interfaze, serviceElement.getName()); + componentType.getServices().add(theService); + // Add this service to the Service / Bean map + String beanName = serviceElement.getTarget(); + for (SpringBeanElement beanElement : beans) { + if (beanName.equals(beanElement.getId())) { + implementation.setBeanForService(theService, beanElement); + } + } // end for + } // end while + + // Next handle the references + Iterator itr = references.iterator(); + while (itr.hasNext()) { + SpringSCAReferenceElement referenceElement = itr.next(); + Class interfaze = cl.loadClass(referenceElement.getType()); + Reference theReference = createReference(interfaze, referenceElement.getName()); + componentType.getReferences().add(theReference); + } // end while + + // Finally deal with the beans + Iterator itb; + // If there are no explicit service elements, then expose all the beans + if (services.isEmpty()) { + itb = beans.iterator(); + // Loop through all the beans found + while (itb.hasNext()) { + SpringBeanElement beanElement = itb.next(); + // Load the Spring bean class + Class beanClass = cl.loadClass(beanElement.getClassName()); + // Introspect the bean + ComponentType beanComponentType = assemblyFactory.createComponentType(); + beanIntrospector.introspectBean(beanClass, beanComponentType, implementation); + // Get the service interface defined by this Spring Bean and add to + // the component type of the Spring Assembly + List beanServices = beanComponentType.getServices(); + componentType.getServices().addAll(beanServices); + // Add these services to the Service / Bean map + for (Service beanService : beanServices) { + implementation.setBeanForService(beanService, beanElement); + } + } // end while + } // end if + // Now check to see if there are any more references from beans that are not satisfied + itb = beans.iterator(); + while (itb.hasNext()) { + SpringBeanElement beanElement = itb.next(); + boolean unresolvedProperties = false; + if (!beanElement.getProperties().isEmpty()) { + // Scan through the properties + Iterator itp = beanElement.getProperties().iterator(); + while (itp.hasNext()) { + SpringPropertyElement propertyElement = itp.next(); + if (propertyRefUnresolved(propertyElement.getRef(), beans, references, scaproperties)) { + // This means an unresolved reference from the spring bean... + unresolvedProperties = true; + } // end if + } // end while + // If there are unresolved properties, then find which ones are references + if (unresolvedProperties) { + Class beanClass = cl.loadClass(beanElement.getClassName()); + // Introspect the bean + ComponentType beanComponentType = assemblyFactory.createComponentType(); + Map propertyMap = + beanIntrospector.introspectBean(beanClass, beanComponentType, implementation); + // Get the references by this Spring Bean and add the unresolved ones to + // the component type of the Spring Assembly + List beanReferences = beanComponentType.getReferences(); + List beanProperties = beanComponentType.getProperties(); + itp = beanElement.getProperties().iterator(); + while (itp.hasNext()) { + SpringPropertyElement propertyElement = itp.next(); + if (propertyRefUnresolved(propertyElement.getRef(), beans, references, scaproperties)) { + boolean resolved = false; + // This means an unresolved reference from the spring bean...add it to + // the references for the Spring application context + for (Reference reference : beanReferences) { + if (propertyElement.getName().equals(reference.getName())) { + // The name of the reference in this case is the string in + // the @ref attribute of the Spring property element, NOT the + // name of the field in the Spring bean.... + reference.setName(propertyElement.getRef()); + componentType.getReferences().add(reference); + resolved = true; + } // end if + } // end for + if (!resolved) { + // If the bean property is not already resolved as a reference + // then it must be an SCA property... + for (Property scaproperty : beanProperties) { + if (propertyElement.getName().equals(scaproperty.getName())) { + // The name of the reference in this case is the string in + // the @ref attribute of the Spring property element, NOT the + // name of the field in the Spring bean.... + scaproperty.setName(propertyElement.getRef()); + componentType.getProperties().add(scaproperty); + // Fetch and store the type of the property + implementation.setPropertyClass(scaproperty.getName(), propertyMap + .get(scaproperty.getName()).getType()); + resolved = true; + } // end if + } // end for + } // end if + } // end if + } // end while + } // end if + } // end if + + } // end while + + Iterator itsp = scaproperties.iterator(); + while (itsp.hasNext()) { + SpringSCAPropertyElement scaproperty = itsp.next(); + // Create a component type property if the SCA property element has a name + // and a type declared... + if (scaproperty.getType() != null && scaproperty.getName() != null) { + Property theProperty = assemblyFactory.createProperty(); + theProperty.setName(scaproperty.getName()); + // Get the Java class and then an XSD element type for the property + Class propType = Class.forName(scaproperty.getType()); + theProperty.setXSDType(JavaXMLMapper.getXMLType(propType)); + componentType.getProperties().add(theProperty); + // Remember the Java Class (ie the type) for this property + implementation.setPropertyClass(theProperty.getName(), propType); + } // end if + } // end while + + } catch (ClassNotFoundException e) { + // Means that either an interface class, property class or a bean was not found + throw new ContributionReadException(e); + } catch (InvalidInterfaceException e) { + throw new ContributionReadException(e); + } catch (ContributionResolveException e) { + + } // end try + + // If we get here, the Spring assembly component type is resolved + componentType.setUnresolved(false); + implementation.setComponentType(componentType); + return; + } // end method generateComponentType + + /* + * Determines whether a reference attribute of a Spring property element is resolved either + * by a bean in the application context or by an SCA reference element or by an SCA property + * element + * @param ref - a String containing the name of the reference - may be null + * @param beans - a List of SpringBean elements + * @param references - a List of SCA reference elements + * @return true if the property is not resolved, false if it is resolved + */ + private boolean propertyRefUnresolved(String ref, + List beans, + List references, + List scaproperties) { + boolean unresolved = true; + + if (ref != null) { + // Scan over the beans looking for a match + Iterator itb = beans.iterator(); + while (itb.hasNext()) { + SpringBeanElement beanElement = itb.next(); + // Does the bean name match the ref? + if (ref.equals(beanElement.getId())) { + unresolved = false; + break; + } // end if + } // end while + // Scan over the SCA reference elements looking for a match + if (unresolved) { + Iterator itr = references.iterator(); + while (itr.hasNext()) { + SpringSCAReferenceElement referenceElement = itr.next(); + if (ref.equals(referenceElement.getName())) { + unresolved = false; + break; + } // end if + } // end while + } // end if + // Scan over the SCA property elements looking for a match + if (unresolved) { + Iterator itsp = scaproperties.iterator(); + while (itsp.hasNext()) { + SpringSCAPropertyElement propertyElement = itsp.next(); + if (ref.equals(propertyElement.getName())) { + unresolved = false; + break; + } // end if + } // end while + } // end if + } else { + // In the case where ref = null, the property is not going to be a reference of any + // kind and can be ignored + unresolved = false; + } // end if + + return unresolved; + + } // end method propertyRefUnresolved + + /** + * Gets hold of the application-context.xml file as a Spring resource + * @param locationAttr - the location attribute from the element + * @param cl - the ClassLoader for the Spring implementation + */ + protected Resource getApplicationContextResource(String locationAttr, ClassLoader cl) + throws ContributionReadException { + File manifestFile = null; + File appXmlFile; + File locationFile = null; + + URL url = cl.getResource(locationAttr); + if (url != null) { + String path = url.getPath(); + locationFile = new File(path); + } else { + throw new ContributionReadException( + "SpringXMLLoader getApplicationContextResource: " + "unable to find resource file " + + locationAttr); + } + + if (locationFile.isDirectory()) { + try { + manifestFile = new File(locationFile, "META-INF"+ File.separator +"MANIFEST.MF"); + if (manifestFile.exists()) { + Manifest mf = new Manifest(new FileInputStream(manifestFile)); + Attributes mainAttrs = mf.getMainAttributes(); + String appCtxPath = mainAttrs.getValue("Spring-Context"); + if (appCtxPath != null) { + appXmlFile = new File(locationFile, appCtxPath); + if (appXmlFile.exists()) { + return new UrlResource(appXmlFile.toURL()); + } + } + } + // no manifest-specified Spring context, use default + appXmlFile = new File(locationFile, "META-INF" + File.separator + "spring" + + File.separator + Constants.APPLICATION_CONTEXT); + if (appXmlFile.exists()) { + return new UrlResource(appXmlFile.toURL()); + } + } catch (IOException e) { + throw new ContributionReadException("Error reading manifest " + manifestFile); + } + } else { + if (locationFile.isFile() && locationFile.getName().endsWith(".jar")) { + try { + JarFile jf = new JarFile(locationFile); + JarEntry je; + Manifest mf = jf.getManifest(); + if (mf != null) { + Attributes mainAttrs = mf.getMainAttributes(); + String appCtxPath = mainAttrs.getValue("Spring-Context"); + if (appCtxPath != null) { + je = jf.getJarEntry(appCtxPath); + if (je != null) { + // TODO return a Spring specific Resource type for jars + return new UrlResource(new URL("jar:" + locationFile.toURI().toURL() + "!/" + appCtxPath)); + } + } + } + je = jf.getJarEntry("META-INF" + "/" + "spring" + "/" + Constants.APPLICATION_CONTEXT); + if (je != null) { + return new UrlResource(new URL("jar:" + locationFile.toURI().toURL() + "!/" + Constants.APPLICATION_CONTEXT)); + } + } catch (IOException e) { + // bad archive + // TODO: create a more appropriate exception type + throw new ContributionReadException("SpringXMLLoader getApplicationContextResource: " + + " IO exception reading context file.", e); + } + } + else { + if (locationFile.getName().endsWith(".xml")) { + return new UrlResource(url); + } + else { + // Deal with the directory inside a jar file, in case the contribution itself is a JAR file. + try { + if (locationFile.getPath().indexOf(".jar") > 0) { + String jarEntry = url.getPath().substring(6, url.getPath().indexOf("!")); + JarFile jf = new JarFile(jarEntry); + JarEntry je = jf.getJarEntry(url.getPath().substring(url.getPath().indexOf("!/")+2) + + "/" + "META-INF" + "/" + "MANIFEST.MF"); + if (je != null) { + Manifest mf = new Manifest(jf.getInputStream(je)); + Attributes mainAttrs = mf.getMainAttributes(); + String appCtxPath = mainAttrs.getValue("Spring-Context"); + if (appCtxPath != null) { + je = jf.getJarEntry(url.getPath().substring(url.getPath().indexOf("!/")+2) + "/" + appCtxPath); + if (je != null) { + return new UrlResource(new URL("jar:" + url.getPath() + "/" + appCtxPath)); + } + } + } + } + } catch (IOException e) { + throw new ContributionReadException("Error reading manifest " + manifestFile); + } + } + } + } + + throw new ContributionReadException("SpringXMLLoader getApplicationContextResource: " + + "META-INF/spring/" + Constants.APPLICATION_CONTEXT + "not found"); + } // end method getApplicationContextResource + + /** + * Creates a Service for the component type based on its name and Java interface + */ + public Service createService(Class interfaze, String name) throws InvalidInterfaceException { + Service service = assemblyFactory.createService(); + JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract(); + service.setInterfaceContract(interfaceContract); + + // Set the name for the service + service.setName(name); + + // Set the call interface and, if present, the callback interface + JavaInterface callInterface = javaFactory.createJavaInterface(interfaze); + service.getInterfaceContract().setInterface(callInterface); + if (callInterface.getCallbackClass() != null) { + JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass()); + service.getInterfaceContract().setCallbackInterface(callbackInterface); + } + return service; + } // end method createService + + /** + * Creates a Reference for the component type based on its name and Java interface + */ + private org.apache.tuscany.sca.assembly.Reference createReference(Class interfaze, String name) + throws InvalidInterfaceException { + org.apache.tuscany.sca.assembly.Reference reference = assemblyFactory.createReference(); + JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract(); + reference.setInterfaceContract(interfaceContract); + + // Set the name of the reference to the supplied name and the multiplicity of the reference + // to 1..1 - for Spring implementations, this is the only multiplicity supported + reference.setName(name); + reference.setMultiplicity(Multiplicity.ONE_ONE); + + // Set the call interface and, if present, the callback interface + JavaInterface callInterface = javaFactory.createJavaInterface(interfaze); + reference.getInterfaceContract().setInterface(callInterface); + if (callInterface.getCallbackClass() != null) { + JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass()); + reference.getInterfaceContract().setCallbackInterface(callbackInterface); + } + + return reference; + } +} // end class SpringXMLComponentTypeLoader diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor new file mode 100644 index 0000000000..4b71cef6c4 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor @@ -0,0 +1,19 @@ +# 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. + +# Implementation class for the artifact processor extension +org.apache.tuscany.sca.implementation.spring.SpringImplementationProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#implementation.spring,model=org.apache.tuscany.sca.implementation.spring.SpringImplementation diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory b/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory new file mode 100644 index 0000000000..ab707cfd68 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory @@ -0,0 +1,19 @@ +# 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. + +# Implementation class for the implementation extension +org.apache.tuscany.sca.implementation.spring.SpringImplementationProviderFactory;model=org.apache.tuscany.sca.implementation.spring.SpringImplementation diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/spring.handlers b/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/spring.handlers new file mode 100644 index 0000000000..7f9a7b17b0 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/spring.handlers @@ -0,0 +1 @@ +http\://www.springframework.org/schema/sca=org.apache.tuscany.sca.implementation.spring.ScaNamespaceHandler diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/spring.schemas b/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/spring.schemas new file mode 100644 index 0000000000..249cc21c13 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/META-INF/spring.schemas @@ -0,0 +1 @@ +http\://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd=org/springframework/sca/xml/spring-sca.xsd diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/impl-spring-validation-messages.properties b/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/impl-spring-validation-messages.properties new file mode 100644 index 0000000000..6fce02664a --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/impl-spring-validation-messages.properties @@ -0,0 +1,23 @@ +# +# +# 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. +# +# +LocationAttributeMissing = Reading implementation.spring - location attribute missing +ContributionResolveException = ContributionResolveException occured due to: +UnableToResolveComponentType = SpringArtifactProcessor: unable to resolve componentType for Spring component \ No newline at end of file diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/org/springframework/sca/xml/spring-sca.xsd b/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/org/springframework/sca/xml/spring-sca.xsd new file mode 100644 index 0000000000..e20f4e8158 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/main/resources/org/springframework/sca/xml/spring-sca.xsd @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/AbstractSCATestCase.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/AbstractSCATestCase.java new file mode 100644 index 0000000000..6b2d114756 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/AbstractSCATestCase.java @@ -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.tuscany.sca.implementation.spring.itests; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.host.embedded.SCADomain; + +/** + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractSCATestCase extends TestCase { + + protected SCADomain domain; + protected T service; + + @Override + protected void setUp() throws Exception { + domain = SCADomain.newInstance(getCompositeName()); + service = (T)domain.getService(getServiceClass(), "ClientComponent"); + } + + protected abstract Class getServiceClass(); + + @Override + protected void tearDown() throws Exception { + domain.close(); + } + + protected String getCompositeName() { + String className = this.getClass().getName(); + String compositeName = className.substring(0, className.length() - 8).replace('.', '/') + ".composite"; + System.out.println("Using composite: " + compositeName); + return compositeName; + } + +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/AbstractHelloWorldTestCase.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/AbstractHelloWorldTestCase.java new file mode 100644 index 0000000000..c9b30b1688 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/AbstractHelloWorldTestCase.java @@ -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.tuscany.sca.implementation.spring.itests.helloworld; + +import org.apache.tuscany.sca.implementation.spring.itests.AbstractSCATestCase; + +/** + * Basic "hello world" style test case for testing Spring component implementation + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractHelloWorldTestCase extends AbstractSCATestCase { + + /** + * Calls the hello world service and checks that it gives the right response... + */ + public void testCalculator() throws Exception { + assertEquals("Hello petra", service.sayHello("petra")); + System.out.println("Test " + this.getClass().getSimpleName() + " completed successfully"); + } + + @Override + protected Class getServiceClass() { + return HelloWorld.class; + } +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/HelloWorld.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/HelloWorld.java new file mode 100644 index 0000000000..fd295daaf6 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/HelloWorld.java @@ -0,0 +1,35 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.helloworld; + +import org.osoa.sca.annotations.Remotable; + +/** + * Interface for the "hello world" service - predictably simple with a single operation + * "sayHello" + * + * @version $Rev$ $Date$ + */ +@Remotable +public interface HelloWorld { + + String sayHello(String s); + +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/HelloWorldImpl.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/HelloWorldImpl.java new file mode 100644 index 0000000000..65ab096855 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/HelloWorldImpl.java @@ -0,0 +1,38 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.helloworld; + +/** + * A simple proxy Java class which implements the HelloWorld interface but which uses + * a reference "delegate" to actually provide the HelloWorld service + * + * @version $Rev$ $Date$ + */ +public class HelloWorldImpl implements HelloWorld { + + static String hello = "Hello "; + + public String sayHello(String s) { + // Simply call the reference to satisfy the service request... + System.out.println("HelloWorldImpl - sayHello called"); + return (hello + s); + } + +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/HelloWorldProxy.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/HelloWorldProxy.java new file mode 100644 index 0000000000..bd35e9f3b9 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/HelloWorldProxy.java @@ -0,0 +1,42 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.helloworld; + +import org.osoa.sca.annotations.Reference; + +/** + * A simple proxy Java class which implements the HelloWorld interface but which uses + * a reference "delegate" to actually provide the HelloWorld service + * + * @version $Rev$ $Date$ + */ +public class HelloWorldProxy implements HelloWorld { + + // Here is the reference "delegate" - it implements the HelloWorld interface... + @Reference + public HelloWorld delegate; + + public String sayHello(String s) { + // Simply call the reference to satisfy the service request... + System.out.println("HelloWorldProxy - calling sayHello"); + return delegate.sayHello(s); + } + +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringContextAccessTestCase.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringContextAccessTestCase.java new file mode 100644 index 0000000000..d77f183a66 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringContextAccessTestCase.java @@ -0,0 +1,35 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.helloworld; + +/** + * A test case to check the ability of Spring Beans used as an SCA implementation + * to access the Spring application context without problems: + * 1) A composite containing a component with a Spring implementation + * 2) The composite has a component with a Java POJO implementation which uses the + * Spring implementation to satisfy a reference + * 3) The Spring Bean accesses the Spring application context and only returns data + * if it is successful + * + * @version $Rev$ $Date$ + */ +public class SpringContextAccessTestCase extends AbstractHelloWorldTestCase { + // super class does it all getting composite based on this class name +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitHelloWorldTestCase.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitHelloWorldTestCase.java new file mode 100644 index 0000000000..86f979fe15 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitHelloWorldTestCase.java @@ -0,0 +1,34 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.helloworld; + +/** + * A basic test case of: + * 1) A composite containing a component with a Spring implementation + * 2) The composite has a component with a Java POJO implementation which uses the + * Spring implementation to satisfy a reference + * 3) The element references an application context that + * uses an explicit sca: element to identify the service offered by the Spring application + * + * @version $Rev$ $Date$ + */ +public class SpringExplicitHelloWorldTestCase extends AbstractHelloWorldTestCase { + // super class does it all getting composite based on this class name +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitReferenceTestCase.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitReferenceTestCase.java new file mode 100644 index 0000000000..44016ad249 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitReferenceTestCase.java @@ -0,0 +1,39 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.helloworld; + +/** + * A test case designed to test the implementation of References from a Spring application + * context, where the references are explicit, through the presence of an sca:reference + * element within the Spring application context + * + * The artifacts involved in this test are: + * + * 1) A composite containing a component with a Spring implementation which makes + * a reference to a second component + * 2) The composite has a component with a Java POJO implementation which satisfies the reference + * 3) The element references an application context that + * uses an explicit sca:reference element to identify the reference made by the Spring application + * + * @version $Rev$ $Date$ + */ +public class SpringExplicitReferenceTestCase extends AbstractHelloWorldTestCase { + // super class does it all getting composite based on this class name +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringHelloWorldTestCase.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringHelloWorldTestCase.java new file mode 100644 index 0000000000..74dcf32723 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringHelloWorldTestCase.java @@ -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.tuscany.sca.implementation.spring.itests.helloworld; + +/** + * A basic test case of: + * 1) A composite containing a component with a Spring implementation + * 2) The composite has a component with a Java POJO implementation which uses the + * Spring implementation to satisfy a reference + * + * @version $Rev$ $Date$ + */ +public class SpringHelloWorldTestCase extends AbstractHelloWorldTestCase { + // super class does it all getting composite based on this class name +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImplicitReferenceTestCase.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImplicitReferenceTestCase.java new file mode 100644 index 0000000000..97f91ff91e --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImplicitReferenceTestCase.java @@ -0,0 +1,42 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.helloworld; + +/** + * A test case designed to test the implementation of References from a Spring application + * context, where the references are implicit, through the presence of Bean properties with a + * ref attribute which is not satisfied by a Bean within the application context. + * + * The artifacts involved in this test are: + * + * 1) A composite containing a component with a Spring implementation which makes + * a reference to a second component + * 2) The composite has a component with a Java POJO implementation which satisfies the reference + * 3) The element references an application context that + * does not use an explicit sca:reference element to identify the reference made by the + * Spring application, but relies on an unsatisfied Bean property with a ref attribute. + * + * @version $Rev$ $Date$ + */ +public class SpringImplicitReferenceTestCase extends AbstractHelloWorldTestCase { + // super class does it all getting composite based on this class name +} + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImportHelloWorldTestCase.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImportHelloWorldTestCase.java new file mode 100644 index 0000000000..bfe3d64cf3 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImportHelloWorldTestCase.java @@ -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.tuscany.sca.implementation.spring.itests.helloworld; + +/** + * A basic test case of: + * 1) A composite containing a component with a Spring implementation + * 2) The composite has a component with a Java POJO implementation which uses the + * Spring implementation to satisfy a reference + * + * @version $Rev$ $Date$ + */ +public class SpringImportHelloWorldTestCase extends AbstractHelloWorldTestCase { + // super class does it all getting composite based on this class name +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringSCAPropertyTestCase.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringSCAPropertyTestCase.java new file mode 100644 index 0000000000..2c46f8c066 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringSCAPropertyTestCase.java @@ -0,0 +1,39 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.helloworld; + +/** + * A test case designed to test the implementation of Properties from a Spring application + * context, where the properties are explicit, through the presence of an sca:property + * element within the Spring application context + * + * The artifacts involved in this test are: + * + * 1) A composite containing a component with a Spring implementation + * 2) The element references an application context that + * uses an explicit sca:property element which is used to compute the response to an invocation + * of the service of the implementation + * + * @version $Rev$ $Date$ + */ +public class SpringSCAPropertyTestCase extends AbstractHelloWorldTestCase { + // super class does it all getting composite based on this class name +} + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestBean.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestBean.java new file mode 100644 index 0000000000..4d60bffef8 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestBean.java @@ -0,0 +1,31 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.mock; + +/** + * @version $Rev: 430937 $ $Date: 2006-08-12 02:17:56 +0100 (Sat, 12 Aug 2006) $ + */ +public interface TestBean { + String echo(String msg); + + TestBean getBean(); + + void setBean(TestBean bean); + +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestBeanImpl.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestBeanImpl.java new file mode 100644 index 0000000000..acad9f2fea --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestBeanImpl.java @@ -0,0 +1,42 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.mock; + +/** + * @version $Rev: 441406 $ $Date: 2006-09-08 08:20:10 +0100 (Fri, 08 Sep 2006) $ + */ +public class TestBeanImpl implements TestBean { + + private TestBean bean; + + public TestBeanImpl() { + } + + public String echo(String msg) { + return msg; + } + + public TestBean getBean() { + return bean; + } + + public void setBean(TestBean bean) { + this.bean = bean; + } +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestContextAccessBean.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestContextAccessBean.java new file mode 100644 index 0000000000..79de2b32a0 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestContextAccessBean.java @@ -0,0 +1,77 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.mock; + +/** + * Spring bean test class for testing the access to the Spring Context from within + * a Spring Bean running as part of an SCA Component. + * + * This class accesses the Spring Context and only returns non-null data if the + * Context is successfully accessed. + * + * The design to receive the application context is as follows: + * - the Bean implements the ApplicationContextAware interface + * - this interface provides getter and setter methods for the Spring application + * context + * - when the Bean is created at runtime, the setter method is called, injecting + * the context + */ + +import org.apache.tuscany.sca.implementation.spring.itests.helloworld.HelloWorld; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + + +public class TestContextAccessBean implements HelloWorld, ApplicationContextAware { + + private static ApplicationContext ctx; + static String hello = "Hello "; + + // Return the hello string only if the application context is successfully accessed + public String sayHello(String message) { + System.out.println("TestContextAccessBean - sayHello called"); + ApplicationContext theContext = getApplicationContext(); + + if( theContext == null ) return null; + + // A simple check to see if the context contains this bean, which it should... + if ( !theContext.containsBean( "testBean" ) ) return null; + + return (hello + message); + } // end sayHello() + + /** + * Application context setter + */ + public void setApplicationContext(ApplicationContext appContext) throws BeansException { + // Wiring the ApplicationContext into a static method + ctx = appContext; + } + + /** + * Application context getter + * @return + */ + public static ApplicationContext getApplicationContext() { + return ctx; + } + +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestHelloWorldBean.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestHelloWorldBean.java new file mode 100644 index 0000000000..f165bb8b75 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestHelloWorldBean.java @@ -0,0 +1,39 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.mock; + +/** + * A simple test Spring bean which provides the HelloWorld service + * + * @version $Rev$ $Date$ + */ + +import org.apache.tuscany.sca.implementation.spring.itests.helloworld.HelloWorld; + +public class TestHelloWorldBean implements HelloWorld { + + static String hello = "Hello "; + + // Classic "Hello xxx" response to any input message + public String sayHello(String message) { + System.out.println("TestHelloWorldBean - sayHello called"); + return (hello + message); + } + +} // end class TestHelloWorldBean diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestReference.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestReference.java new file mode 100644 index 0000000000..a1d9b5a2f4 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestReference.java @@ -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.tuscany.sca.implementation.spring.itests.mock; + +/** + * @version $Rev: 536115 $ $Date: 2007-05-08 09:04:20 +0100 (Tue, 08 May 2007) $ + */ +public interface TestReference { + String echo(String msg); +} diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestReferenceBean.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestReferenceBean.java new file mode 100644 index 0000000000..ab4c07d059 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestReferenceBean.java @@ -0,0 +1,57 @@ +/* + * 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.tuscany.sca.implementation.spring.itests.mock; + +/** + * A test Spring bean which provides the HelloWorld service by calling a reference + * to provide the content of the response + * + * @version $Rev$ $Date$ + */ + +import org.apache.tuscany.sca.implementation.spring.itests.helloworld.HelloWorld; + +public class TestReferenceBean implements HelloWorld { + + // The reference + private HelloWorld bean; + + // Classic "Hello xxx" response to any input message + public String sayHello(String message) { + System.out.println("TestReferenceBean - sayHello called"); + return (bean.sayHello(message)); + } + + /** + * Setter for the bean reference + * @param theBean + */ + public void setBean(HelloWorld theBean) { + this.bean = theBean; + } + + /** + * Getter for the reference + * @return + */ + public HelloWorld getBean() { + return this.bean; + } + +} // end class TestReferenceBean diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestSCAPropertyBean.java b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestSCAPropertyBean.java new file mode 100644 index 0000000000..0f00c7e480 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/java/org/apache/tuscany/sca/implementation/spring/itests/mock/TestSCAPropertyBean.java @@ -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.tuscany.sca.implementation.spring.itests.mock; + +/** + * A test Spring bean which provides the HelloWorld service. + * This bean has a single String property called "hello" which must be set through + * external configuration to give the correct response message, otherwise an (incorrect) + * default message is generated + * + * @version $Rev$ $Date$ + */ + +import org.apache.tuscany.sca.implementation.spring.itests.helloworld.HelloWorld; + +public class TestSCAPropertyBean implements HelloWorld { + + private String hello = "Go away"; + + /** + * Provides the operation of the "HelloWorld" interface - a simple string response + * to a string input message, where the response is a greeting followed by the original + * input message. + */ + public String sayHello(String message) { + System.out.println("TestHelloWorldBean - sayHello called"); + return (hello + " " + message); + } + + /** + * Public setter for the (unannotated) field "hello" which constitutes an SCA + * property + * @param message - the message to use for the response to "sayHello" + */ + public void setHello(String message) { + hello = message; + } + +} // end class TestSCAPropertyBean diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringContextAccess-context.xml b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringContextAccess-context.xml new file mode 100644 index 0000000000..a7d30bf201 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringContextAccess-context.xml @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringExplicitHelloWorld-context.xml b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringExplicitHelloWorld-context.xml new file mode 100644 index 0000000000..7c358ac01c --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringExplicitHelloWorld-context.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringExplicitReference-context.xml b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringExplicitReference-context.xml new file mode 100644 index 0000000000..38e90b41fa --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringExplicitReference-context.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringHelloWorld-Imported-context.xml b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringHelloWorld-Imported-context.xml new file mode 100644 index 0000000000..18ce21805c --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringHelloWorld-Imported-context.xml @@ -0,0 +1,31 @@ + + + + + + + + + \ No newline at end of file diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringHelloWorld-context.xml b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringHelloWorld-context.xml new file mode 100644 index 0000000000..18ce21805c --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringHelloWorld-context.xml @@ -0,0 +1,31 @@ + + + + + + + + + \ No newline at end of file diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringImplicitReference-context.xml b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringImplicitReference-context.xml new file mode 100644 index 0000000000..e6b69e8cad --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringImplicitReference-context.xml @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringImportHelloWorld-context.xml b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringImportHelloWorld-context.xml new file mode 100644 index 0000000000..8e18a56cca --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/SpringImportHelloWorld-context.xml @@ -0,0 +1,29 @@ + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/testReferenceContext.xml b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/testReferenceContext.xml new file mode 100644 index 0000000000..fdbbeeced2 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/testReferenceContext.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/testServiceContext.xml b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/testServiceContext.xml new file mode 100644 index 0000000000..6b3f1f9890 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/META-INF/sca/testServiceContext.xml @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/SpringHelloWorld-Imported-context.xml b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/SpringHelloWorld-Imported-context.xml new file mode 100644 index 0000000000..18ce21805c --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/SpringHelloWorld-Imported-context.xml @@ -0,0 +1,31 @@ + + + + + + + + + \ No newline at end of file diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringContextAccess.composite b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringContextAccess.composite new file mode 100644 index 0000000000..0b260b5dcf --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringContextAccess.composite @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitHelloWorld.composite b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitHelloWorld.composite new file mode 100644 index 0000000000..79f4041fe6 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitHelloWorld.composite @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitReference.composite b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitReference.composite new file mode 100644 index 0000000000..87353b69ea --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringExplicitReference.composite @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringHelloWorld.composite b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringHelloWorld.composite new file mode 100644 index 0000000000..ebb693d243 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringHelloWorld.composite @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImplicitReference.composite b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImplicitReference.composite new file mode 100644 index 0000000000..9f51277d22 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImplicitReference.composite @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImportHelloWorld.composite b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImportHelloWorld.composite new file mode 100644 index 0000000000..95dd9131eb --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringImportHelloWorld.composite @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringSCAProperty.composite b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringSCAProperty.composite new file mode 100644 index 0000000000..af1b3be0a5 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/org/apache/tuscany/sca/implementation/spring/itests/helloworld/SpringSCAProperty.composite @@ -0,0 +1,39 @@ + + + + + + + + + + + + + Hello + + + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/spring/META-INF/MANIFEST.MF b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/spring/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..950dbeba4c --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/spring/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Spring-Context: META-INF/spring/SpringSCAProperty-context.xml + diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/spring/META-INF/spring/SpringSCAProperty-context.xml b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/spring/META-INF/spring/SpringSCAProperty-context.xml new file mode 100644 index 0000000000..f1ee21686d --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/spring/META-INF/spring/SpringSCAProperty-context.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/test.xml b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/test.xml new file mode 100644 index 0000000000..f2d684f766 --- /dev/null +++ b/branches/sca-java-1.4/modules/implementation-spring/src/test/resources/test.xml @@ -0,0 +1,27 @@ + + + + + + + -- cgit v1.2.3