diff options
Diffstat (limited to '')
188 files changed, 15980 insertions, 0 deletions
diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/.ruleset b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/.ruleset new file mode 100644 index 0000000000..a1547fea92 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/.ruleset @@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<ruleset name="pmd-eclipse"> + <description>PMD Plugin preferences rule set</description> + + + <rule ref="rulesets/basic.xml/BooleanInstantiation"/> + <rule ref="rulesets/basic.xml/CollapsibleIfStatements"/> + <rule ref="rulesets/basic.xml/DoubleCheckedLocking"/> +<!--<rule ref="rulesets/basic.xml/EmptyCatchBlock"/>--> +<!--<rule ref="rulesets/basic.xml/EmptyFinallyBlock"/>--> +<!--<rule ref="rulesets/basic.xml/EmptyIfStmt"/>--> + <rule ref="rulesets/basic.xml/EmptyStatementNotInLoop"/> +<!--<rule ref="rulesets/basic.xml/EmptyStaticInitializer"/>--> +<!--<rule ref="rulesets/basic.xml/EmptySwitchStatements"/>--> +<!--<rule ref="rulesets/basic.xml/EmptySynchronizedBlock"/>--> +<!--<rule ref="rulesets/basic.xml/EmptyTryBlock"/>--> +<!--<rule ref="rulesets/basic.xml/EmptyWhileStmt"/>--> + <rule ref="rulesets/basic.xml/ForLoopShouldBeWhileLoop"/> + <rule ref="rulesets/basic.xml/JumbledIncrementer"/> +<!--<rule ref="rulesets/basic.xml/OverrideBothEqualsAndHashcode"/>--> + <rule ref="rulesets/basic.xml/ReturnFromFinallyBlock"/> + <rule ref="rulesets/basic.xml/UnconditionalIfStatement"/> + <rule ref="rulesets/basic.xml/UnnecessaryConversionTemporary"/> + <rule ref="rulesets/basic.xml/UnnecessaryFinalModifier"/> + <rule ref="rulesets/basic.xml/UnnecessaryReturn"/> +<!--<rule ref="rulesets/basic.xml/UselessOverridingMethod"/>--> + +<!--<rule ref="rulesets/braces.xml/ForLoopsMustUseBraces"/>--> +<!--<rule ref="rulesets/braces.xml/IfElseStmtsMustUseBraces"/>--> +<!--<rule ref="rulesets/braces.xml/IfStmtsMustUseBraces"/>--> +<!--<rule ref="rulesets/braces.xml/WhileLoopsMustUseBraces"/>--> + +<!--<rule ref="rulesets/clone.xml/CloneMethodMustImplementCloneable"/>--> +<!--<rule ref="rulesets/clone.xml/CloneThrowsCloneNotSupportedException"/>--> +<!--<rule ref="rulesets/clone.xml/ProperCloneImplementation"/>--> + +<!--<rule ref="rulesets/codesize.xml/CyclomaticComplexity"/>--> +<!--<rule ref="rulesets/codesize.xml/ExcessiveClassLength"/>--> +<!--<rule ref="rulesets/codesize.xml/ExcessiveMethodLength"/>--> +<!--<rule ref="rulesets/codesize.xml/ExcessiveParameterList"/>--> +<!--<rule ref="rulesets/codesize.xml/ExcessivePublicCount"/>--> +<!--<rule ref="rulesets/codesize.xml/TooManyFields"/>--> + +<!--<rule ref="rulesets/controversial.xml/AssignmentInOperand"/>--> +<!--<rule ref="rulesets/controversial.xml/AtLeastOneConstructor"/>--> +<!--<rule ref="rulesets/controversial.xml/CallSuperInConstructor"/>--> +<!--<rule ref="rulesets/controversial.xml/DontImportSun"/>--> +<!--<rule ref="rulesets/controversial.xml/NullAssignment"/>--> +<!--<rule ref="rulesets/controversial.xml/OnlyOneReturn"/>--> +<!--<rule ref="rulesets/controversial.xml/SingularField"/>--> +<!--<rule ref="rulesets/controversial.xml/SuspiciousOctalEscape"/>--> +<!--<rule ref="rulesets/controversial.xml/UnnecessaryConstructor"/>--> +<rule ref="rulesets/controversial.xml/UnnecessaryParentheses"/> +<!--<rule ref="rulesets/controversial.xml/UnusedModifier"/>--> + +<!--<rule ref="rulesets/coupling.xml/CouplingBetweenObjects"/>--> +<!--<rule ref="rulesets/coupling.xml/ExcessiveImports"/>--> +<!--<rule ref="rulesets/coupling.xml/LooseCoupling"/>--> + +<!--<rule ref="rulesets/design.xml/AbstractClassWithoutAbstractMethod"/>--> +<!--<rule ref="rulesets/design.xml/AccessorClassGeneration"/>--> +<!--<rule ref="rulesets/design.xml/AssignmentToNonFinalStatic"/>--> +<!--<rule ref="rulesets/design.xml/AvoidDeeplyNestedIfStmts"/>--> +<!--<rule ref="rulesets/design.xml/AvoidInstanceofChecksInCatchClause"/>--> +<rule ref="rulesets/design.xml/AvoidProtectedFieldInFinalClass"/> +<!--<rule ref="rulesets/design.xml/AvoidReassigningParameters"/>--> +<!--<rule ref="rulesets/design.xml/AvoidSynchronizedAtMethodLevel"/>--> +<!--<rule ref="rulesets/design.xml/BadComparison"/>--> +<!--<rule ref="rulesets/design.xml/CloseConnection"/>--> +<!--<rule ref="rulesets/design.xml/CompareObjectsWithEquals"/>--> +<!--<rule ref="rulesets/design.xml/ConfusingTernary"/>--> +<rule ref="rulesets/design.xml/ConstructorCallsOverridableMethod"/> +<!--<rule ref="rulesets/design.xml/DefaultLabelNotLastInSwitchStmt"/>--> +<!--<rule ref="rulesets/design.xml/FinalFieldCouldBeStatic"/>--> +<rule ref="rulesets/design.xml/IdempotentOperations"/> +<!--<rule ref="rulesets/design.xml/ImmutableField"/>--> +<!--<rule ref="rulesets/design.xml/InstantiationToGetClass"/>--> +<!--<rule ref="rulesets/design.xml/MissingBreakInSwitch"/>--> +<!--<rule ref="rulesets/design.xml/MissingStaticMethodInNonInstantiatableClass"/>--> +<!--<rule ref="rulesets/design.xml/NonCaseLabelInSwitchStatement"/>--> +<!--<rule ref="rulesets/design.xml/NonStaticInitializer"/>--> +<rule ref="rulesets/design.xml/OptimizableToArrayCall"/> +<rule ref="rulesets/design.xml/PositionLiteralsFirstInComparisons"/> +<rule ref="rulesets/design.xml/SimplifyBooleanExpressions"/> +<rule ref="rulesets/design.xml/SimplifyBooleanReturns"/> +<rule ref="rulesets/design.xml/SimplifyConditional"/> +<!--<rule ref="rulesets/design.xml/SwitchDensity"/>--> +<!--<rule ref="rulesets/design.xml/SwitchStmtsShouldHaveDefault"/>--> +<rule ref="rulesets/design.xml/UnnecessaryLocalBeforeReturn"/> +<!--<rule ref="rulesets/design.xml/UseLocaleWithCaseConversions"/>--> +<!--<rule ref="rulesets/design.xml/UseNotifyAllInsteadOfNotify"/>--> +<!--<rule ref="rulesets/design.xml/UseSingleton"/>--> + +<!--<rule ref="rulesets/finalizers.xml/EmptyFinalizer"/>--> +<!--<rule ref="rulesets/finalizers.xml/FinalizeOnlyCallsSuperFinalize"/>--> +<!--<rule ref="rulesets/finalizers.xml/FinalizeOverloaded"/>--> +<!--<rule ref="rulesets/finalizers.xml/FinalizeDoesNotCallSuperFinalize"/>--> +<!--<rule ref="rulesets/finalizers.xml/FinalizeShouldBeProtected"/>--> +<!--<rule ref="rulesets/finalizers.xml/AvoidCallingFinalize"/>--> + +<!--<rule ref="rulesets/imports.xml/DuplicateImports"/>--> +<!--<rule ref="rulesets/imports.xml/DontImportJavaLang"/>--> +<!--<rule ref="rulesets/imports.xml/UnusedImports"/>--> +<!--<rule ref="rulesets/imports.xml/ImportFromSamePackage"/>--> + +<!--<rule ref="rulesets/javabeans.xml/BeanMembersShouldSerialize"/>--> +<!--<rule ref="rulesets/javabeans.xml/MissingSerialVersionUID"/>--> + +<!--<rule ref="rulesets/junit.xml/JUnitStaticSuite"/>--> +<!--<rule ref="rulesets/junit.xml/JUnitSpelling"/>--> +<!--<rule ref="rulesets/junit.xml/JUnitAssertionsShouldIncludeMessage"/>--> +<!--<rule ref="rulesets/junit.xml/JUnitTestsShouldIncludeAssert"/>--> +<!--<rule ref="rulesets/junit.xml/TestClassWithoutTestCases"/>--> +<!--<rule ref="rulesets/junit.xml/UnnecessaryBooleanAssertion"/>--> +<!--<rule ref="rulesets/junit.xml/UseAssertEqualsInsteadOfAssertTrue"/>--> +<!--<rule ref="rulesets/junit.xml/UseAssertSameInsteadOfAssertTrue"/>--> + + <!--<rule ref="rulesets/logging-java.xml/AvoidPrintStackTrace"/>--> + <!--<rule ref="rulesets/logging-java.xml/LoggerIsNotStaticFinal"/>--> + <!--<rule ref="rulesets/logging-java.xml/MoreThanOneLogger"/>--> + <!--<rule ref="rulesets/logging-java.xml/LoggerIsNotStaticFinal"/>--> + <!--<rule ref="rulesets/logging-java.xml/LogBlockWithoutIf"/>--> + <!--<rule ref="rulesets/logging-java.xml/SystemPrintln"/>--> + <!--<rule ref="rulesets/logging-jakarta-commons.xml/UseCorrectExceptionLogging"/>--> + <!--<rule ref="rulesets/logging-jakarta-commons.xml/ProperLogger"/>--> + + <!--<rule ref="rulesets/naming.xml/ShortVariable"/>--> + <!--<rule ref="rulesets/naming.xml/LongVariable"/>--> + <!--<rule ref="rulesets/naming.xml/ShortMethodName"/>--> + <!--<rule ref="rulesets/naming.xml/VariableNamingConventions"/>--> + <!--<rule ref="rulesets/naming.xml/MethodNamingConventions"/>--> + <!--<rule ref="rulesets/naming.xml/ClassNamingConventions"/>--> + <!--<rule ref="rulesets/naming.xml/AbstractNaming"/>--> + <!--<rule ref="rulesets/naming.xml/AvoidDollarSigns"/>--> + <!--<rule ref="rulesets/naming.xml/MethodWithSameNameAsEnclosingClass"/>--> + <!--<rule ref="rulesets/naming.xml/SuspiciousHashcodeMethodName"/>--> + <!--<rule ref="rulesets/naming.xml/SuspiciousConstantFieldName"/>--> + <!--<rule ref="rulesets/naming.xml/AvoidFieldNameMatchingTypeName"/>--> + <!--<rule ref="rulesets/naming.xml/AvoidFieldNameMatchingMethodName"/>--> + <!--<rule ref="rulesets/naming.xml/AvoidNonConstructorMethodsWithClassName"/>--> + <!--<rule ref="rulesets/naming.xml/NoPackage"/>--> + <!--<rule ref="rulesets/naming.xml/PackageCase"/>--> + + <!--<rule ref="rulesets/optimizations.xml/LocalVariableCouldBeFinal"/>--> + <!--<rule ref="rulesets/optimizations.xml/MethodArgumentCouldBeFinal"/>--> + <!--<rule ref="rulesets/optimizations.xml/AvoidInstantiatingObjectsInLoops"/>--> + <!--<rule ref="rulesets/optimizations.xml/UseArrayListInsteadOfVector"/>--> + <!--<rule ref="rulesets/optimizations.xml/SimplifyStartsWith"/>--> + <!--<rule ref="rulesets/optimizations.xml/UseStringBufferForStringAppends"/>--> + + <!--<rule ref="rulesets/strictexception.xml/AvoidCatchingThrowable"/>--> + <!--<rule ref="rulesets/strictexception.xml/SignatureDeclareThrowsException"/>--> + <!--<rule ref="rulesets/strictexception.xml/ExceptionAsFlowControl"/>--> + <!--<rule ref="rulesets/strictexception.xml/AvoidCatchingNPE"/>--> + <!--<rule ref="rulesets/strictexception.xml/AvoidThrowingRawExceptionTypes"/>--> + <!--<rule ref="rulesets/strictexception.xml/AvoidThrowingNullPointerException"/>--> + + <!--<rule ref="rulesets/strings.xml/AvoidDuplicateLiterals"/>--> + <!--<rule ref="rulesets/strings.xml/StringInstantiation"/>--> + <!--<rule ref="rulesets/strings.xml/StringToString"/>--> + <!--<rule ref="rulesets/strings.xml/AvoidConcatenatingNonLiteralsInStringBuffer"/>--> + <!--<rule ref="rulesets/strings.xml/UnnecessaryCaseChange"/>--> + + <!--<rule ref="rulesets/sunsecure.xml/MethodReturnsInternalArray"/>--> + <!--<rule ref="rulesets/sunsecure.xml/ArrayIsStoredDirectly"/>--> + + <rule ref="rulesets/unusedcode.xml/UnusedLocalVariable"/> + <rule ref="rulesets/unusedcode.xml/UnusedPrivateField"/> + <rule ref="rulesets/unusedcode.xml/UnusedPrivateMethod"/> + <!--<rule ref="rulesets/unusedcode.xml/UnusedFormalParameter"/>--> + +</ruleset> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/LICENSE.txt b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/LICENSE.txt new file mode 100644 index 0000000000..0084319535 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/LICENSE.txt @@ -0,0 +1,202 @@ + + 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, serviceDefinition 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/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/NOTICE.txt b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/NOTICE.txt new file mode 100644 index 0000000000..d83ebbe236 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/NOTICE.txt @@ -0,0 +1,14 @@ +${pom.name} +Copyright (c) 2005 - 2006 The Apache Software Foundation + +Apache Tuscany is an effort undergoing incubation at The Apache Software +Foundation (ASF), sponsored by the Apache Web Services PMC. Incubation is +required of all newly accepted projects until a further review indicates that +the infrastructure, communications, and decision making process have stabilized +in a manner consistent with other successful ASF projects. While incubation +status is not necessarily a reflection of the completeness or stability of the +code, it does indicate that the project has yet to be fully endorsed by the ASF. + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/pom.xml b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/pom.xml new file mode 100644 index 0000000000..b0557df456 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/pom.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<project> + + <parent> + <groupId>org.apache.tuscany.sca.services.containers</groupId> + <artifactId>parent</artifactId> + <version>1.0-incubator-M2</version> + </parent> + + <modelVersion>4.0.0</modelVersion> + <artifactId>groovy</artifactId> + <name>Apache Tuscany Groovy Container</name> + <description>Apache Tuscany Groovy Container</description> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca.kernel</groupId> + <artifactId>tuscany-spi</artifactId> + <version>${sca.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>groovy</groupId> + <artifactId>groovy</artifactId> + <version>1.0-jsr-05</version> + <scope>provided</scope> + <exclusions> + <exclusion> + <groupId>cglib</groupId> + <artifactId>cglib-full</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>xpp3</groupId> + <artifactId>xpp3</artifactId> + <version>1.1.3.4-RC8</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>test</artifactId> + <version>${sca.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + </dependency> + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymockclassextension</artifactId> + </dependency> + </dependencies> + +</project> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncGroovyInvoker.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncGroovyInvoker.java new file mode 100644 index 0000000000..f761122847 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncGroovyInvoker.java @@ -0,0 +1,92 @@ +/* + * 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.container.groovy; + +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; + +/** + * Responsible for performing a non-blocking dispatch on a Groovy component implementation instance + * + * @version $Rev$ $Date$ + */ +public class AsyncGroovyInvoker extends GroovyInvoker { + + private InboundWire wire; + private AsyncMonitor monitor; + private WorkContext workContext; + private Object target; + + /** + * Creates a new invoker + * + * @param operation the operation the invoker is associated with + * @param wire + * @param component the target component + * @param monitor the monitor to pass events to + * @param workContext + */ + public AsyncGroovyInvoker(String operation, + InboundWire wire, + GroovyAtomicComponent component, + AsyncMonitor monitor, + WorkContext workContext) { + super(operation, component); + this.wire = wire; + this.monitor = monitor; + this.workContext = workContext; + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + Object messageId = msg.getMessageId(); + wire.addMapping(messageId, msg.getFromAddress()); + workContext.setCurrentMessageId(null); + workContext.setCurrentCorrelationId(messageId); + invokeTarget(msg.getBody()); + // async so no return value + return null; + } catch (Throwable e) { + // FIXME need to log exceptions + monitor.executionError(e); + return null; + } + } + + public AsyncGroovyInvoker clone() throws CloneNotSupportedException { + return (AsyncGroovyInvoker) super.clone(); + } + + /** + * Resolves the target service instance or returns a cached one + */ + protected Object getInstance() throws TargetException { + if (!cacheable) { + return component.getTargetInstance(); + } else { + if (target == null) { + target = component.getTargetInstance(); + } + return target; + } + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncMonitor.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncMonitor.java new file mode 100644 index 0000000000..4da5538990 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/AsyncMonitor.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.container.groovy; + +/** + * A monitor used to log events during non-blocking invocations + * <p/> + * + * @version $$Rev$$ $$Date$$ + */ +public interface AsyncMonitor { + + /** + * Logs an exception thrown during an invocation + */ + void executionError(Throwable e); + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyAtomicComponent.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyAtomicComponent.java new file mode 100644 index 0000000000..b0ed18382f --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyAtomicComponent.java @@ -0,0 +1,120 @@ +/* + * 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.container.groovy; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.extension.AtomicComponentExtension; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.TargetInvoker; + +import groovy.lang.GroovyObject; + +/** + * The Groovy atomic component implementation. Groovy implementations may be "scripts" or classes. + */ +public class GroovyAtomicComponent extends AtomicComponentExtension { + private final Class<? extends GroovyObject> groovyClass; + private final List<Class<?>> services; + //FIXME properties should move up to AtomicComponentExtension + private final Map<String, ObjectFactory> properties; + private AsyncMonitor monitor; + + public GroovyAtomicComponent(GroovyConfiguration configuration, AsyncMonitor monitor) { + super(configuration.getName(), + configuration.getParent(), + configuration.getScopeContainer(), + configuration.getWireService(), + configuration.getWorkContext(), + null, configuration.getInitLevel()); + + this.groovyClass = configuration.getGroovyClass(); + this.services = Collections.unmodifiableList(configuration.getServices()); + this.properties = new HashMap<String, ObjectFactory>(); + assert groovyClass != null; + this.monitor = monitor; + } + + public List<Class<?>> getServiceInterfaces() { + return services; + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) { + return new GroovyInvoker(operation.getName(), this); + } + + public TargetInvoker createAsyncTargetInvoker(InboundWire wire, Operation operation) { + return new AsyncGroovyInvoker(operation.getName(), wire, this, monitor, workContext); + } + + public Object createInstance() throws ObjectCreationException { + GroovyObject instance; + try { + instance = groovyClass.newInstance(); + } catch (IllegalAccessException e) { + throw new ObjectCreationException(e); + } catch (InstantiationException e) { + throw new ObjectCreationException(e); + } + + // inject properties + for (Map.Entry<String, ObjectFactory> property : properties.entrySet()) { + instance.setProperty(property.getKey(), property.getValue().getInstance()); + } + + // inject references + for (List<OutboundWire> referenceWires : getOutboundWires().values()) { + for (OutboundWire wire : referenceWires) { + instance.setProperty(wire.getReferenceName(), wireService.createProxy(wire)); + } + } + return instance; + } + + public GroovyObject getTargetInstance() throws TargetException { + return (GroovyObject) scopeContainer.getInstance(this); + } + + public Object getServiceInstance() throws TargetException { + //TODO this should return a default service from a wire + return scopeContainer.getInstance(this); + } + + public Object getServiceInstance(String service) throws TargetException { + InboundWire wire = getInboundWire(service); + if (wire == null) { + TargetException e = new TargetException("ServiceDefinition not found"); // TODO better error message + e.setIdentifier(service); + throw e; + } + return wireService.createProxy(wire); + } + + public void addPropertyFactory(String name, ObjectFactory<?> factory) { + properties.put(name, factory); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentBuilder.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentBuilder.java new file mode 100644 index 0000000000..4e99b888da --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentBuilder.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.container.groovy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.builder.BuilderConfigException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentBuilderExtension; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import groovy.lang.GroovyClassLoader; +import groovy.lang.GroovyObject; +import org.codehaus.groovy.control.CompilationFailedException; + +/** + * Extension point for creating {@link GroovyAtomicComponent}s from an assembly configuration + * + * @version $$Rev$$ $$Date$$ + */ +public class GroovyComponentBuilder extends ComponentBuilderExtension<GroovyImplementation> { + + protected Class<GroovyImplementation> getImplementationType() { + return GroovyImplementation.class; + } + + public Component build(CompositeComponent parent, + ComponentDefinition<GroovyImplementation> componentDefinition, + DeploymentContext deploymentContext) + throws BuilderConfigException { + + String name = componentDefinition.getName(); + GroovyImplementation implementation = componentDefinition.getImplementation(); + GroovyComponentType componentType = implementation.getComponentType(); + + int initLevel = componentType.getInitLevel(); + + // get list of services provided by this component + Collection<ServiceDefinition> collection = componentType.getServices().values(); + List<Class<?>> services = new ArrayList<Class<?>>(collection.size()); + for (ServiceDefinition serviceDefinition : collection) { + services.add(serviceDefinition.getServiceContract().getInterfaceClass()); + } + + // get the Groovy classloader for this deployment component + GroovyClassLoader groovyClassLoader = (GroovyClassLoader) deploymentContext.getExtension("groovy.classloader"); + if (groovyClassLoader == null) { + groovyClassLoader = new GroovyClassLoader(deploymentContext.getClassLoader()); + deploymentContext.putExtension("groovy.classloader", groovyClassLoader); + } + + // create the implementation class for the script + Class<? extends GroovyObject> groovyClass; + try { + String script = implementation.getScript(); + // REVIEW JFM can we cache the class? + groovyClass = groovyClassLoader.parseClass(script); + } catch (CompilationFailedException e) { + BuilderConfigException bce = new BuilderConfigException(e); + bce.setIdentifier(name); + throw bce; + } + // TODO deal with init and destroy + + GroovyConfiguration configuration = new GroovyConfiguration(); + configuration.setName(name); + configuration.setGroovyClass(groovyClass); + configuration.setParent(parent); + // get the scope container for this component's scope + Scope scope = componentType.getLifecycleScope(); + if (Scope.MODULE == scope) { + configuration.setScopeContainer(deploymentContext.getModuleScope()); + } else { + configuration.setScopeContainer(scopeRegistry.getScopeContainer(scope)); + } + + + configuration.setWireService(wireService); + configuration.setWorkContext(workContext); + configuration.setInitLevel(initLevel); + configuration.setServices(services); + GroovyAtomicComponent component = new GroovyAtomicComponent(configuration, null); + + // handle properties + for (Property<?> property : componentType.getProperties().values()) { + ObjectFactory<?> factory = property.getDefaultValueFactory(); + if (factory != null) { + component.addPropertyFactory(property.getName(), factory); + } + } + return component; + } + + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentType.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentType.java new file mode 100644 index 0000000000..bd54371fd7 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentType.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.container.groovy; + +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * Model object representing a Groovy component type + * + * @version $$Rev$$ $$Date$$ + */ +public class GroovyComponentType extends ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> { + private Scope lifecycleScope; + + public Scope getLifecycleScope() { + return lifecycleScope; + } + + public void setLifecycleScope(Scope lifecycleScope) { + this.lifecycleScope = lifecycleScope; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoader.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoader.java new file mode 100644 index 0000000000..6da7840fdb --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoader.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.container.groovy; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.model.Scope; + +/** + * @version $Rev$ $Date$ + */ +public class GroovyComponentTypeLoader extends ComponentTypeLoaderExtension<GroovyImplementation> { + protected Class<GroovyImplementation> getImplementationClass() { + return GroovyImplementation.class; + } + + public void load(CompositeComponent parent, GroovyImplementation implementation, DeploymentContext context) + throws LoaderException { + GroovyComponentType componentType = new GroovyComponentType(); + // for now, default to module + componentType.setLifecycleScope(Scope.MODULE); + implementation.setComponentType(componentType); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyConfiguration.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyConfiguration.java new file mode 100644 index 0000000000..b9ede2d034 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyConfiguration.java @@ -0,0 +1,150 @@ +/* + * 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.container.groovy; + +import java.lang.reflect.Member; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.wire.WireService; + +import groovy.lang.GroovyObject; + +/** + * Encapsulates confuration for a Groovy-based atomic component + * + * @version $Rev$ $Date$ + */ +public class GroovyConfiguration { + + private CompositeComponent parent; + private ScopeContainer scopeContainer; + private int initLevel; + private Map<String, Member> referenceSites = new HashMap<String, Member>(); + private Map<String, Member> propertySites = new HashMap<String, Member>(); + private Map<String, Member> callbackSites = new HashMap<String, Member>(); + private List<Class<?>> serviceInterfaces = new ArrayList<Class<?>>(); + private WireService wireService; + private WorkContext workContext; + private String name; + private Class<? extends GroovyObject> groovyClass; + private List<Class<?>> services; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Class<? extends GroovyObject> getGroovyClass() { + return groovyClass; + } + + public void setGroovyClass(Class<? extends GroovyObject> groovyClass) { + this.groovyClass = groovyClass; + } + + public CompositeComponent getParent() { + return parent; + } + + public void setParent(CompositeComponent parent) { + this.parent = parent; + } + + public ScopeContainer getScopeContainer() { + return scopeContainer; + } + + public void setScopeContainer(ScopeContainer scopeContainer) { + this.scopeContainer = scopeContainer; + } + + public List<Class<?>> getServiceInterfaces() { + return serviceInterfaces; + } + + public void addServiceInterface(Class<?> serviceInterface) { + serviceInterfaces.add(serviceInterface); + } + + public int getInitLevel() { + return initLevel; + } + + public void setInitLevel(int initLevel) { + this.initLevel = initLevel; + } + + public List<Class<?>> getServices() { + return services; + } + + public void setServices(List<Class<?>> services) { + this.services = services; + } + + public Map<String, Member> getReferenceSite() { + return referenceSites; + } + + public void addReferenceSite(String name, Member member) { + referenceSites.put(name, member); + } + + public Map<String, Member> getCallbackSite() { + return callbackSites; + } + + public void addCallbackSite(String name, Member member) { + callbackSites.put(name, member); + } + + public Map<String, Member> getPropertySites() { + return propertySites; + } + + public void addPropertySite(String name, Member member) { + propertySites.put(name, member); + } + + public WireService getWireService() { + return wireService; + } + + public void setWireService(WireService wireService) { + this.wireService = wireService; + } + + public WorkContext getWorkContext() { + return workContext; + } + + public void setWorkContext(WorkContext workContext) { + this.workContext = workContext; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyImplementation.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyImplementation.java new file mode 100644 index 0000000000..96b4a3bc2d --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyImplementation.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.container.groovy; + +import org.apache.tuscany.spi.model.AtomicImplementation; + +/** + * Model object for a Groovy implementation. + */ +public class GroovyImplementation extends AtomicImplementation<GroovyComponentType> { + + //the Groovy source to be executed + private String script; + + /** + * Returns the Groovy source to be executed. + */ + public String getScript() { + return script; + } + + /** + * Sets the Groovy source to be executed. + */ + public void setScript(String script) { + this.script = script; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyInvoker.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyInvoker.java new file mode 100644 index 0000000000..b6fdbbb0b6 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/GroovyInvoker.java @@ -0,0 +1,87 @@ +/* + * 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.container.groovy; + +import java.lang.reflect.InvocationTargetException; + +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; + +import groovy.lang.GroovyObject; + +/** + * Dispatches to a Groovy implementation instance + * + * @version $$Rev$$ $$Date$$ + */ +public class GroovyInvoker implements TargetInvoker, Cloneable { + + protected GroovyAtomicComponent component; + protected String operation; + protected boolean cacheable; + + public GroovyInvoker(String operation, GroovyAtomicComponent context) { + this.component = context; + this.operation = operation; + } + + public boolean isCacheable() { + return cacheable; + } + + public void setCacheable(boolean cacheable) { + this.cacheable = cacheable; + } + + public boolean isOptimizable() { + return false; + } + + /** + * Dispatches to the the target. + */ + public Object invokeTarget(final Object payload) throws InvocationTargetException { + GroovyObject target = component.getTargetInstance(); + Object[] args = (Object[]) payload; + try { + return target.invokeMethod(operation, args); + } catch (Exception ex) { + throw new InvocationTargetException(ex); + } + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + Object resp = invokeTarget(msg.getBody()); + msg.setBody(resp); + } catch (InvocationTargetException e) { + msg.setBodyWithFault(e.getCause()); + } catch (Throwable e) { + msg.setBodyWithFault(e); + } + return msg; + } + + public GroovyInvoker clone() throws CloneNotSupportedException { + return (GroovyInvoker) super.clone(); + } + + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/ImplementationLoader.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/ImplementationLoader.java new file mode 100644 index 0000000000..da93abbd9d --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/java/org/apache/tuscany/container/groovy/ImplementationLoader.java @@ -0,0 +1,110 @@ +/* + * 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.container.groovy; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.LoaderExtension; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.LoaderUtil; +import org.apache.tuscany.spi.loader.MissingResourceException; + +/** + * Loader for handling <groovy:implementation> elements. + * + * @version $Rev$ $Date$ + */ +public class ImplementationLoader extends LoaderExtension<GroovyImplementation> { + private static final QName IMPLEMENTATION_GROOVY = + new QName("http://incubator.apache.org/tuscany/xmlns/container/groovy/1.0-incubator-M2", "implementation.groovy"); + + public ImplementationLoader(@Autowire LoaderRegistry registry) { + super(registry); + } + + public QName getXMLType() { + return IMPLEMENTATION_GROOVY; + } + + public GroovyImplementation load(CompositeComponent parent, + XMLStreamReader reader, + DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException { + + String script = reader.getAttributeValue(null, "script"); + if (script == null) { + throw new MissingResourceException("No script supplied"); + } + String source = loadSource(deploymentContext.getClassLoader(), script); + + LoaderUtil.skipToEndElement(reader); + + GroovyImplementation implementation = new GroovyImplementation(); + implementation.setScript(source); + // no component type support + //registry.loadComponentType(parent, implementation, deploymentContext); + return implementation; + } + + protected String loadSource(ClassLoader cl, String resource) throws LoaderException { + URL url = cl.getResource(resource); + if (url == null) { + throw new MissingResourceException(resource); + } + InputStream is; + try { + is = url.openStream(); + } catch (IOException e) { + MissingResourceException mre = new MissingResourceException(resource, e); + mre.setIdentifier(resource); + throw mre; + } + try { + Reader reader = new InputStreamReader(is, "UTF-8"); + char[] buffer = new char[1024]; + StringBuilder source = new StringBuilder(); + int count; + while ((count = reader.read(buffer)) > 0) { + source.append(buffer, 0, count); + } + return source.toString(); + } catch (IOException e) { + LoaderException le = new LoaderException(e); + le.setIdentifier(resource); + throw le; + } finally { + try { + is.close(); + } catch (IOException e) { + // ignore + } + } + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/resources/META-INF/sca/groovy.system.scdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/resources/META-INF/sca/groovy.system.scdl new file mode 100644 index 0000000000..24fbfd5e25 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/main/resources/META-INF/sca/groovy.system.scdl @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. + --> +<!-- + JavaScript configuration for the launcher environment. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://incubator.apache.org/tuscany/xmlns/system/1.0-incubator-M2" + + name="groovy.extension"> + + <component name="GroovyLoader"> + <system:implementation.system class="org.apache.tuscany.container.groovy.ImplementationLoader"/> + </component> + + <component name="GroovyComponentTypeLoader"> + <system:implementation.system class="org.apache.tuscany.container.groovy.GroovyComponentTypeLoader"/> + </component> + + <component name="GroovyBuilder"> + <system:implementation.system class="org.apache.tuscany.container.groovy.GroovyComponentBuilder"/> + </component> + +</composite>
\ No newline at end of file diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/AsyncInvokerTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/AsyncInvokerTestCase.java new file mode 100644 index 0000000000..a27bb25484 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/AsyncInvokerTestCase.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.container.groovy; + +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.services.work.WorkScheduler; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; + +import groovy.lang.GroovyObject; +import junit.framework.TestCase; +import org.apache.tuscany.container.groovy.mock.AsyncTarget; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.getCurrentArguments; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import org.easymock.IAnswer; +import org.easymock.classextension.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class AsyncInvokerTestCase extends TestCase { + + public void testInvoke() throws Exception { + GroovyObject instance = createMock(GroovyObject.class); + expect(instance.invokeMethod("invoke", null)).andReturn(null).once(); + replay(instance); + GroovyAtomicComponent component = EasyMock.createMock(GroovyAtomicComponent.class); + expect(component.getTargetInstance()).andReturn(instance); + EasyMock.replay(component); + AsyncMonitor monitor = createMock(AsyncMonitor.class); + replay(monitor); + + WorkScheduler scheduler = createMock(WorkScheduler.class); + scheduler.scheduleWork(isA(Runnable.class)); + expectLastCall().andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + Runnable runnable = (Runnable) getCurrentArguments()[0]; + runnable.run(); + return null; + } + }); + replay(scheduler); + WorkContext context = createMock(WorkContext.class); + Method method = AsyncTarget.class.getMethod("invoke"); + method.setAccessible(true); + InboundWire wire = createMock(InboundWire.class); + AsyncGroovyInvoker invoker = new AsyncGroovyInvoker("invoke", wire, component, monitor, context); + Message msg = new MessageImpl(); + invoker.invoke(msg); + verify(instance); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoaderTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoaderTestCase.java new file mode 100644 index 0000000000..bfff4bdef7 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/GroovyComponentTypeLoaderTestCase.java @@ -0,0 +1,37 @@ +/* + * 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.container.groovy; + +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class GroovyComponentTypeLoaderTestCase extends TestCase { + + public void testLoad() throws Exception { + GroovyComponentTypeLoader loader = new GroovyComponentTypeLoader(); + GroovyImplementation impl = new GroovyImplementation(); + loader.load(null, impl, null); + GroovyComponentType type = impl.getComponentType(); + assertEquals(Scope.MODULE, type.getLifecycleScope()); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ImplementationLoaderTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ImplementationLoaderTestCase.java new file mode 100644 index 0000000000..2af0611757 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ImplementationLoaderTestCase.java @@ -0,0 +1,102 @@ +/* + * 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.container.groovy; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.MissingResourceException; + +import junit.framework.TestCase; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.expect; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; + +/** + * @version $Rev$ $Date$ + */ +public class ImplementationLoaderTestCase extends TestCase { + private CompositeComponent parent; + private XMLStreamReader reader; + private DeploymentContext deploymentContext; + private ClassLoader classLoader; + private LoaderRegistry registry; + private ImplementationLoader loader; + + public void testNoScriptAttribute() throws LoaderException, XMLStreamException { + expect(reader.getAttributeValue(null, "script")).andReturn(null); + replay(reader); + replay(deploymentContext); + + try { + loader.load(parent, reader, deploymentContext); + fail(); + } catch (MissingResourceException e) { + // ok + } + verify(reader); + verify(deploymentContext); + } + + public void testNoScriptPresent() throws LoaderException, XMLStreamException { + expect(reader.getAttributeValue(null, "script")).andReturn("foo.groovy"); + expect(deploymentContext.getClassLoader()).andReturn(classLoader); + + replay(reader); + replay(deploymentContext); + + ImplementationLoader mockLoader = new ImplementationLoader(registry) { + protected String loadSource(ClassLoader cl, String resource) throws LoaderException { + assertSame(classLoader, cl); + assertEquals("foo.groovy", resource); + throw new MissingResourceException(resource); + } + }; + try { + mockLoader.load(parent, reader, deploymentContext); + fail(); + } catch (MissingResourceException e) { + assertEquals("foo.groovy", e.getMessage()); + } + verify(reader); + verify(deploymentContext); + } + + public void testLoadScript() throws LoaderException { + String script = loader.loadSource(getClass().getClassLoader(), + "org/apache/tuscany/container/groovy/mock/TestScript.groovy"); + assertEquals("Test Script", script); + } + + protected void setUp() throws Exception { + super.setUp(); + registry = createMock(LoaderRegistry.class); + loader = new ImplementationLoader(registry); + + parent = createMock(CompositeComponent.class); + reader = createMock(XMLStreamReader.class); + deploymentContext = createMock(DeploymentContext.class); + classLoader = createMock(ClassLoader.class); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/PropertyTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/PropertyTestCase.java new file mode 100644 index 0000000000..9b828db7eb --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/PropertyTestCase.java @@ -0,0 +1,90 @@ +/* + * 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.container.groovy; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; + +import groovy.lang.GroovyClassLoader; +import groovy.lang.GroovyObject; +import junit.framework.TestCase; +import org.apache.tuscany.container.groovy.mock.Greeting; +import static org.apache.tuscany.test.ArtifactFactory.createWireService; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.getCurrentArguments; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; +import org.easymock.IAnswer; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class PropertyTestCase extends TestCase { + + private static final String SCRIPT = "import org.apache.tuscany.container.groovy.mock.Greeting;" + + "class Foo implements Greeting{" + + " String property;" + + " public String greet(String name){" + + " return property; " + + " }" + + "}"; + + private ScopeContainer scopeContainer; + private Class<? extends GroovyObject> implClass; + + /** + * Tests injecting a simple property type on a Groovy implementation instance + */ + public void testPropertyInjection() throws Exception { + List<Class<?>> services = new ArrayList<Class<?>>(); + services.add(Greeting.class); + GroovyConfiguration configuration = new GroovyConfiguration(); + configuration.setName("source"); + configuration.setGroovyClass(implClass); + configuration.setServices(services); + configuration.setScopeContainer(scopeContainer); + configuration.setWireService(createWireService()); + GroovyAtomicComponent component = new GroovyAtomicComponent(configuration, null); + ObjectFactory<?> factory = createMock(ObjectFactory.class); + expect((String) factory.getInstance()).andReturn("bar"); + replay(factory); + component.addPropertyFactory("property", factory); + Greeting greeting = (Greeting) component.getServiceInstance(); + assertEquals("bar", greeting.greet("foo")); + } + + @SuppressWarnings("unchecked") + protected void setUp() throws Exception { + super.setUp(); + GroovyClassLoader cl = new GroovyClassLoader(getClass().getClassLoader()); + implClass = cl.parseClass(SCRIPT); + scopeContainer = createMock(ScopeContainer.class); + expect(scopeContainer.getInstance(isA(AtomicComponent.class))).andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + return ((AtomicComponent) getCurrentArguments()[0]).createInstance(); + } + }); + replay(scopeContainer); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ScriptInvokeTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ScriptInvokeTestCase.java new file mode 100644 index 0000000000..f0ae7deb33 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/ScriptInvokeTestCase.java @@ -0,0 +1,79 @@ +/* + * 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.container.groovy; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; + +import groovy.lang.GroovyClassLoader; +import groovy.lang.GroovyObject; +import junit.framework.TestCase; +import org.apache.tuscany.container.groovy.mock.Greeting; +import static org.apache.tuscany.test.ArtifactFactory.createWireService; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.getCurrentArguments; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; +import org.easymock.IAnswer; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class ScriptInvokeTestCase extends TestCase { + + private static final String SCRIPT = "def greet(name) { return name }"; + + private Class<? extends GroovyObject> implClass; + private ScopeContainer scopeContainer; + + /** + * Tests the invocation of a Groovy "script" as opposed to a class + */ + public void testBasicScriptInvocation() throws Exception { + List<Class<?>> services = new ArrayList<Class<?>>(); + services.add(Greeting.class); + GroovyConfiguration configuration = new GroovyConfiguration(); + configuration.setName("source"); + configuration.setGroovyClass(implClass); + configuration.setServices(services); + configuration.setScopeContainer(scopeContainer); + configuration.setWireService(createWireService()); + GroovyAtomicComponent context = new GroovyAtomicComponent(configuration, null); + GroovyObject object = (GroovyObject) context.getServiceInstance(); + assertEquals("foo", object.invokeMethod("greet", "foo")); + } + + @SuppressWarnings("unchecked") + protected void setUp() throws Exception { + super.setUp(); + GroovyClassLoader cl = new GroovyClassLoader(getClass().getClassLoader()); + implClass = cl.parseClass(SCRIPT); + scopeContainer = createMock(ScopeContainer.class); + expect(scopeContainer.getInstance(isA(AtomicComponent.class))).andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + return ((AtomicComponent) getCurrentArguments()[0]).createInstance(); + } + }); + replay(scopeContainer); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/WireTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/WireTestCase.java new file mode 100644 index 0000000000..79f37f514c --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/WireTestCase.java @@ -0,0 +1,189 @@ +/* + * 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.container.groovy; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InboundInvocationChain; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.OutboundInvocationChain; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.TargetInvoker; + +import groovy.lang.GroovyClassLoader; +import groovy.lang.GroovyObject; +import junit.framework.TestCase; +import org.apache.tuscany.container.groovy.mock.Greeting; +import static org.apache.tuscany.test.ArtifactFactory.createInboundWire; +import static org.apache.tuscany.test.ArtifactFactory.createOutboundWire; +import static org.apache.tuscany.test.ArtifactFactory.createWireService; +import static org.apache.tuscany.test.ArtifactFactory.terminateWire; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.getCurrentArguments; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.reportMatcher; +import static org.easymock.EasyMock.verify; +import org.easymock.IAnswer; +import org.easymock.IArgumentMatcher; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class WireTestCase extends TestCase { + + private static final String SCRIPT = "import org.apache.tuscany.container.groovy.mock.Greeting;" + + "class Foo implements Greeting{" + + " Greeting wire;" + + " " + + " void setWire(Greeting ref){" + + " wire = ref;" + + " };" + + " " + + " String greet(String name){" + + " return wire.greet(name); " + + " };" + + "}"; + + private static final String SCRIPT2 = "import org.apache.tuscany.container.groovy.mock.Greeting;" + + "class Foo implements Greeting{" + + " public String greet(String name){" + + " return name; " + + " }" + + "}"; + + private Class<? extends GroovyObject> implClass1; + private Class<? extends GroovyObject> implClass2; + private ScopeContainer scopeContainer; + + /** + * Tests a basic invocation down a source wire + */ + public void testReferenceWireInvocation() throws Exception { + List<Class<?>> services = new ArrayList<Class<?>>(); + services.add(Greeting.class); + GroovyConfiguration configuration = new GroovyConfiguration(); + configuration.setName("source"); + configuration.setGroovyClass(implClass1); + configuration.setServices(services); + configuration.setScopeContainer(scopeContainer); + configuration.setWireService(createWireService()); + GroovyAtomicComponent component = new GroovyAtomicComponent(configuration, null); + OutboundWire wire = createOutboundWire("wire", Greeting.class); + terminateWire(wire); + + TargetInvoker invoker = createMock(TargetInvoker.class); + expect(invoker.isCacheable()).andReturn(false); + Message response = new MessageImpl(); + response.setBody("foo"); + expect(invoker.invoke(eqMessage())).andReturn(response); + replay(invoker); + + for (OutboundInvocationChain chain : wire.getInvocationChains().values()) { + chain.setTargetInvoker(invoker); + } + component.addOutboundWire(wire); + Greeting greeting = (Greeting) component.getServiceInstance(); + assertEquals("foo", greeting.greet("foo")); + verify(invoker); + } + + // todo this could be generalized and moved to test module + public static Message eqMessage() { + reportMatcher(new IArgumentMatcher() { + public boolean matches(Object object) { + if (!(object instanceof Message)) { + return false; + } + final Message msg = (Message) object; + Object[] body = (Object[]) msg.getBody(); + return "foo".equals(body[0]); + } + + public void appendTo(StringBuffer stringBuffer) { + } + }); + return null; + } + + + /** + * Tests a basic invocation to a target + */ + public void testTargetInvocation() throws Exception { + List<Class<?>> services = new ArrayList<Class<?>>(); + services.add(Greeting.class); + GroovyConfiguration configuration = new GroovyConfiguration(); + configuration.setName("source"); + configuration.setGroovyClass(implClass2); + configuration.setServices(services); + configuration.setScopeContainer(scopeContainer); + configuration.setWireService(createWireService()); + GroovyAtomicComponent component = new GroovyAtomicComponent(configuration, null); + Operation<Type> operation = new Operation<Type>("greet", null, null, null, false, null); + TargetInvoker invoker = component.createTargetInvoker(null, operation); + assertEquals("foo", invoker.invokeTarget(new String[]{"foo"})); + } + + + /** + * Tests a basic invocation down a target wire + */ + public void testTargetWireInvocation() throws Exception { + List<Class<?>> services = new ArrayList<Class<?>>(); + services.add(Greeting.class); + GroovyConfiguration configuration = new GroovyConfiguration(); + configuration.setName("source"); + configuration.setGroovyClass(implClass2); + configuration.setServices(services); + configuration.setScopeContainer(scopeContainer); + configuration.setWireService(createWireService()); + GroovyAtomicComponent component = new GroovyAtomicComponent(configuration, null); + InboundWire wire = createInboundWire("Greeting", Greeting.class); + terminateWire(wire); + for (InboundInvocationChain chain : wire.getInvocationChains().values()) { + chain.setTargetInvoker(component.createTargetInvoker(null, chain.getOperation())); + } + component.addInboundWire(wire); + Greeting greeting = (Greeting) component.getServiceInstance("Greeting"); + assertEquals("foo", greeting.greet("foo")); + } + + protected void setUp() throws Exception { + super.setUp(); + GroovyClassLoader cl = new GroovyClassLoader(getClass().getClassLoader()); + implClass1 = cl.parseClass(SCRIPT); + implClass2 = cl.parseClass(SCRIPT2); + scopeContainer = createMock(ScopeContainer.class); + expect(scopeContainer.getInstance(isA(AtomicComponent.class))).andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + return ((AtomicComponent) getCurrentArguments()[0]).createInstance(); + } + }); + replay(scopeContainer); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/AsyncTarget.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/AsyncTarget.java new file mode 100644 index 0000000000..8918c3dfd5 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/AsyncTarget.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.container.groovy.mock; + +/** + * @version $Rev$ $Date$ + */ +public interface AsyncTarget { + + void invoke(); +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/Greeting.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/Greeting.java new file mode 100644 index 0000000000..b975491f16 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/java/org/apache/tuscany/container/groovy/mock/Greeting.java @@ -0,0 +1,25 @@ +/* + * 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.container.groovy.mock; + +public interface Greeting { + + String setWire(Greeting ref); + String greet(String name); +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/resources/META-INF/sca/default.scdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/resources/META-INF/sca/default.scdl new file mode 100644 index 0000000000..2a04ae7a6c --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/resources/META-INF/sca/default.scdl @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. + --> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:groovy="http://incubator.apache.org/tuscany/xmlns/container/groovy/1.0-incubator-M2" + name="groovy.test"> + + <component name="Greeting"> + <groovy:implementation.groovy script="Foo.groovy"/> + </component> + +</composite> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/resources/org/apache/tuscany/container/groovy/mock/TestScript.groovy b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/resources/org/apache/tuscany/container/groovy/mock/TestScript.groovy new file mode 100644 index 0000000000..f0b0a3a9d4 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.groovy/src/test/resources/org/apache/tuscany/container/groovy/mock/TestScript.groovy @@ -0,0 +1 @@ +Test Script
\ No newline at end of file diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/LICENSE.txt b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/LICENSE.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/LICENSE.txt @@ -0,0 +1,202 @@ + + 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/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/NOTICE.txt b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/NOTICE.txt new file mode 100644 index 0000000000..d83ebbe236 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/NOTICE.txt @@ -0,0 +1,14 @@ +${pom.name} +Copyright (c) 2005 - 2006 The Apache Software Foundation + +Apache Tuscany is an effort undergoing incubation at The Apache Software +Foundation (ASF), sponsored by the Apache Web Services PMC. Incubation is +required of all newly accepted projects until a further review indicates that +the infrastructure, communications, and decision making process have stabilized +in a manner consistent with other successful ASF projects. While incubation +status is not necessarily a reflection of the completeness or stability of the +code, it does indicate that the project has yet to be fully endorsed by the ASF. + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/pom.xml b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/pom.xml new file mode 100644 index 0000000000..48ce59a391 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/pom.xml @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<project> + + <parent> + <groupId>org.apache.tuscany.sca.services.containers</groupId> + <artifactId>parent</artifactId> + <version>1.0-incubator-M2</version> + </parent> + + <modelVersion>4.0.0</modelVersion> + <artifactId>javascript</artifactId> + <name>Apache Tuscany JavaScript Container</name> + <description>Apache Tuscany JavaScript Container</description> + + <dependencies> + + <dependency> + <groupId>org.apache.tuscany.sca.kernel</groupId> + <artifactId>core</artifactId> + <version>${sca.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca.services.idl</groupId> + <artifactId>wsdl</artifactId> + <version>${sca.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>rhino</groupId> + <artifactId>js</artifactId> + <version>1.6R2</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>xmlbeans</groupId> + <artifactId>xbean</artifactId> <!-- Reqd for E4X --> + <version>2.1.0</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>test</artifactId> + <version>${sca.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + </dependency> + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymockclassextension</artifactId> + </dependency> + <dependency> + <groupId>org.apache.ws.commons.axiom</groupId> + <artifactId>axiom-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.ws.commons.axiom</groupId> + <artifactId>axiom-impl</artifactId> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.1</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>woodstox</groupId> + <artifactId>wstx-asl</artifactId> + </dependency> + <dependency> + <groupId>cglib</groupId> + <artifactId>cglib-nodep</artifactId> + <version>2.1_3</version> + <scope>compile</scope> + </dependency> + + </dependencies> + +</project> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptComponent.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptComponent.java new file mode 100644 index 0000000000..9872788a05 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptComponent.java @@ -0,0 +1,120 @@ +/* + * 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.container.javascript; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.extension.AtomicComponentExtension; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.WireService; + +import org.apache.tuscany.container.javascript.rhino.RhinoScript; +import org.apache.tuscany.container.javascript.rhino.RhinoScriptInstance; + +/** + * The JavaScript component implementation. + */ +public class JavaScriptComponent extends AtomicComponentExtension { + + private final List<Class<?>> services; + + private final Map<String, Object> properties; + + private RhinoScript rhinoScript; + + public JavaScriptComponent(String name, RhinoScript rhinoScript, Map<String, Object> properties, List<Class<?>> services, + CompositeComponent parent, ScopeContainer scopeContainer, WireService wireService, + WorkContext workContext) { + super(name, parent, scopeContainer, wireService, workContext, null, 0); + + this.rhinoScript = rhinoScript; + this.services = services; + this.scope = scopeContainer.getScope(); + this.properties = properties; + } + + public Object createInstance() throws ObjectCreationException { + + Map<String, Object> context = new HashMap<String, Object>(getProperties()); + + for (List<OutboundWire> referenceWires : getOutboundWires().values()) { + for (OutboundWire wire : referenceWires) { + Object wireProxy = wireService.createProxy(wire); + //since all types that may be used in the reference interface may not be known to Rhino + //using the wireProxy as is will fail result in type conversion exceptions in cases where + //Rhino does not know enough of the tpypes used. Hence introduce a interceptor proxy, + //with weak typing (java.lang.Object) so that Rhino's call to the proxy succeeds. Then + //within this interceptor proxy perform data mediations required to correctly call the + //referenced service. + Class<?> businessInterface = wire.getServiceContract().getInterfaceClass(); + JavaScriptReferenceProxy interceptingProxy = + new JavaScriptReferenceProxy(businessInterface, + wireProxy, + rhinoScript.createInstanceScope(context)); + context.put(wire.getReferenceName(), interceptingProxy.createProxy()); + + } + } + + return rhinoScript.createRhinoScriptInstance(context); + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) { + return new JavaScriptInvoker(operation.getName(), (Class)operation.getOutputType().getLogical(), this); + } + + // TODO: move all the following up to AtomicComponentExtension? + + public List<Class<?>> getServiceInterfaces() { + return services; + } + + public Map<String, Object> getProperties() { + return properties; + } + + public RhinoScriptInstance getTargetInstance() throws TargetException { + return (RhinoScriptInstance) scopeContainer.getInstance(this); + } + + public Object getServiceInstance() throws TargetException { + return getServiceInstance(null); + } + + public Object getServiceInstance(String service) throws TargetException { + InboundWire wire = getInboundWire(service); + if (wire == null) { + TargetException e = new TargetException("ServiceDefinition not found"); // TODO better error message + e.setIdentifier(service); + throw e; + } + return wireService.createProxy(wire); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptComponentBuilder.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptComponentBuilder.java new file mode 100644 index 0000000000..1987026e59 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptComponentBuilder.java @@ -0,0 +1,152 @@ +/* + * 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.container.javascript; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.container.javascript.rhino.RhinoScript; +import org.apache.tuscany.container.javascript.utils.xmlfromxsd.XmlInstanceRegistry; +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.builder.BuilderConfigException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentBuilderExtension; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.PropertyValue; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceDefinition; +import org.apache.xmlbeans.XmlObject; +import org.osoa.sca.annotations.Constructor; + +/** + * Extension point for creating {@link JavaScriptComponent}s from an assembly configuration + */ +public class JavaScriptComponentBuilder extends ComponentBuilderExtension<JavaScriptImplementation> { + + private static String head = "var xmlInstanceMap = new Array();"; + + private static String part1 = "xmlInstanceMap[\""; + + private static String part2 = "\"] = "; + + private static String part3 = ";"; + + private static String getXmlObjectFunction = + "function getXmlObject(xmlElementNamespace, xmlElementName){\n" + + "return xmlInstanceMap[xmlElementNamespace + \"#\" + xmlElementName];\n}"; + + XmlInstanceRegistry xmlInstRegistry; + + @Constructor({"xmlInstRegistry"}) + public JavaScriptComponentBuilder(@Autowire XmlInstanceRegistry reg) { + this.xmlInstRegistry = reg; + } + + protected Class<JavaScriptImplementation> getImplementationType() { + return JavaScriptImplementation.class; + } + + @SuppressWarnings("unchecked") + public Component build(CompositeComponent parent, ComponentDefinition<JavaScriptImplementation> componentDefinition, + DeploymentContext deploymentContext) throws BuilderConfigException { + + String name = componentDefinition.getName(); + JavaScriptImplementation implementation = componentDefinition.getImplementation(); + JavaScriptComponentType componentType = implementation.getComponentType(); + + // get list of services provided by this component + Collection<ServiceDefinition> collection = componentType.getServices().values(); + List<Class<?>> services = new ArrayList<Class<?>>(collection.size()); + for (ServiceDefinition serviceDefinition : collection) { + services.add(serviceDefinition.getServiceContract().getInterfaceClass()); + //do this for the set of references also + enhanceRhinoScript(serviceDefinition, implementation); + } + + // get the properties for the component + Collection<PropertyValue<?>> propertyValues = componentDefinition.getPropertyValues().values(); + Map<String, Object> properties = new HashMap<String, Object>(); + for (PropertyValue propertyValue : propertyValues) { + properties.put(propertyValue.getName(), propertyValue.getValueFactory().getInstance()); + } + + RhinoScript rhinoScript = implementation.getRhinoScript(); + + // TODO: have ComponentBuilderExtension pass ScopeContainer in on build method? + ScopeContainer scopeContainer; + Scope scope = componentType.getLifecycleScope(); + if (Scope.MODULE == scope) { + scopeContainer = deploymentContext.getModuleScope(); + } else { + scopeContainer = scopeRegistry.getScopeContainer(scope); + } + + return new JavaScriptComponent(name, rhinoScript, properties, services, parent, scopeContainer, wireService, workContext); + } + + private void enhanceRhinoScript(ServiceDefinition serviceDefn, JavaScriptImplementation implementation) throws BuilderConfigException { + //if the service interface of the component is a wsdl get the wsdl interface and generate + //xml instances for the elements in it. Add these xml instances to the rhinoscript. + //TODO : when interface.wsdl and wsdl registry is integrated remove this hardcoding and + //obtain wsdl from the interface.wsdl or wsdl registry + String wsdlPath = "org/apache/tuscany/container/javascript/rhino/helloworld.wsdl"; + + //this if block is a tempfix to get other testcases working. Again when a the interface.wsdl + //extension is in place this will be deleted. Right now this is the only way we know that + //a js has to do with an interface that is wsdl. + if (!implementation.getRhinoScript().getScriptName().endsWith("e4x.js")) { + return; + } + + try { + Map<String, XmlObject> xmlInstanceMap = xmlInstRegistry.getXmlInstance(wsdlPath); + StringBuffer sb = new StringBuffer(); + + sb.append(head); + sb.append("\n"); + for (String xmlInstanceKey : xmlInstanceMap.keySet()) { + sb.append(part1); + sb.append(xmlInstanceKey); + sb.append(part2); + sb.append(xmlInstanceMap.get(xmlInstanceKey).toString()); + sb.append(part3); + sb.append("\n"); + } + // System.out.println(" **** - " + sb.toString()); + + sb.append(getXmlObjectFunction); + + RhinoScript rhinoScript = implementation.getRhinoScript(); + sb.append(rhinoScript.getScript()); + rhinoScript.setScript(sb.toString()); + rhinoScript.initScriptScope(rhinoScript.getScriptName(), sb.toString(), null, rhinoScript.getClassLoader()); + implementation.setRhinoScript(rhinoScript); + + } catch (Exception e) { + throw new BuilderConfigException(e); + } + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptComponentType.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptComponentType.java new file mode 100644 index 0000000000..31a4db14b6 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptComponentType.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.container.javascript; + +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceDefinition; + +public class JavaScriptComponentType extends ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> { + + private Scope lifecycleScope = Scope.MODULE; + + public JavaScriptComponentType() { + } + + @SuppressWarnings("unchecked") + public JavaScriptComponentType(ComponentType ct) { + // TODO: A bit hacky but this is so the non-JavaScript .componentType side file can be used for now + setInitLevel(ct.getInitLevel()); + for (Object property : ct.getProperties().values()) { + add((Property)property); + } + for (Object reference : ct.getReferences().values()) { + add((ReferenceDefinition)reference); + } + for (Object service : ct.getServices().values()) { + add((ServiceDefinition)service); + } + } + + public Scope getLifecycleScope() { + return lifecycleScope; + } + + public void setLifecycleScope(Scope lifecycleScope) { + this.lifecycleScope = lifecycleScope; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptComponentTypeLoader.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptComponentTypeLoader.java new file mode 100644 index 0000000000..e28daeceb0 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptComponentTypeLoader.java @@ -0,0 +1,113 @@ +/* + * 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.container.javascript; + +import java.net.URL; + +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.MissingResourceException; +import org.apache.tuscany.spi.model.ComponentType; + +import org.apache.tuscany.container.javascript.rhino.RhinoSCAConfig; +import org.apache.tuscany.container.javascript.rhino.RhinoScript; + +/** + * @version $Rev$ $Date$ + */ +public class JavaScriptComponentTypeLoader extends ComponentTypeLoaderExtension<JavaScriptImplementation> { + + private JavaInterfaceProcessorRegistry processorRegistry; + + public JavaScriptComponentTypeLoader(@Autowire JavaInterfaceProcessorRegistry processorRegistry) { + this.processorRegistry = processorRegistry; + } + + @Override + protected Class<JavaScriptImplementation> getImplementationClass() { + return JavaScriptImplementation.class; + } + + protected JavaScriptComponentType loadByIntrospection(CompositeComponent parent, + JavaScriptImplementation implementation, + DeploymentContext deploymentContext) throws + MissingResourceException, + InvalidServiceContractException { + + RhinoScript rhinoScript = implementation.getRhinoScript(); + RhinoSCAConfig scaConfig = rhinoScript.getSCAConfig(); + if (!scaConfig.hasSCAConfig()) { + throw new IllegalArgumentException( + "must use either .componentType side file or JS SCA varriable definition"); + } + + // FIXME this should be a system service, not instantiated here + JavaScriptComponentType componentType = new JavaScriptIntrospector(null, processorRegistry) + .introspectScript(scaConfig, rhinoScript.getClassLoader()); + + return componentType; + } + + protected String getResourceName(JavaScriptImplementation implementation) { + return implementation.getRhinoScript().getScriptName(); + } + + // TODO: must be possible to move all the following up in to ComponentTypeLoaderExtension + + public void load(CompositeComponent parent, JavaScriptImplementation implementation, + DeploymentContext deploymentContext) + throws LoaderException { + + URL resource = implementation.getRhinoScript().getClassLoader().getResource(getSideFileName(implementation)); + JavaScriptComponentType componentType; + if (resource == null) { + try { + componentType = loadByIntrospection(parent, implementation, deploymentContext); + } catch (InvalidServiceContractException e) { + throw new LoaderException("Invalid service contract", e); + } + } else { + componentType = loadFromSidefile(resource, deploymentContext); + } + + implementation.setComponentType(componentType); + } + + protected JavaScriptComponentType loadFromSidefile(URL url, DeploymentContext deploymentContext) + throws LoaderException { + ComponentType ct = loaderRegistry.load(null, url, ComponentType.class, deploymentContext); + JavaScriptComponentType jsct = new JavaScriptComponentType(ct); + return jsct; + } + + private String getSideFileName(JavaScriptImplementation implementation) { + String baseName = getResourceName(implementation); + int lastDot = baseName.lastIndexOf('.'); + if (lastDot != -1) { + baseName = baseName.substring(0, lastDot); + } + return baseName + ".componentType"; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptImplementation.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptImplementation.java new file mode 100644 index 0000000000..7de479f096 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptImplementation.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.container.javascript; + +import org.apache.tuscany.container.javascript.rhino.RhinoScript; +import org.apache.tuscany.spi.model.AtomicImplementation; + +/** + * Model object for a JavaScript implementation. + */ +public class JavaScriptImplementation extends AtomicImplementation<JavaScriptComponentType> { + + private RhinoScript rhinoScript; + + public RhinoScript getRhinoScript() { + return rhinoScript; + } + + public void setRhinoScript(RhinoScript rhinoScript) { + this.rhinoScript = rhinoScript; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptImplementationLoader.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptImplementationLoader.java new file mode 100644 index 0000000000..67cc35afc2 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptImplementationLoader.java @@ -0,0 +1,111 @@ +/* + * 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.container.javascript; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.container.javascript.rhino.RhinoScript; +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.LoaderExtension; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.LoaderUtil; +import org.apache.tuscany.spi.loader.MissingResourceException; +import org.osoa.sca.annotations.Constructor; + +/** + * Loader for handling JavaScript <js:implementation.js> elements. + */ +public class JavaScriptImplementationLoader extends LoaderExtension<JavaScriptImplementation> { + private static final QName IMPLEMENTATION_JAVASCRIPT = + new QName("http://incubator.apache.org/tuscany/xmlns/container/js/1.0-incubator-M2", "implementation.js"); + + @Constructor({"registry"}) + public JavaScriptImplementationLoader(@Autowire LoaderRegistry registry) { + super(registry); + } + + public QName getXMLType() { + return IMPLEMENTATION_JAVASCRIPT; + } + + public JavaScriptImplementation load(CompositeComponent parent, XMLStreamReader reader, DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException { + + String script = reader.getAttributeValue(null, "script"); + if (script == null) { + throw new MissingResourceException("No script supplied"); + } + + ClassLoader cl = deploymentContext.getClassLoader(); + String source = loadSource(cl, script); + + LoaderUtil.skipToEndElement(reader); + + JavaScriptImplementation implementation = new JavaScriptImplementation(); + RhinoScript rhinoScript = new RhinoScript(script, source, null, cl); + implementation.setRhinoScript(rhinoScript); + registry.loadComponentType(parent, implementation, deploymentContext); + return implementation; + } + + protected String loadSource(ClassLoader cl, String resource) throws LoaderException { + URL url = cl.getResource(resource); + if (url == null) { + throw new MissingResourceException(resource); + } + InputStream is; + try { + is = url.openStream(); + } catch (IOException e) { + MissingResourceException mre = new MissingResourceException(resource, e); + mre.setIdentifier(resource); + throw mre; + } + try { + Reader reader = new InputStreamReader(is, "UTF-8"); + char[] buffer = new char[1024]; + StringBuilder source = new StringBuilder(); + int count; + while ((count = reader.read(buffer)) > 0) { + source.append(buffer, 0, count); + } + return source.toString(); + } catch (IOException e) { + LoaderException le = new LoaderException(e); + le.setIdentifier(resource); + throw le; + } finally { + try { + is.close(); + } catch (IOException e) { + // ignore + } + } + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptIntrospector.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptIntrospector.java new file mode 100644 index 0000000000..542504b62e --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptIntrospector.java @@ -0,0 +1,173 @@ +/* + * 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.container.javascript; + +import java.util.Iterator; +import java.util.Map; +import javax.wsdl.Definition; +import javax.wsdl.PortType; +import javax.wsdl.WSDLException; +import javax.wsdl.factory.WSDLFactory; +import javax.wsdl.xml.WSDLReader; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.loader.MissingResourceException; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import org.apache.tuscany.container.javascript.rhino.RhinoSCAConfig; +import org.apache.tuscany.idl.wsdl.WSDLDefinitionRegistry; +import org.apache.tuscany.idl.wsdl.WSDLServiceContract; + +/** + * Introspects JavaScript files for SCA configuration + */ +public class JavaScriptIntrospector { + + private WSDLDefinitionRegistry wsdlRegistry; + private JavaInterfaceProcessorRegistry processorRegistry; + + public JavaScriptIntrospector(@Autowire WSDLDefinitionRegistry wsdlRegistry, + @Autowire JavaInterfaceProcessorRegistry processorRegistry) { + this.wsdlRegistry = wsdlRegistry; + this.processorRegistry = processorRegistry; + } + + public JavaScriptComponentType introspectScript(RhinoSCAConfig scaConfig, ClassLoader cl) + throws MissingResourceException, InvalidServiceContractException { + JavaScriptComponentType componentType = new JavaScriptComponentType(); + introspectJavaInterface(componentType, cl, scaConfig.getJavaInterface()); + introspectWSDLInterface(componentType, cl, scaConfig.getWSDLNamespace(), scaConfig.getWSDLPortType(), + scaConfig.getWSDLLocation()); + introspectReferences(componentType, cl, scaConfig.getReferences()); + introspectProperties(componentType, cl, scaConfig.getProperties()); + introspectScope(componentType, scaConfig.getScope()); + return componentType; + } + + private void introspectScope(JavaScriptComponentType componentType, Scope scope) { + if (scope != null) { + componentType.setLifecycleScope(scope); + } + } + + @SuppressWarnings("unchecked") + private void introspectJavaInterface(ComponentType componentType, ClassLoader cl, String serviceClass) + throws MissingResourceException, InvalidServiceContractException { + if (serviceClass != null) { + ServiceDefinition service = new ServiceDefinition(); + try { + ServiceContract<?> sc = processorRegistry.introspect(Class.forName(serviceClass)); + service.setServiceContract(sc); + componentType.add(service); + } catch (ClassNotFoundException e) { + throw new MissingResourceException("Interface not found", e); + } + } + } + + @SuppressWarnings("unchecked") + private void introspectWSDLInterface(ComponentType componentType, ClassLoader cl, String wsdlNamespace, + String wsdlPortType, String wsdlLocation) { + if (wsdlNamespace == null && wsdlPortType == null && wsdlLocation == null) { + return; + } + + PortType portType = null; + if (wsdlLocation != null) { + portType = readWSDLPortType(wsdlNamespace, wsdlPortType, wsdlLocation, portType); + } else { + portType = getPortType(wsdlNamespace, wsdlPortType); + } + + ServiceDefinition service = new ServiceDefinition(); + WSDLServiceContract wsdlSC = new WSDLServiceContract(); + wsdlSC.setPortType(portType); + service.setServiceContract(wsdlSC); + componentType.add(service); + } + + private PortType readWSDLPortType(String wsdlNamespace, String wsdlPortType, String wsdlLocation, + PortType portType) { + Definition wsdlDefinition; + try { + WSDLReader reader = WSDLFactory.newInstance().newWSDLReader(); + reader.setFeature("javax.wsdl.verbose", false); + wsdlDefinition = reader.readWSDL(wsdlLocation.toString()); + } catch (WSDLException e) { + throw new RuntimeException(e); + + } + Map portTypes = wsdlDefinition.getPortTypes(); + for (Iterator i = portTypes.keySet().iterator(); i.hasNext();) { + QName portTypeQN = (QName) i.next(); + if (wsdlNamespace != null) { + if (!portTypeQN.getNamespaceURI().equals(wsdlNamespace)) { + continue; + } + } + if (wsdlPortType != null) { + if (!portTypeQN.getLocalPart().equals(wsdlPortType)) { + continue; + } + } + if (portType != null) { + throw new RuntimeException("multiple matching portTypes in wsdl: " + wsdlLocation); + } + portType = (PortType) portTypes.get(portTypeQN); + } + if (portType == null) { + throw new RuntimeException("portType not found in wsdl: " + wsdlLocation); + } + return portType; + } + + private PortType getPortType(String wsdlNamespace, String wsdlPortType) { + if (wsdlPortType == null) { + throw new IllegalArgumentException("must specify the wsdlPortType in script SCA config"); + } + PortType portType = null; + if (wsdlNamespace != null) { + QName portTypeQN = new QName(wsdlNamespace.toString(), wsdlPortType.toString()); + portType = wsdlRegistry.getPortType(portTypeQN); + if (portType == null) { + throw new IllegalArgumentException("no WSDL registered for portType: " + portTypeQN); + } + } else { + // wsdlRegistry.getPortType(wsdlPortType.toString()); + if (portType == null) { + throw new IllegalArgumentException("no WSDL registered for portType:" + wsdlPortType); + } + } + return portType; + } + + + private void introspectProperties(ComponentType componentType, ClassLoader cl, Map properties) { + } + + private void introspectReferences(ComponentType componentType, ClassLoader cl, Map references) { + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptInvoker.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptInvoker.java new file mode 100644 index 0000000000..281b417d64 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptInvoker.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.container.javascript; + +import java.lang.reflect.InvocationTargetException; + +import org.apache.tuscany.container.javascript.rhino.RhinoScriptInstance; +import org.apache.tuscany.spi.extension.TargetInvokerExtension; + +/** + * Dispatches to a JavaScript implementation instance + * + * @version $$Rev$$ $$Date$$ + */ +public class JavaScriptInvoker extends TargetInvokerExtension { + + private JavaScriptComponent context; + + private String functionName; + + private Class responseClass; + + public JavaScriptInvoker(String functionName, Class respClass, JavaScriptComponent context) { + this.functionName = functionName; + this.context = context; + this.responseClass = respClass; + } + + /** + * Invokes a function on a script instance + */ + public Object invokeTarget(final Object payload) throws InvocationTargetException { + RhinoScriptInstance target = context.getTargetInstance(); + return target.invokeFunction(functionName, (Object[]) payload, responseClass); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptRefInvocInterceptor.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptRefInvocInterceptor.java new file mode 100644 index 0000000000..f8c978f833 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptRefInvocInterceptor.java @@ -0,0 +1,132 @@ +/* + * 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.container.javascript; + +import java.io.ByteArrayInputStream; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.axiom.om.OMAbstractFactory; +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.impl.builder.StAXOMBuilder; +import org.apache.axiom.om.util.StAXUtils; +import org.apache.xmlbeans.XmlObject; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; +import org.mozilla.javascript.Wrapper; +import org.mozilla.javascript.xml.XMLObject; + +/** + * This Interceptor encasulates the data mediation required by the JavaScriptReferenceProxy. The + * invocation handler of this class traps the javascript reference calls, performs data mediation + * and calls then calls the actual referred service. This classes implementation is subject to + * review and change when the DataMediation infrastructure of Tuscany is ready. + * + */ +public class JavaScriptRefInvocInterceptor implements InvocationHandler { + private Object actualProxy; + + private Class wireInterface; + + private Scriptable instanceScope; + + JavaScriptRefInvocInterceptor(Object wireProxy, Class wireIfc, Scriptable instScope) { + this.actualProxy = wireProxy; + this.wireInterface = wireIfc; + this.instanceScope = instScope; + } + + public Object invoke(Object arg0, Method method, Object[] args) throws Throwable { + // TODO Auto-generated method stub + Context cx = Context.enter(); + try { + Method invokedMethod = getInvokedMethod(method.getName()); + Object[] tranformedArgs = new Object[args.length]; + for (int count = 0; count < args.length; ++count) { + tranformedArgs[count] = fromJavaScript(invokedMethod.getParameterTypes()[count], args[count]); + } + + Object response = invokedMethod.invoke(actualProxy, tranformedArgs); + response = toJavaScript(response, instanceScope, cx); + return response; + } finally { + Context.exit(); + } + } + + private Method getInvokedMethod(String methodName) { + Method[] methods = wireInterface.getMethods(); + + for (int count = 0; count < methods.length; ++count) { + if (methods[count].getName().equals(methodName)) { + return methods[count]; + } + } + throw new RuntimeException("Unable to find invocation method"); + } + + protected Object fromJavaScript(Class reqArgType, Object jsArg) throws Exception { + Object javaArg; + if (Context.getUndefinedValue().equals(jsArg)) { + javaArg = null; + } else if (jsArg instanceof XMLObject) { + // TODO: E4X Bug? Shouldn't need this copy, but without it the outer element gets lost??? + Scriptable jsXML = (Scriptable) ScriptableObject.callMethod((Scriptable) jsArg, "copy", new Object[0]); + Wrapper wrapper = (Wrapper) ScriptableObject.callMethod(jsXML, "getXmlObject", new Object[0]); + javaArg = wrapper.unwrap(); + + XMLStreamReader xmlReader = StAXUtils.createXMLStreamReader(new ByteArrayInputStream(javaArg.toString().getBytes())); + StAXOMBuilder staxOMBuilder = new StAXOMBuilder(OMAbstractFactory.getOMFactory(), xmlReader); + javaArg = staxOMBuilder.getDocumentElement(); + } else if (jsArg instanceof Wrapper) { + javaArg = ((Wrapper) jsArg).unwrap(); + } else { + if (reqArgType != null) { + javaArg = Context.jsToJava(jsArg, reqArgType); + } else { + javaArg = Context.jsToJava(jsArg, String.class); + } + } + + return javaArg; + } + + protected Object toJavaScript(Object retVal, Scriptable scope, Context cx) throws RuntimeException { + Object jsRetVal; + if (retVal instanceof OMElement) { + try { + XmlObject xmlObject = XmlObject.Factory.parse(retVal.toString()); + Object jsXML = cx.getWrapFactory().wrap(cx, scope, xmlObject, XmlObject.class); + jsRetVal = cx.newObject(scope, "XML", new Object[] { jsXML }); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else if (retVal instanceof XmlObject) { + Object jsXML = cx.getWrapFactory().wrap(cx, scope, (XmlObject) retVal, XmlObject.class); + jsRetVal = cx.newObject(scope, "XML", new Object[] { jsXML }); + } else { + jsRetVal = Context.toObject(retVal, scope); + } + + return jsRetVal; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptReferenceProxy.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptReferenceProxy.java new file mode 100644 index 0000000000..8b432872b8 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/JavaScriptReferenceProxy.java @@ -0,0 +1,132 @@ +/* + * 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.container.javascript; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import net.sf.cglib.asm.ClassWriter; +import net.sf.cglib.asm.CodeVisitor; +import net.sf.cglib.asm.Constants; +import net.sf.cglib.asm.Type; + +import org.apache.tuscany.spi.wire.WireInvocationHandler; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; +import org.mozilla.javascript.Wrapper; +import org.mozilla.javascript.xml.XMLObject; + +/** + * This is a proxy that will mediate reference calls from the JavaScript. The mediation code here will be reviewed when the DataMediation + * infrastructure is ready. This proxy assmes that there is no verloading of service methods on the reference interface i.e. there are no two service + * methods that have the same method name or operation name. + */ +public class JavaScriptReferenceProxy { + + private Class interfaze; + + private Object wireProxy; + + private Scriptable instanceScope; + + public JavaScriptReferenceProxy(Class interfaze, Object wireProxy, Scriptable instScope) { + this.interfaze = interfaze; + this.wireProxy = wireProxy; + this.instanceScope = instScope; + } + + public Object createProxy() { + try { + GenericProxyClassLoader classloader = new GenericProxyClassLoader(); + final byte[] byteCode = generateGenericInterface(interfaze); + + Class genericInterface = classloader.defineClass(byteCode); + InvocationHandler proxyHandler = new JavaScriptRefInvocInterceptor(wireProxy, + interfaze, instanceScope); + // return genericInterface.cast(Proxy.newProxyInstance(classloader, new Class[]{genericInterface}, proxyHandler)); + return Proxy.newProxyInstance(classloader, + new Class[]{genericInterface}, + proxyHandler); + } catch (Exception e) { + return null; + } + } + + private static byte[] generateGenericInterface(Class serviceInterface) { + String interfazeName = serviceInterface.getCanonicalName(); + ClassWriter cw = new ClassWriter(false); + + cw.visit(Constants.V1_5, + Constants.ACC_PUBLIC + Constants.ACC_ABSTRACT + Constants.ACC_INTERFACE, + interfazeName.replace('.', + '/'), + "java/lang/Object", + null, + serviceInterface.getSimpleName() + ".java"); + + StringBuffer argsAndReturn = new StringBuffer("("); + Method[] methods = serviceInterface.getMethods(); + for (int count = 0; count < methods.length; ++count) { + argsAndReturn = new StringBuffer("("); + Class[] paramTypes = methods[count].getParameterTypes(); + Class returnType = methods[count].getReturnType(); + + for (int paramCount = 0; paramCount < paramTypes.length; ++paramCount) { + argsAndReturn.append(Type.getType(Object.class)); + } + argsAndReturn.append(")"); + argsAndReturn.append(Type.getType(Object.class)); + + Class[] exceptionTypes = methods[count].getExceptionTypes(); + String[] exceptions = new String[exceptionTypes.length]; + for (int excCount = 0; excCount < exceptionTypes.length; ++excCount) { + exceptions[excCount] = exceptionTypes[excCount].getName(); + exceptions[excCount] = exceptions[excCount].replace('.', + '/'); + } + + CodeVisitor cv = cw.visitMethod(Constants.ACC_PUBLIC + Constants.ACC_ABSTRACT, + methods[count].getName(), + argsAndReturn.toString(), + exceptions, + null); + cw.visitEnd(); + } + + cw.visitEnd(); + + return cw.toByteArray(); + } + + private class GenericProxyClassLoader extends ClassLoader { + public Class defineClass(byte[] byteArray) { + try { + return defineClass(null, + byteArray, + 0, + byteArray.length); + } catch (Throwable e) { + return null; + } + } + + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoFunctionInvoker.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoFunctionInvoker.java new file mode 100644 index 0000000000..b2064f9110 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoFunctionInvoker.java @@ -0,0 +1,123 @@ +/* + * 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.container.javascript.rhino; + +import java.io.ByteArrayInputStream; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.axiom.om.OMAbstractFactory; +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.impl.builder.StAXOMBuilder; +import org.apache.axiom.om.util.StAXUtils; +import org.apache.xmlbeans.XmlObject; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Function; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; +import org.mozilla.javascript.Wrapper; +import org.mozilla.javascript.xml.XMLObject; + +/** + * An invoker for a specific function in a JavaScript script + */ +public class RhinoFunctionInvoker { + + private Scriptable instanceScope; + + private Function function; + + private Class responseClass; + + public RhinoFunctionInvoker(Scriptable instanceScope, Function function, Class responseClass) { + this.instanceScope = instanceScope; + this.function = function; + this.responseClass = responseClass; + } + + public Object invoke(Object[] args) { + Context cx = Context.enter(); + try { + + Object[] jsArgs = toJavaScript(args, instanceScope, cx); + Object jsResponse = function.call(cx, instanceScope, instanceScope, jsArgs); + Object response = fromJavaScript(jsResponse); + return response; + + } catch ( Exception e ) { + throw new RuntimeException(e); + } + finally { + Context.exit(); + } + } + + protected Object[] toJavaScript(Object[] arg, Scriptable scope, Context cx) throws RuntimeException { + Object[] jsArgs; + if (arg == null) { + jsArgs = new Object[0]; + } else if (arg.length == 1 && arg[0] instanceof OMElement) { + try { + XmlObject xmlObject = XmlObject.Factory.parse(arg[0].toString()); + Object jsXML = cx.getWrapFactory().wrap(cx, scope, xmlObject, XmlObject.class); + jsArgs = new Object[] { cx.newObject(scope, "XML", new Object[] { jsXML }) }; + } catch ( Exception e ) { + throw new RuntimeException(e); + } + } else if (arg.length == 1 && arg[0] instanceof XmlObject) { + Object jsXML = cx.getWrapFactory().wrap(cx, scope, (XmlObject)arg[0], XmlObject.class); + jsArgs = new Object[] { cx.newObject(scope, "XML", new Object[] { jsXML }) }; + } else { + jsArgs = new Object[arg.length]; + for (int i = 0; i < jsArgs.length; i++) { + jsArgs[i] = Context.toObject(arg[i], scope); + } + } + + return jsArgs; + } + + protected Object fromJavaScript(Object o) throws Exception { + Object response; + if (Context.getUndefinedValue().equals(o)) { + response = null; + } else if (o instanceof XMLObject) { + // TODO: E4X Bug? Shouldn't need this copy, but without it the outer element gets lost??? + Scriptable jsXML = (Scriptable) ScriptableObject.callMethod((Scriptable) o, "copy", new Object[0]); + Wrapper wrapper = (Wrapper) ScriptableObject.callMethod(jsXML, "getXmlObject", new Object[0]); + response = wrapper.unwrap(); + + XMLStreamReader xmlReader = + StAXUtils.createXMLStreamReader(new ByteArrayInputStream(response.toString().getBytes())); + StAXOMBuilder staxOMBuilder = new StAXOMBuilder(OMAbstractFactory.getOMFactory(), xmlReader); + response = staxOMBuilder.getDocumentElement(); + + } else if (o instanceof Wrapper) { + response = ((Wrapper) o).unwrap(); + } else { + if (responseClass != null) { + response = Context.jsToJava(o, responseClass); + } else { + response = Context.jsToJava(o, String.class); + } + } + return response; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoSCAConfig.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoSCAConfig.java new file mode 100644 index 0000000000..af27403c03 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoSCAConfig.java @@ -0,0 +1,157 @@ +/* + * 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.container.javascript.rhino; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.model.Scope; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.UniqueTag; + +/** + * Represents the variable defining the SCA aspects of the script + * <code> + * SCA = { + * javaInterface : "my.pkg.ClassName", + * wsdlPortType : "wsdlPortTypeName", + * wsdlNameSpace : "http://my.namespace.com", + * wsdlLocation : "\wsdl\mywsdl.txt", + * properties : { "foo" : ["java.lang.String", "defaultValue"],}, + * references : {}, + * scope : 'stateless'|'request'|'conversational'|'composite', + * } + * </code> + * The config must define the service with either javaInterface or wsdl. When + * using wsdl the three parameters are optional. If wsdlLocation is used that is the + * WSDL document used, and the namespace and portType parameters are only required if + * the WSDL definition defines multiple portTypes. + */ +public class RhinoSCAConfig { + + private boolean hasSCAConfig; + + private String javaInterface; + + private String wsdlLocation; + + private String wsdlNamespace; + + private String wsdlPortType; + + private Map properties; + + private Map references; + + private Scope scope; + + public RhinoSCAConfig(Scriptable scriptScope) { + Object o = scriptScope.get("SCA", scriptScope); + if (o != null && UniqueTag.NOT_FOUND != o) { + hasSCAConfig = true; + Scriptable scaVar = (Scriptable) o; + o = scaVar.get("javaInterface", scriptScope); + if (o != null && UniqueTag.NOT_FOUND != o) { + this.javaInterface = o.toString(); + } + o = scaVar.get("wsdlLocation", scriptScope); + if (o != null && UniqueTag.NOT_FOUND != o) { + this.wsdlLocation = o.toString(); + } + o = scaVar.get("wsdlPortType", scriptScope); + if (o != null && UniqueTag.NOT_FOUND != o) { + this.wsdlPortType = o.toString(); + } + o = scaVar.get("wsdlNamespace", scriptScope); + if (o != null && UniqueTag.NOT_FOUND != o) { + this.wsdlNamespace = o.toString(); + } + if (javaInterface != null) { + if (wsdlLocation != null || wsdlPortType != null || wsdlNamespace != null) { + throw new IllegalArgumentException("script SCA config defines both Java and WSDL service interface"); + } + } else { + if (wsdlLocation == null && wsdlPortType == null && wsdlNamespace == null) { + throw new IllegalArgumentException("script SCA config must define either Java or WSDL service interface"); + } + } + + this.properties = new HashMap(); + o = scaVar.get("properties", scriptScope); + if (o != null && UniqueTag.NOT_FOUND != o) { + // TODO parse properties + } + + this.references = new HashMap(); + o = scaVar.get("references", scriptScope); + if (o != null && UniqueTag.NOT_FOUND != o) { + // TODO parse references + } + + o = scaVar.get("scope", scriptScope); + if (o != null && UniqueTag.NOT_FOUND != o) { + if ("stateless".equalsIgnoreCase(String.valueOf(o))) { + this.scope = Scope.STATELESS; + } else if ("request".equalsIgnoreCase(String.valueOf(o))) { + this.scope = Scope.REQUEST; + } else if ("conversational".equalsIgnoreCase(String.valueOf(o))) { + this.scope = Scope.SESSION; // TODO: where's CONVERSATIONAL? + } else if ("composite".equalsIgnoreCase(String.valueOf(o))) { + this.scope = Scope.MODULE; // TODO: composite = MODULE for now? + } else { + throw new IllegalArgumentException("invalid scope value: " + o); + } + } + + } + } + + public boolean hasSCAConfig() { + return hasSCAConfig; + } + + public String getJavaInterface() { + return javaInterface; + } + + public Map getProperties() { + return properties; + } + + public Map getReferences() { + return references; + } + + public String getWSDLLocation() { + return wsdlLocation; + } + + public String getWSDLNamespace() { + return wsdlNamespace; + } + + public String getWSDLPortType() { + return wsdlPortType; + } + + public Scope getScope() { + return scope; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoScript.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoScript.java new file mode 100644 index 0000000000..3552372223 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoScript.java @@ -0,0 +1,210 @@ +/* + * 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.container.javascript.rhino; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.mozilla.javascript.Context; +import org.mozilla.javascript.ContextFactory; +import org.mozilla.javascript.ImporterTopLevel; +import org.mozilla.javascript.Script; +import org.mozilla.javascript.Scriptable; + +/** + * A RhinoScript represents a compiled JavaScript script + */ +public class RhinoScript { + + protected String scriptName; + + protected String script; + + protected Scriptable scriptScope; + + protected Map<String, Class> responseClasses; + + protected ClassLoader classLoader; + + /* + * Enable dynamic scopes so a script can be used concurrently with a global shared scope and individual execution scopes. See + * http://www.mozilla.org/rhino/scopes.html + */ + private static class MyFactory extends ContextFactory { + protected boolean hasFeature(Context cx, int featureIndex) { + if (featureIndex == Context.FEATURE_DYNAMIC_SCOPE) { + return true; + } + return super.hasFeature(cx, featureIndex); + } + } + + static { + ContextFactory.initGlobal(new MyFactory()); + } + + /** + * Create a new RhinoScript. + * + * @param scriptName + * the name of the script. Can be anything, only used in messages to identify the script + * @param script + * the complete script + */ + public RhinoScript(String scriptName, String script) { + this(scriptName, script, (Map) null, null); + } + + /** + * Create a new RhinoInvoker. + * + * @param scriptName + * the name of the script. Can be anything, only used in messages to identify the script + * @param script + * the complete script + * @param context + * name-value pairs that are added in to the scope where the script is compiled. May be null. The value objects are made available to + * the script by using a variable with the name. + * @param classLoader + * the ClassLoader Rhino should use to locate any user Java classes used in the script + */ + public RhinoScript(String scriptName, String script, Map context, ClassLoader classLoader) { + this.scriptName = scriptName; + this.script = script; + this.responseClasses = new HashMap<String, Class>(); + this.classLoader = classLoader; + initScriptScope(scriptName, script, context, classLoader); + } + + /** + * Create a new invokeable instance of the script + * + * @return a RhinoScriptInstance + */ + public RhinoScriptInstance createRhinoScriptInstance() { + return createRhinoScriptInstance(null); + } + + /** + * Create a new invokeable instance of the script + * + * @param context + * objects to add to scope of the script instance + * @return a RhinoScriptInstance + */ + public RhinoScriptInstance createRhinoScriptInstance(Map<String, Object> context) { + Scriptable instanceScope = createInstanceScope(context); + RhinoScriptInstance rsi = new RhinoScriptInstance(scriptScope, instanceScope, context, responseClasses); + return rsi; + } + + /** + * Initialize the Rhino Scope for this script instance + */ + public Scriptable createInstanceScope(Map<String, Object> context) { + Context cx = Context.enter(); + try { + + Scriptable instanceScope = cx.newObject(scriptScope); + instanceScope.setPrototype(scriptScope); + instanceScope.setParentScope(null); + + addContexts(instanceScope, context); + + return instanceScope; + + } finally { + Context.exit(); + } + } + + /** + * Create a Rhino scope and compile the script into it + */ + public void initScriptScope(String fileName, String scriptCode, Map context, ClassLoader cl) { + Context cx = Context.enter(); + try { + if (cl != null) { + // TODO: broken with the way the tuscany launcher now uses class loaders + // cx.setApplicationClassLoader(cl); + } + this.scriptScope = new ImporterTopLevel(cx, true); + Script compiledScript = cx.compileString(scriptCode, fileName, 1, null); + compiledScript.exec(cx, scriptScope); + addContexts(scriptScope, context); + + } finally { + Context.exit(); + } + } + + /** + * Add the context to the scope. This will make the objects available to a script by using the name it was added with. + */ + protected void addContexts(Scriptable scope, Map contexts) { + if (contexts != null) { + for (Iterator i = contexts.keySet().iterator(); i.hasNext();) { + String name = (String) i.next(); + Object value = contexts.get(name); + if (value != null) { + scope.put(name, scope, Context.toObject(value, scope)); + } + } + } + } + + public String getScript() { + return script; + } + + public String getScriptName() { + return scriptName; + } + + public Scriptable getScriptScope() { + return scriptScope; + } + + public Map<String, Class> getResponseClasses() { + return responseClasses; + } + + public ClassLoader getClassLoader() { + return classLoader; + } + + /** + * Set the Java type of a response value. JavaScript is dynamically typed so Rhino cannot always work out what the intended Java type of a + * response should be, for example should the statement "return 42" be a Java int, or Integer or Double etc. When Rhino can't determine the type + * it will default to returning a String, using this method enables overriding the Rhino default to use a specific Java type. + */ + public void setResponseClass(String functionName, Class responseClasses) { + this.responseClasses.put(functionName, responseClasses); + } + + public RhinoSCAConfig getSCAConfig() { + return new RhinoSCAConfig(getScriptScope()); + } + + public void setScript(String script) { + this.script = script; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoScriptInstance.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoScriptInstance.java new file mode 100644 index 0000000000..508bc2a90a --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/rhino/RhinoScriptInstance.java @@ -0,0 +1,109 @@ +/* + * 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.container.javascript.rhino; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Function; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.UniqueTag; + +/** + * An invokeable instance of a JavaScript script. + */ +public class RhinoScriptInstance { + + private Scriptable scriptScope; + + private Scriptable instanceScope; + + private Map<String, Class> responseClasses; + + public RhinoScriptInstance(Scriptable scriptScope, Scriptable instanceScope, Map<String, Object> context, Map<String, Class> responseClasses) { + this.scriptScope = scriptScope; + this.instanceScope = instanceScope; + this.responseClasses = responseClasses; + if (this.responseClasses == null) { + this.responseClasses = new HashMap<String, Class>(); + } + addContexts(instanceScope, context); + } + + public Object invokeFunction(String functionName, Object[] args) { + return invokeFunction(functionName, args, null); + } + + public Object invokeFunction(String functionName, Object[] args, Class respClass) { + RhinoFunctionInvoker invoker = createRhinoFunctionInvoker(functionName, respClass); + return invoker.invoke(args); + } + + public RhinoFunctionInvoker createRhinoFunctionInvoker(String functionName) { + return createRhinoFunctionInvoker(functionName, null); + } + + + public RhinoFunctionInvoker createRhinoFunctionInvoker(String functionName, Class responseClass) { + Function function = getFunction(functionName); + //Class responseClass = responseClasses.get(functionName); + RhinoFunctionInvoker invoker = new RhinoFunctionInvoker(instanceScope, function, responseClass); + return invoker; + } + + /** + * Add the context to the scope. This will make the objects available to a script by using the name it was added with. + */ + protected void addContexts(Scriptable scope, Map contexts) { + if (contexts != null) { + Context.enter(); + try { + for (Iterator i = contexts.keySet().iterator(); i.hasNext();) { + String name = (String) i.next(); + Object value = contexts.get(name); + if (value != null) { + scope.put(name, scope, Context.toObject(value, scope)); + } + } + } finally { + Context.exit(); + } + } + } + + /** + * Get the Rhino Function object for the named script function + */ + protected Function getFunction(String functionName) { + + Object handleObj = scriptScope.get(functionName, instanceScope); + if (UniqueTag.NOT_FOUND.equals(handleObj)) { + // Bit of a hack so E4X scripts don't need to define a function for every operation + handleObj = scriptScope.get("process", instanceScope); + } + if (!(handleObj instanceof Function)) { + throw new RuntimeException("script function '" + functionName + "' is undefined or not a function"); + } + + return (Function) handleObj; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/CmdLineArgsHandler.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/CmdLineArgsHandler.java new file mode 100644 index 0000000000..b724b33ac3 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/CmdLineArgsHandler.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.container.javascript.utils.xmlfromxsd; + +/** + * This interface is to be implemented by classes that wish to + * handle commandline arguments. + * + */ +public interface CmdLineArgsHandler { + public void handleArgument(String optionFlag, String argValue) throws IllegalArgumentException; +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/CmdLineArgsProcessor.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/CmdLineArgsProcessor.java new file mode 100644 index 0000000000..914f1d03f2 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/CmdLineArgsProcessor.java @@ -0,0 +1,79 @@ +/* + * 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.container.javascript.utils.xmlfromxsd; + +/** + * This class provides a generic command line arguments processing utility. The processArgs + * method of this class processes the command line arguments that could contain option flags, + * options and values and calls a ArgumentHanlder instance for handling the agruments. + * + */ +public class CmdLineArgsProcessor { + private String printUsageMessage = "No hints available on Usage!"; + + private CmdLineArgsHandler argsHandler = null; + + public static final String HYPEN = "-"; + + public void processArgs(String[] args) { + try { + if (args.length == 0) { + printUsage(); + } else { + parseAndHandleArgs(args); + } + } catch (Exception e) { + System.out.println("Exception in processing argument - " + e); + printUsage(); + } + + } + + public void parseAndHandleArgs(String[] args) throws Exception { + int index = 0; + while (index < args.length - 1) { + if (args[index].startsWith(HYPEN) && !args[index + 1].startsWith(HYPEN)) { + argsHandler.handleArgument(args[index].substring(1), args[index + 1]); + index = index + 2; + } else { + throw new IllegalArgumentException("Wrong Usage of options!"); + } + } + } + + protected void printUsage() { + + } + + public CmdLineArgsHandler getArgsHandler() { + return argsHandler; + } + + public void setArgsHandler(CmdLineArgsHandler argsHandler) { + this.argsHandler = argsHandler; + } + + public String getPrintUsageMessage() { + return printUsageMessage; + } + + public void setPrintUsageMessage(String printUsageMessage) { + this.printUsageMessage = printUsageMessage; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/TuscanySampleXmlUtil.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/TuscanySampleXmlUtil.java new file mode 100644 index 0000000000..a0155c76e6 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/TuscanySampleXmlUtil.java @@ -0,0 +1,1097 @@ +/* + * 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.container.javascript.utils.xmlfromxsd; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaLocalElement; +import org.apache.xmlbeans.SchemaProperty; +import org.apache.xmlbeans.GDuration; +import org.apache.xmlbeans.GDurationBuilder; +import org.apache.xmlbeans.GDate; +import org.apache.xmlbeans.GDateBuilder; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.SimpleValue; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlInteger; +import org.apache.xmlbeans.XmlDate; +import org.apache.xmlbeans.XmlDateTime; +import org.apache.xmlbeans.XmlTime; +import org.apache.xmlbeans.XmlGYear; +import org.apache.xmlbeans.XmlGYearMonth; +import org.apache.xmlbeans.XmlGMonth; +import org.apache.xmlbeans.XmlGMonthDay; +import org.apache.xmlbeans.XmlGDay; +import org.apache.xmlbeans.XmlDecimal; +import org.apache.xmlbeans.XmlDuration; +import org.apache.xmlbeans.soap.SchemaWSDLArrayType; +import org.apache.xmlbeans.soap.SOAPArrayType; +import org.apache.xmlbeans.impl.util.Base64; +import org.apache.xmlbeans.impl.util.HexBin; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.Random; +import java.util.Set; +import java.util.HashSet; +import java.util.Arrays; + +import javax.xml.namespace.QName; + +/** + * This class is a replication of the XMLBeans SampleXMLutil class. This replication + * is required to overide the XMLBeans behaviour of this class in certain places. Since + * most methods of the XMLBeans implementation of this class is private, no overiding + * has been possible using inheritance. Hence this replication. + * + */ +public class TuscanySampleXmlUtil { + private static final String BLANK_STRING = " "; + + private boolean generate_sample_data = false; + + private boolean _soapEnc; + + private static final int MAX_ELEMENTS = 1000; + + private int _nElements; + + boolean flag = true; + + private TuscanySampleXmlUtil(boolean soapEnc) { + _soapEnc = soapEnc; + } + + public TuscanySampleXmlUtil() { + this(false); + } + + public String createSampleForType(SchemaType sType) { + XmlObject object = XmlObject.Factory.newInstance(); + XmlCursor cursor = object.newCursor(); + // Skip the document node + cursor.toNextToken(); + // Using the type and the cursor, call the utility method to get a + // sample XML payload for that Schema element + createSampleForType(sType, cursor); + // Cursor now contains the sample payload + // Pretty print the result. Note that the cursor is positioned at the + // end of the doc so we use the original xml object that the cursor was + // created upon to do the xmlText() against. + XmlOptions options = new XmlOptions(); + options.put(XmlOptions.SAVE_PRETTY_PRINT); + options.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, 2); + options.put(XmlOptions.SAVE_AGGRESSIVE_NAMESPACES); + String result = object.xmlText(options); + return result; + } + + Random _picker = new Random(1); + + /** + * Cursor position + * Before: + * <theElement>^</theElement> + * After: + * <theElement><lots of stuff/>^</theElement> + */ + private void createSampleForType(SchemaType stype, XmlCursor xmlc) { + if (_typeStack.contains(stype)) + //if ( !flag ) + return; + //else + // flag = false; + + _typeStack.add(stype); + + try { + if (stype.isSimpleType() || stype.isURType()) { + processSimpleType(stype, xmlc); + return; + } + + // complex Type + // <theElement>^</theElement> + processAttributes(stype, xmlc); + + // <theElement attri1="string">^</theElement> + switch (stype.getContentType()) { + case SchemaType.NOT_COMPLEX_TYPE: + case SchemaType.EMPTY_CONTENT: + // noop + break; + case SchemaType.SIMPLE_CONTENT: { + processSimpleType(stype, xmlc); + } + break; + case SchemaType.MIXED_CONTENT: + if (isGenerate_sample_data()) + xmlc.insertChars(pick(WORDS) + " "); + if (stype.getContentModel() != null) { + processParticle(stype.getContentModel(), xmlc, true); + } + if (isGenerate_sample_data()) + xmlc.insertChars(pick(WORDS)); + + break; + case SchemaType.ELEMENT_CONTENT: + if (stype.getContentModel() != null) { + processParticle(stype.getContentModel(), xmlc, false); + } + break; + } + } finally { + _typeStack.remove(_typeStack.size() - 1); + } + } + + private void processSimpleType(SchemaType stype, XmlCursor xmlc) { + String sample = sampleDataForSimpleType(stype); + xmlc.insertChars(sample); + + } + + private String sampleDataForSimpleType(SchemaType sType) { + if (isGenerate_sample_data()) { + return generateSampleDataForSimpleType(sType); + } else { + return BLANK_STRING; + } + } + + private String generateSampleDataForSimpleType(SchemaType sType) { + if (XmlObject.type.equals(sType)) + return "anyType"; + + if (XmlAnySimpleType.type.equals(sType)) + return "anySimpleType"; + + if (sType.getSimpleVariety() == SchemaType.LIST) { + SchemaType itemType = sType.getListItemType(); + StringBuffer sb = new StringBuffer(); + int length = pickLength(sType); + if (length > 0) + sb.append(sampleDataForSimpleType(itemType)); + for (int i = 1; i < length; i += 1) { + sb.append(' '); + sb.append(sampleDataForSimpleType(itemType)); + } + return sb.toString(); + } + + if (sType.getSimpleVariety() == SchemaType.UNION) { + SchemaType[] possibleTypes = sType.getUnionConstituentTypes(); + if (possibleTypes.length == 0) + return ""; + return sampleDataForSimpleType(possibleTypes[pick(possibleTypes.length)]); + } + + XmlAnySimpleType[] enumValues = sType.getEnumerationValues(); + if (enumValues != null && enumValues.length > 0) { + return enumValues[pick(enumValues.length)].getStringValue(); + } + + switch (sType.getPrimitiveType().getBuiltinTypeCode()) { + default: + case SchemaType.BTC_NOT_BUILTIN: + return ""; + + case SchemaType.BTC_ANY_TYPE: + case SchemaType.BTC_ANY_SIMPLE: + return "anything"; + + case SchemaType.BTC_BOOLEAN: + return pick(2) == 0 ? "true" : "false"; + + case SchemaType.BTC_BASE_64_BINARY: { + String result = null; + try { + result = new String(Base64.encode(formatToLength(pick(WORDS), sType).getBytes("utf-8"))); + } catch (java.io.UnsupportedEncodingException e) { /* Can't possibly happen */ + } + return result; + } + + case SchemaType.BTC_HEX_BINARY: + return HexBin.encode(formatToLength(pick(WORDS), sType)); + + case SchemaType.BTC_ANY_URI: + return formatToLength("http://www." + pick(DNS1) + "." + pick(DNS2) + "/" + pick(WORDS) + "/" + pick(WORDS), sType); + + case SchemaType.BTC_QNAME: + return formatToLength("qname", sType); + + case SchemaType.BTC_NOTATION: + return formatToLength("notation", sType); + + case SchemaType.BTC_FLOAT: + return "1.5E2"; + case SchemaType.BTC_DOUBLE: + return "1.051732E7"; + case SchemaType.BTC_DECIMAL: + switch (closestBuiltin(sType).getBuiltinTypeCode()) { + case SchemaType.BTC_SHORT: + return formatDecimal("1", sType); + case SchemaType.BTC_UNSIGNED_SHORT: + return formatDecimal("5", sType); + case SchemaType.BTC_BYTE: + return formatDecimal("2", sType); + case SchemaType.BTC_UNSIGNED_BYTE: + return formatDecimal("6", sType); + case SchemaType.BTC_INT: + return formatDecimal("3", sType); + case SchemaType.BTC_UNSIGNED_INT: + return formatDecimal("7", sType); + case SchemaType.BTC_LONG: + return formatDecimal("10", sType); + case SchemaType.BTC_UNSIGNED_LONG: + return formatDecimal("11", sType); + case SchemaType.BTC_INTEGER: + return formatDecimal("100", sType); + case SchemaType.BTC_NON_POSITIVE_INTEGER: + return formatDecimal("-200", sType); + case SchemaType.BTC_NEGATIVE_INTEGER: + return formatDecimal("-201", sType); + case SchemaType.BTC_NON_NEGATIVE_INTEGER: + return formatDecimal("200", sType); + case SchemaType.BTC_POSITIVE_INTEGER: + return formatDecimal("201", sType); + default: + case SchemaType.BTC_DECIMAL: + return formatDecimal("1000.00", sType); + } + + case SchemaType.BTC_STRING: { + String result; + switch (closestBuiltin(sType).getBuiltinTypeCode()) { + case SchemaType.BTC_STRING: + case SchemaType.BTC_NORMALIZED_STRING: + result = "string"; + break; + + case SchemaType.BTC_TOKEN: + result = "token"; + break; + + default: + result = "string"; + break; + } + + return formatToLength(result, sType); + } + + case SchemaType.BTC_DURATION: + return formatDuration(sType); + + case SchemaType.BTC_DATE_TIME: + case SchemaType.BTC_TIME: + case SchemaType.BTC_DATE: + case SchemaType.BTC_G_YEAR_MONTH: + case SchemaType.BTC_G_YEAR: + case SchemaType.BTC_G_MONTH_DAY: + case SchemaType.BTC_G_DAY: + case SchemaType.BTC_G_MONTH: + return formatDate(sType); + } + } + + // a bit from the Aenid + public static final String[] WORDS = new String[] { "ipsa", "iovis", "rapidum", "iaculata", "e", "nubibus", "ignem", "disiecitque", "rates", + "evertitque", "aequora", "ventis", "illum", "exspirantem", "transfixo", "pectore", "flammas", "turbine", "corripuit", "scopuloque", + "infixit", "acuto", "ast", "ego", "quae", "divum", "incedo", "regina", "iovisque", "et", "soror", "et", "coniunx", "una", "cum", "gente", + "tot", "annos", "bella", "gero", "et", "quisquam", "numen", "iunonis", "adorat", "praeterea", "aut", "supplex", "aris", "imponet", + "honorem", "talia", "flammato", "secum", "dea", "corde", "volutans", "nimborum", "in", "patriam", "loca", "feta", "furentibus", + "austris", "aeoliam", "venit", "hic", "vasto", "rex", "aeolus", "antro", "luctantis", "ventos", "tempestatesque", "sonoras", "imperio", + "premit", "ac", "vinclis", "et", "carcere", "frenat", "illi", "indignantes", "magno", "cum", "murmure", "montis", "circum", "claustra", + "fremunt", "celsa", "sedet", "aeolus", "arce", "sceptra", "tenens", "mollitque", "animos", "et", "temperat", "iras", "ni", "faciat", + "maria", "ac", "terras", "caelumque", "profundum", "quippe", "ferant", "rapidi", "secum", "verrantque", "per", "auras", "sed", "pater", + "omnipotens", "speluncis", "abdidit", "atris", "hoc", "metuens", "molemque", "et", "montis", "insuper", "altos", "imposuit", "regemque", + "dedit", "qui", "foedere", "certo", "et", "premere", "et", "laxas", "sciret", "dare", "iussus", "habenas", }; + + private static final String[] DNS1 = new String[] { "corp", "your", "my", "sample", "company", "test", "any" }; + + private static final String[] DNS2 = new String[] { "com", "org", "com", "gov", "org", "com", "org", "com", "edu" }; + + private int pick(int n) { + return _picker.nextInt(n); + } + + private String pick(String[] a) { + return a[pick(a.length)]; + } + + private String pick(String[] a, int count) { + if (count <= 0) + return ""; + + int i = pick(a.length); + StringBuffer sb = new StringBuffer(a[i]); + while (count-- > 0) { + i += 1; + if (i >= a.length) + i = 0; + sb.append(' '); + sb.append(a[i]); + } + return sb.toString(); + } + + private String pickDigits(int digits) { + StringBuffer sb = new StringBuffer(); + while (digits-- > 0) + sb.append(Integer.toString(pick(10))); + return sb.toString(); + } + + private int pickLength(SchemaType sType) { + XmlInteger length = (XmlInteger) sType.getFacet(SchemaType.FACET_LENGTH); + if (length != null) + return length.getBigIntegerValue().intValue(); + XmlInteger min = (XmlInteger) sType.getFacet(SchemaType.FACET_MIN_LENGTH); + XmlInteger max = (XmlInteger) sType.getFacet(SchemaType.FACET_MAX_LENGTH); + int minInt, maxInt; + if (min == null) + minInt = 0; + else + minInt = min.getBigIntegerValue().intValue(); + if (max == null) + maxInt = Integer.MAX_VALUE; + else + maxInt = max.getBigIntegerValue().intValue(); + // We try to keep the length of the array within reasonable limits, + // at least 1 item and at most 3 if possible + if (minInt == 0 && maxInt >= 1) + minInt = 1; + if (maxInt > minInt + 2) + maxInt = minInt + 2; + if (maxInt < minInt) + maxInt = minInt; + return minInt + pick(maxInt - minInt); + } + + /** + * Formats a given string to the required length, using the following operations: + * - append the source string to itself as necessary to pass the minLength; + * - truncate the result of previous step, if necessary, to keep it within minLength. + */ + private String formatToLength(String s, SchemaType sType) { + String result = s; + try { + SimpleValue min = (SimpleValue) sType.getFacet(SchemaType.FACET_LENGTH); + if (min == null) + min = (SimpleValue) sType.getFacet(SchemaType.FACET_MIN_LENGTH); + if (min != null) { + int len = min.getIntValue(); + while (result.length() < len) + result = result + result; + } + SimpleValue max = (SimpleValue) sType.getFacet(SchemaType.FACET_LENGTH); + if (max == null) + max = (SimpleValue) sType.getFacet(SchemaType.FACET_MAX_LENGTH); + if (max != null) { + int len = max.getIntValue(); + if (result.length() > len) + result = result.substring(0, len); + } + } catch (Exception e) // intValue can be out of range + { + } + return result; + } + + private String formatDecimal(String start, SchemaType sType) { + BigDecimal result = new BigDecimal(start); + XmlDecimal xmlD; + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + BigDecimal min = xmlD != null ? xmlD.getBigDecimalValue() : null; + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + BigDecimal max = xmlD != null ? xmlD.getBigDecimalValue() : null; + boolean minInclusive = true, maxInclusive = true; + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (xmlD != null) { + BigDecimal minExcl = xmlD.getBigDecimalValue(); + if (min == null || min.compareTo(minExcl) < 0) { + min = minExcl; + minInclusive = false; + } + } + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (xmlD != null) { + BigDecimal maxExcl = xmlD.getBigDecimalValue(); + if (max == null || max.compareTo(maxExcl) > 0) { + max = maxExcl; + maxInclusive = false; + } + } + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_TOTAL_DIGITS); + int totalDigits = -1; + if (xmlD != null) { + totalDigits = xmlD.getBigDecimalValue().intValue(); + + StringBuffer sb = new StringBuffer(totalDigits); + for (int i = 0; i < totalDigits; i++) + sb.append('9'); + BigDecimal digitsLimit = new BigDecimal(sb.toString()); + if (max != null && max.compareTo(digitsLimit) > 0) { + max = digitsLimit; + maxInclusive = true; + } + digitsLimit = digitsLimit.negate(); + if (min != null && min.compareTo(digitsLimit) < 0) { + min = digitsLimit; + minInclusive = true; + } + } + + int sigMin = min == null ? 1 : result.compareTo(min); + int sigMax = max == null ? -1 : result.compareTo(max); + boolean minOk = sigMin > 0 || sigMin == 0 && minInclusive; + boolean maxOk = sigMax < 0 || sigMax == 0 && maxInclusive; + + // Compute the minimum increment + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_FRACTION_DIGITS); + int fractionDigits = -1; + BigDecimal increment; + if (xmlD == null) + increment = new BigDecimal(1); + else { + fractionDigits = xmlD.getBigDecimalValue().intValue(); + if (fractionDigits > 0) { + StringBuffer sb = new StringBuffer("0."); + for (int i = 1; i < fractionDigits; i++) + sb.append('0'); + sb.append('1'); + increment = new BigDecimal(sb.toString()); + } else + increment = new BigDecimal(1.0); + } + + if (minOk && maxOk) { + // OK + } else if (minOk && !maxOk) { + // TOO BIG + if (maxInclusive) + result = max; + else + result = max.subtract(increment); + } else if (!minOk && maxOk) { + // TOO SMALL + if (minInclusive) + result = min; + else + result = min.add(increment); + } else { + // MIN > MAX!! + } + + // We have the number + // Adjust the scale according to the totalDigits and fractionDigits + int digits = 0; + BigDecimal ONE = new BigDecimal(BigInteger.ONE); + for (BigDecimal n = result; n.abs().compareTo(ONE) >= 0; digits++) + n = n.movePointLeft(1); + + if (fractionDigits > 0) + if (totalDigits >= 0) + result.setScale(Math.max(fractionDigits, totalDigits - digits)); + else + result.setScale(fractionDigits); + else if (fractionDigits == 0) + result.setScale(0); + + return result.toString(); + } + + private String formatDuration(SchemaType sType) { + XmlDuration d = (XmlDuration) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + GDuration minInclusive = null; + if (d != null) + minInclusive = d.getGDurationValue(); + + d = (XmlDuration) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + GDuration maxInclusive = null; + if (d != null) + maxInclusive = d.getGDurationValue(); + + d = (XmlDuration) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + GDuration minExclusive = null; + if (d != null) + minExclusive = d.getGDurationValue(); + + d = (XmlDuration) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + GDuration maxExclusive = null; + if (d != null) + maxExclusive = d.getGDurationValue(); + + GDurationBuilder gdurb = new GDurationBuilder(); + BigInteger min, max; + + gdurb.setSecond(pick(800000)); + gdurb.setMonth(pick(20)); + + // Years + // Months + // Days + // Hours + // Minutes + // Seconds + // Fractions + if (minInclusive != null) { + if (gdurb.getYear() < minInclusive.getYear()) + gdurb.setYear(minInclusive.getYear()); + if (gdurb.getMonth() < minInclusive.getMonth()) + gdurb.setMonth(minInclusive.getMonth()); + if (gdurb.getDay() < minInclusive.getDay()) + gdurb.setDay(minInclusive.getDay()); + if (gdurb.getHour() < minInclusive.getHour()) + gdurb.setHour(minInclusive.getHour()); + if (gdurb.getMinute() < minInclusive.getMinute()) + gdurb.setMinute(minInclusive.getMinute()); + if (gdurb.getSecond() < minInclusive.getSecond()) + gdurb.setSecond(minInclusive.getSecond()); + if (gdurb.getFraction().compareTo(minInclusive.getFraction()) < 0) + gdurb.setFraction(minInclusive.getFraction()); + } + + if (maxInclusive != null) { + if (gdurb.getYear() > maxInclusive.getYear()) + gdurb.setYear(maxInclusive.getYear()); + if (gdurb.getMonth() > maxInclusive.getMonth()) + gdurb.setMonth(maxInclusive.getMonth()); + if (gdurb.getDay() > maxInclusive.getDay()) + gdurb.setDay(maxInclusive.getDay()); + if (gdurb.getHour() > maxInclusive.getHour()) + gdurb.setHour(maxInclusive.getHour()); + if (gdurb.getMinute() > maxInclusive.getMinute()) + gdurb.setMinute(maxInclusive.getMinute()); + if (gdurb.getSecond() > maxInclusive.getSecond()) + gdurb.setSecond(maxInclusive.getSecond()); + if (gdurb.getFraction().compareTo(maxInclusive.getFraction()) > 0) + gdurb.setFraction(maxInclusive.getFraction()); + } + + if (minExclusive != null) { + if (gdurb.getYear() <= minExclusive.getYear()) + gdurb.setYear(minExclusive.getYear() + 1); + if (gdurb.getMonth() <= minExclusive.getMonth()) + gdurb.setMonth(minExclusive.getMonth() + 1); + if (gdurb.getDay() <= minExclusive.getDay()) + gdurb.setDay(minExclusive.getDay() + 1); + if (gdurb.getHour() <= minExclusive.getHour()) + gdurb.setHour(minExclusive.getHour() + 1); + if (gdurb.getMinute() <= minExclusive.getMinute()) + gdurb.setMinute(minExclusive.getMinute() + 1); + if (gdurb.getSecond() <= minExclusive.getSecond()) + gdurb.setSecond(minExclusive.getSecond() + 1); + if (gdurb.getFraction().compareTo(minExclusive.getFraction()) <= 0) + gdurb.setFraction(minExclusive.getFraction().add(new BigDecimal(0.001))); + } + + if (maxExclusive != null) { + if (gdurb.getYear() > maxExclusive.getYear()) + gdurb.setYear(maxExclusive.getYear()); + if (gdurb.getMonth() > maxExclusive.getMonth()) + gdurb.setMonth(maxExclusive.getMonth()); + if (gdurb.getDay() > maxExclusive.getDay()) + gdurb.setDay(maxExclusive.getDay()); + if (gdurb.getHour() > maxExclusive.getHour()) + gdurb.setHour(maxExclusive.getHour()); + if (gdurb.getMinute() > maxExclusive.getMinute()) + gdurb.setMinute(maxExclusive.getMinute()); + if (gdurb.getSecond() > maxExclusive.getSecond()) + gdurb.setSecond(maxExclusive.getSecond()); + if (gdurb.getFraction().compareTo(maxExclusive.getFraction()) > 0) + gdurb.setFraction(maxExclusive.getFraction()); + } + + gdurb.normalize(); + return gdurb.toString(); + } + + private String formatDate(SchemaType sType) { + GDateBuilder gdateb = new GDateBuilder(new Date(1000L * pick(365 * 24 * 60 * 60) + (30L + pick(20)) * 365 * 24 * 60 * 60 * 1000)); + GDate min = null, max = null; + GDate temp; + + // Find the min and the max according to the type + switch (sType.getPrimitiveType().getBuiltinTypeCode()) { + case SchemaType.BTC_DATE_TIME: { + XmlDateTime x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_TIME: { + XmlTime x = (XmlTime) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlTime) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlTime) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlTime) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_DATE: { + XmlDate x = (XmlDate) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlDate) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlDate) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlDate) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_YEAR_MONTH: { + XmlGYearMonth x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_YEAR: { + XmlGYear x = (XmlGYear) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGYear) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGYear) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGYear) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_MONTH_DAY: { + XmlGMonthDay x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_DAY: { + XmlGDay x = (XmlGDay) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGDay) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGDay) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGDay) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_MONTH: { + XmlGMonth x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + } + + if (min != null && max == null) { + if (min.compareToGDate(gdateb) >= 0) { + // Reset the date to min + (1-8) hours + Calendar c = gdateb.getCalendar(); + c.add(Calendar.HOUR_OF_DAY, pick(8)); + gdateb = new GDateBuilder(c); + } + } else if (min == null && max != null) { + if (max.compareToGDate(gdateb) <= 0) { + // Reset the date to max - (1-8) hours + Calendar c = gdateb.getCalendar(); + c.add(Calendar.HOUR_OF_DAY, 0 - pick(8)); + gdateb = new GDateBuilder(c); + } + } else if (min != null && max != null) { + if (min.compareToGDate(gdateb) >= 0 || max.compareToGDate(gdateb) <= 0) { + // Find a date between the two + Calendar c = min.getCalendar(); + Calendar cmax = max.getCalendar(); + c.add(Calendar.HOUR_OF_DAY, 1); + if (c.after(cmax)) { + c.add(Calendar.HOUR_OF_DAY, -1); + c.add(Calendar.MINUTE, 1); + if (c.after(cmax)) { + c.add(Calendar.MINUTE, -1); + c.add(Calendar.SECOND, 1); + if (c.after(cmax)) { + c.add(Calendar.SECOND, -1); + c.add(Calendar.MILLISECOND, 1); + if (c.after(cmax)) + c.add(Calendar.MILLISECOND, -1); + } + } + } + gdateb = new GDateBuilder(c); + } + } + + gdateb.setBuiltinTypeCode(sType.getPrimitiveType().getBuiltinTypeCode()); + if (pick(2) == 0) + gdateb.clearTimeZone(); + return gdateb.toString(); + } + + private SchemaType closestBuiltin(SchemaType sType) { + while (!sType.isBuiltinType()) + sType = sType.getBaseType(); + return sType; + } + + /** + * Cracks a combined QName of the form URL:localname + */ + public static QName crackQName(String qName) { + String ns; + String name; + + int index = qName.lastIndexOf(':'); + if (index >= 0) { + ns = qName.substring(0, index); + name = qName.substring(index + 1); + } else { + ns = ""; + name = qName; + } + + return new QName(ns, name); + } + + /** + * Cursor position: + * Before this call: + * <outer><foo/>^</outer> (cursor at the ^) + * After this call: + * <<outer><foo/><bar/>som text<etc/>^</outer> + */ + private void processParticle(SchemaParticle sp, XmlCursor xmlc, boolean mixed) { + int loop = determineMinMaxForSample(sp, xmlc); + + while (loop-- > 0) { + switch (sp.getParticleType()) { + case (SchemaParticle.ELEMENT): + processElement(sp, xmlc, mixed); + break; + case (SchemaParticle.SEQUENCE): + processSequence(sp, xmlc, mixed); + break; + case (SchemaParticle.CHOICE): + processChoice(sp, xmlc, mixed); + break; + case (SchemaParticle.ALL): + processAll(sp, xmlc, mixed); + break; + case (SchemaParticle.WILDCARD): + processWildCard(sp, xmlc, mixed); + break; + default: + // throw new Exception("No Match on Schema Particle Type: " + String.valueOf(sp.getParticleType())); + } + } + } + + private int determineMinMaxForSample(SchemaParticle sp, XmlCursor xmlc) { + int minOccurs = sp.getIntMinOccurs(); + int maxOccurs = sp.getIntMaxOccurs(); + + if (minOccurs == maxOccurs) + return minOccurs; + + int result = minOccurs; + if (result == 0 && _nElements < MAX_ELEMENTS) + result = 1; + + if (sp.getParticleType() != SchemaParticle.ELEMENT) + return result; + + // it probably only makes sense to put comments in front of individual elements that repeat + + if (sp.getMaxOccurs() == null) { + // xmlc.insertComment("The next " + getItemNameOrType(sp, xmlc) + " may be repeated " + minOccurs + " or more times"); + if (minOccurs == 0) + xmlc.insertComment("Zero or more repetitions:"); + else + xmlc.insertComment(minOccurs + " or more repetitions:"); + } else if (sp.getIntMaxOccurs() > 1) { + xmlc.insertComment(minOccurs + " to " + String.valueOf(sp.getMaxOccurs()) + " repetitions:"); + } else { + xmlc.insertComment("Optional:"); + } + return result; + } + + /* + Return a name for the element or the particle type to use in the comment for minoccurs, max occurs + */ + private String getItemNameOrType(SchemaParticle sp, XmlCursor xmlc) { + String elementOrTypeName = null; + if (sp.getParticleType() == SchemaParticle.ELEMENT) { + elementOrTypeName = "Element (" + sp.getName().getLocalPart() + ")"; + } else { + elementOrTypeName = printParticleType(sp.getParticleType()); + } + return elementOrTypeName; + } + + private void processElement(SchemaParticle sp, XmlCursor xmlc, boolean mixed) { + // cast as schema local element + SchemaLocalElement element = (SchemaLocalElement) sp; + /// ^ -> <elemenname></elem>^ + if (_soapEnc) + xmlc.insertElement(element.getName().getLocalPart()); // soap encoded? drop namespaces. + else + xmlc.insertElement(element.getName().getLocalPart(), element.getName().getNamespaceURI()); + _nElements++; + /// -> <elem>^</elem> + xmlc.toPrevToken(); + // -> <elem>stuff^</elem> + createSampleForType(element.getType(), xmlc); + // -> <elem>stuff</elem>^ + xmlc.toNextToken(); + + } + + private void moveToken(int numToMove, XmlCursor xmlc) { + for (int i = 0; i < Math.abs(numToMove); i++) { + if (numToMove < 0) { + xmlc.toPrevToken(); + } else { + xmlc.toNextToken(); + } + } + } + + private static final String formatQName(XmlCursor xmlc, QName qName) { + XmlCursor parent = xmlc.newCursor(); + parent.toParent(); + String prefix = parent.prefixForNamespace(qName.getNamespaceURI()); + parent.dispose(); + String name; + if (prefix == null || prefix.length() == 0) + name = qName.getLocalPart(); + else + name = prefix + ":" + qName.getLocalPart(); + return name; + } + + private static final QName HREF = new QName("href"); + + private static final QName ID = new QName("id"); + + private static final QName XSI_TYPE = new QName("http://www.w3.org/2001/XMLSchema-instance", "type"); + + private static final QName ENC_ARRAYTYPE = new QName("http://schemas.xmlsoap.org/soap/encoding/", "arrayType"); + + private static final QName ENC_OFFSET = new QName("http://schemas.xmlsoap.org/soap/encoding/", "offset"); + + private static final Set SKIPPED_SOAP_ATTRS = new HashSet(Arrays.asList(new QName[] { HREF, ID, ENC_OFFSET })); + + private void processAttributes(SchemaType stype, XmlCursor xmlc) { + if (_soapEnc) { + QName typeName = stype.getName(); + if (typeName != null) { + xmlc.insertAttributeWithValue(XSI_TYPE, formatQName(xmlc, typeName)); + } + } + + SchemaProperty[] attrProps = stype.getAttributeProperties(); + for (int i = 0; i < attrProps.length; i++) { + SchemaProperty attr = attrProps[i]; + if (_soapEnc) { + if (SKIPPED_SOAP_ATTRS.contains(attr.getName())) + continue; + if (ENC_ARRAYTYPE.equals(attr.getName())) { + SOAPArrayType arrayType = ((SchemaWSDLArrayType) stype.getAttributeModel().getAttribute(attr.getName())).getWSDLArrayType(); + if (arrayType != null) + xmlc.insertAttributeWithValue(attr.getName(), formatQName(xmlc, arrayType.getQName()) + arrayType.soap11DimensionString()); + continue; + } + } + String defaultValue = attr.getDefaultText(); + xmlc.insertAttributeWithValue(attr.getName(), defaultValue == null ? sampleDataForSimpleType(attr.getType()) : defaultValue); + } + } + + private void processSequence(SchemaParticle sp, XmlCursor xmlc, boolean mixed) { + SchemaParticle[] spc = sp.getParticleChildren(); + for (int i = 0; i < spc.length; i++) { + /// <parent>maybestuff^</parent> + processParticle(spc[i], xmlc, mixed); + //<parent>maybestuff...morestuff^</parent> + if (mixed && i < spc.length - 1) { + if (isGenerate_sample_data()) { + xmlc.insertChars(pick(WORDS)); + } else { + xmlc.insertChars(""); + } + } + } + } + + private void processChoice(SchemaParticle sp, XmlCursor xmlc, boolean mixed) { + SchemaParticle[] spc = sp.getParticleChildren(); + xmlc.insertComment("You have a CHOICE of the next " + String.valueOf(spc.length) + " items at this level"); + for (int i = 0; i < spc.length; i++) { + processParticle(spc[i], xmlc, mixed); + } + } + + private void processAll(SchemaParticle sp, XmlCursor xmlc, boolean mixed) { + SchemaParticle[] spc = sp.getParticleChildren(); + // xmlc.insertComment("You may enter the following " + String.valueOf(spc.length) + " items in any order"); + for (int i = 0; i < spc.length; i++) { + processParticle(spc[i], xmlc, mixed); + if (mixed && i < spc.length - 1) + xmlc.insertChars(pick(WORDS)); + } + } + + private void processWildCard(SchemaParticle sp, XmlCursor xmlc, boolean mixed) { + xmlc.insertComment("You may enter ANY elements at this point"); + xmlc.insertElement("AnyElement"); + } + + /** + * This method will get the base type for the schema type + */ + + private static QName getClosestName(SchemaType sType) { + while (sType.getName() == null) + sType = sType.getBaseType(); + + return sType.getName(); + } + + private String printParticleType(int particleType) { + StringBuffer returnParticleType = new StringBuffer(); + returnParticleType.append("Schema Particle Type: "); + + switch (particleType) { + case SchemaParticle.ALL: + returnParticleType.append("ALL\n"); + break; + case SchemaParticle.CHOICE: + returnParticleType.append("CHOICE\n"); + break; + case SchemaParticle.ELEMENT: + returnParticleType.append("ELEMENT\n"); + break; + case SchemaParticle.SEQUENCE: + returnParticleType.append("SEQUENCE\n"); + break; + case SchemaParticle.WILDCARD: + returnParticleType.append("WILDCARD\n"); + break; + default: + returnParticleType.append("Schema Particle Type Unknown"); + break; + } + + return returnParticleType.toString(); + } + + private ArrayList _typeStack = new ArrayList(); + + public boolean isGenerate_sample_data() { + return generate_sample_data; + } + + public void setGenerate_sample_data(boolean generate_sample_data) { + this.generate_sample_data = generate_sample_data; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XBbasedXMLGenerator.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XBbasedXMLGenerator.java new file mode 100644 index 0000000000..128d65cecd --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XBbasedXMLGenerator.java @@ -0,0 +1,253 @@ +/* + * 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.container.javascript.utils.xmlfromxsd; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; + +import javax.wsdl.Definition; +import javax.wsdl.WSDLException; +import javax.wsdl.extensions.schema.Schema; +import javax.wsdl.factory.WSDLFactory; +import javax.wsdl.xml.WSDLReader; +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.impl.xsd2inst.SchemaInstanceGenerator; +import org.xml.sax.InputSource; + +import com.ibm.wsdl.util.xml.DOM2Writer; + +public class XBbasedXMLGenerator extends SchemaInstanceGenerator implements XMLGenerator { + private XMLfromXSDConfiguration config = null; + + public static final String QNAME_SEPARATOR = "#"; + + public XBbasedXMLGenerator(XMLfromXSDConfiguration config) { + this.config = config; + // config.setXsdInputStream(getClass().getResource(conf).openStream()); + } + + public Hashtable<String, XmlObject> generateXmlAll() throws Exception { + Hashtable<String, XmlObject> xmlInstances = new Hashtable<String, XmlObject>(); + TuscanySampleXmlUtil xmlUtil = new TuscanySampleXmlUtil(); + xmlUtil.setGenerate_sample_data(config.isGenerateSampleData()); + SchemaTypeSystem sts = processXSDSources(); + SchemaType elementType = null; + for (SchemaGlobalElement globalElement : sts.globalElements()) { + elementType = getRootElementSchemaType(sts, globalElement.getName().getNamespaceURI(), globalElement.getName().getLocalPart()); + xmlInstances.put(makeQName(globalElement.getName()), XmlObject.Factory.parse(xmlUtil.createSampleForType(elementType))); + } + + return xmlInstances; + } + + public String generateXMLAsString() throws Exception { + SchemaTypeSystem sts = processXSDSources(); + SchemaType rootElementType = getRootElementSchemaType(sts, config.getSchemaTypeNamespaceURI(), config.getSchemaTypeName()); + String result = ""; + if (rootElementType != null) { + TuscanySampleXmlUtil xmlUtil = new TuscanySampleXmlUtil(); + xmlUtil.setGenerate_sample_data(config.isGenerateSampleData()); + result = xmlUtil.createSampleForType(rootElementType); + } else { + System.out.println("Could not find a global element with name \"" + config.getRootElementLocalName() + "\""); + } + return result; + } + + public void generateXMLIntoOutputStream() throws Exception { + config.getXmlOutputStream().write(generateXMLAsString().getBytes()); + } + + public void generateXML() throws Exception { + SchemaTypeSystem sts = processXSDSources(); + + SchemaType rootElementType = getRootElementSchemaType(sts, config.getSchemaTypeNamespaceURI(), config.getSchemaTypeName()); + + if (rootElementType != null) { + TuscanySampleXmlUtil xmlUtil = new TuscanySampleXmlUtil(); + xmlUtil.setGenerate_sample_data(config.isGenerateSampleData()); + String result = xmlUtil.createSampleForType(rootElementType); + config.getXmlOutputStream().write(result.getBytes()); + // System.out.println(result); + } else { + System.out.println("Could not find a global element with name \"" + config.getRootElementLocalName() + "\""); + } + } + + protected SchemaType getRootElementSchemaType(SchemaTypeSystem sts, String schemaNamespace, String schemaTypeName) { + SchemaType schemaType = null; + + if (sts == null) { + System.out.println("No Schemas to process."); + } else { + // first check in the global types + SchemaType[] globalTypes = sts.globalTypes(); + for (int i = 0; i < globalTypes.length; i++) { + if (schemaNamespace.equals(globalTypes[i].getName().getNamespaceURI()) + && schemaTypeName.equals(globalTypes[i].getName().getLocalPart())) { + schemaType = globalTypes[i]; + break; + } + } + + // next check for anonymous types defined inline within elements + if (schemaType == null) { + SchemaType[] globalElems = sts.documentTypes(); + for (int i = 0; i < globalElems.length; i++) { + if (schemaNamespace.equals(globalElems[i].getDocumentElementName().getNamespaceURI()) + && schemaTypeName.equals(globalElems[i].getDocumentElementName().getLocalPart())) { + schemaType = globalElems[i]; + break; + } + } + } + } + return schemaType; + } + + public void generateXML(XMLfromXSDConfiguration config) throws Exception { + this.config = config; + generateXML(); + } + + public XMLfromXSDConfiguration getConfig() { + return config; + } + + public void setConfig(XMLfromXSDConfiguration config) { + this.config = config; + } + + private Definition readInTheWSDLFile(InputStream wsdlStream) throws WSDLException { + WSDLReader reader = WSDLFactory.newInstance().newWSDLReader(); + reader.setFeature("javax.wsdl.importDocuments", true); + + /* + * File file = new File(uri); String baseURI; + * + * if (uri.startsWith("http://")){ baseURI = uri; } else{ if(file.getParentFile() == null){ try { baseURI = new + * File(".").getCanonicalFile().toURI().toString(); } catch (IOException e) { throw new RuntimeException(e); } } else { baseURI = + * file.getParentFile().toURI().toString(); } } + */ + // Document doc; + InputSource inputSource; + try { + + // doc = XMLUtils.newDocument(wsdlStream); + inputSource = new InputSource(wsdlStream); + /* + * } catch (ParserConfigurationException e) { throw new WSDLException(WSDLException.PARSER_ERROR, "Parser Configuration Error", e); } + * catch (SAXException e) { throw new WSDLException(WSDLException.PARSER_ERROR, "Parser SAX Error", e); + */ + } catch (Exception e) { + throw new WSDLException(WSDLException.INVALID_WSDL, "IO Error", e); + } + + // return reader.readWSDL(config.getRootElementNamespaceURI(), doc); + return reader.readWSDL(config.getRootElementNamespaceURI(), inputSource); + } + + protected InputStream[] getXSDsFromWSDL(InputStream xsdInputStream) throws Exception { + Definition defn = readInTheWSDLFile(xsdInputStream); + List list = defn.getTypes().getExtensibilityElements(); + + InputStream[] xsdFragments = new InputStream[list.size()]; + + Iterator iterator = list.iterator(); + Schema schemaElement = null; + + for (int count = 0; count < list.size(); ++count) { + schemaElement = (Schema) iterator.next(); + // System.out.println(" *** - " + element.getElementType().getNamespaceURI()); + // System.out.println(" **** - " + element + " & " + element.getClass().getPackage().getName()); + // System.out.println(DOM2Writer.nodeToString(element.getElement())); + xsdFragments[count] = new ByteArrayInputStream(DOM2Writer.nodeToString(schemaElement.getElement()).getBytes()); + } + + return xsdFragments; + } + + protected SchemaTypeSystem processXSDSources() throws Exception { + SchemaTypeSystem sts = null; + if (config.getXsdFileName().endsWith(XSD_FILE)) { + sts = processXSDs(new InputStream[] { config.getXsdInputStream() }); + } else if (config.getXsdFileName().endsWith(WSDL_FILE)) { + sts = processXSDs(getXSDsFromWSDL(config.getXsdInputStream())); + } + return sts; + } + + protected SchemaTypeSystem processXSDs(InputStream[] inputStreams) { + List sdocs = new ArrayList(); + for (int i = 0; i < inputStreams.length; i++) { + try { + sdocs.add(XmlObject.Factory.parse(inputStreams[i], (new XmlOptions()).setLoadLineNumbers().setLoadMessageDigest())); + } catch (Exception e) { + System.err.println("Can not load schema file: " + inputStreams[i] + ": "); + e.printStackTrace(); + } + } + + XmlObject[] schemas = (XmlObject[]) sdocs.toArray(new XmlObject[sdocs.size()]); + + SchemaTypeSystem sts = null; + if (schemas.length > 0) { + Collection errors = new ArrayList(); + XmlOptions compileOptions = new XmlOptions(); + /* + * if (dl) compileOptions.setCompileDownloadUrls(); if (nopvr) compileOptions.setCompileNoPvrRule(); if (noupa) + * compileOptions.setCompileNoUpaRule(); + */ + try { + sts = XmlBeans.compileXsd(schemas, XmlBeans.getBuiltinTypeSystem(), compileOptions); + } catch (Exception e) { + if (errors.isEmpty() || !(e instanceof XmlException)) + e.printStackTrace(); + + System.out.println("Schema compilation errors: "); + for (Iterator i = errors.iterator(); i.hasNext();) + System.out.println(i.next()); + } + } + + return sts; + } + + private String makeQName(String nameSpace, String localName) { + return nameSpace + QNAME_SEPARATOR + localName; + } + + private String makeQName(QName qName) { + return qName.getNamespaceURI() + QNAME_SEPARATOR + qName.getLocalPart(); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLGenerator.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLGenerator.java new file mode 100644 index 0000000000..15848158e6 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLGenerator.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.container.javascript.utils.xmlfromxsd; + +import java.util.Hashtable; + +import org.apache.xmlbeans.XmlObject; + +/** + * This is the XMLGenerator Interface that will be implemented by various + * types of Generators (SDO based, XMLBeans based etc.) + * + */ +public interface XMLGenerator { + public static final int SDO_BASED = 1; + + public static final int XMLBEANS_BASED = 2; + + public static final String XSD_FILE = ".xsd"; + + public static final String WSDL_FILE = ".wsdl"; + + public void generateXML() throws Exception; + + public void generateXML(XMLfromXSDConfiguration config) throws Exception; + + public void generateXMLIntoOutputStream() throws Exception; + + public String generateXMLAsString() throws Exception; + + public Hashtable<String, XmlObject> generateXmlAll() throws Exception; + + public XMLfromXSDConfiguration getConfig(); + + public void setConfig(XMLfromXSDConfiguration config); +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLGeneratorFactory.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLGeneratorFactory.java new file mode 100644 index 0000000000..e4075557e8 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLGeneratorFactory.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.container.javascript.utils.xmlfromxsd; + +/** + * This is a factory for creating XML Generators. The types of XML Generators + * are enumerated in the XMLGenerator interface. + * + */ +public class XMLGeneratorFactory { + private static XMLGeneratorFactory factory = null; + + protected XMLGeneratorFactory() { + + } + + public static XMLGeneratorFactory getInstance() { + if (factory == null) { + factory = new XMLGeneratorFactory(); + } + return factory; + } + + public XMLGenerator createGenerator(int generatorType) { + XMLGenerator generator = null; + switch (generatorType) { + case XMLGenerator.SDO_BASED: { + // generator = new SDObasedXMLGenerator(new XMLfromXSDConfiguration()); + break; + } + case XMLGenerator.XMLBEANS_BASED: { + generator = new XBbasedXMLGenerator(new XMLfromXSDConfiguration()); + break; + } + } + + return generator; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLfromXSDConfiguration.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLfromXSDConfiguration.java new file mode 100644 index 0000000000..76f6b711bd --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLfromXSDConfiguration.java @@ -0,0 +1,246 @@ +/* + * 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.container.javascript.utils.xmlfromxsd; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; + +/** + * This class encapsulates the configuration settings for the "XML From XSD" generation. + * Presently it contains settings like the XSD to be use, the schematype for which and + * xml instance is to be created, the destination for the output etc. All of these + * settings are used by the 'generator' classes during the genation of the xml instance. + * + */ +public class XMLfromXSDConfiguration implements CmdLineArgsHandler { + private static int fileCount = 0; + + public static final String DEFAULT_XML_OUTPUT_FILENAME = "XML_FROM_XSD_" + (++fileCount) + ".xml"; + + public static final String XSD_FILE_URL_OPTION = "xsd"; + + public static final String XML_OUTPUT_LOCATION_OPTION = "o"; + + public static final String XML_OUTPUT_FILENAME_OPTION = "of"; + + public static final String ROOT_ELEMENT_NAMESPACE_URI_OPTION = "rns"; + + public static final String ROOT_ELEMENT_LOCALNAME_OPTION = "rn"; + + public static final String SCHEMA_TYPE_NAME = "st"; + + public static final String SCHEMA_TYPE_NAMESPACE_URI = "stn"; + + public static final String GENERATE_SAMPLE_DATA = "sd"; + + protected String xmlOutputLocation = null; + + protected File xmlOutputDirectory = null; + + protected String xsdFileName = null; + + protected String xmlFileName = null; + + protected InputStream xsdInputStream = null; + + protected OutputStream xmlOutputStream = null; + + protected String rootElementNamespaceURI = null; + + protected String rootElementLocalName = null; + + protected String schemaTypeName = null; + + protected String schemaTypeNamespaceURI = null; + + protected boolean generateSampleData = false; + + private void handleXSDInputFileOption(String xsdFileUrl) throws Exception { + xsdFileName = xsdFileUrl; + // xsdInputStream = new FileInputStream(new File(xsdFileName)); + URL resourceUrl = Thread.currentThread().getContextClassLoader().getResource(xsdFileName); + if (resourceUrl != null) { + xsdInputStream = resourceUrl.openStream(); + } else { + File inFile = new File(xsdFileName); + xsdFileName = inFile.getName(); + xsdInputStream = new FileInputStream(inFile); + } + } + + private void handleXMLOutputLocationOption(String outputLocation) throws Exception { + xmlOutputLocation = outputLocation; + xmlOutputDirectory = new File(xmlOutputLocation); + if (!xmlOutputDirectory.exists()) { + xmlOutputDirectory.mkdirs(); + } else if (!xmlOutputDirectory.isDirectory()) { + throw new IllegalArgumentException("The input location for the xml output " + outputLocation + "is not a folder"); + } + } + + private void handleOutputFilenameOption(String outputFileName) throws Exception { + xmlFileName = outputFileName; + + // first create a file in the given location + File outputFile = new File(xmlOutputDirectory, xmlFileName); + + try { + if (!outputFile.exists()) { + outputFile.createNewFile(); + } + xmlOutputStream = new FileOutputStream(outputFile); + } catch (IOException e) { + throw new Exception(e); + } + } + + public void handleArgument(String optionFlag, String argValue) throws IllegalArgumentException { + try { + if (XSD_FILE_URL_OPTION.equalsIgnoreCase(optionFlag)) { + handleXSDInputFileOption(argValue); + } else if (XML_OUTPUT_LOCATION_OPTION.equalsIgnoreCase(optionFlag)) { + handleXMLOutputLocationOption(argValue); + } else if (XML_OUTPUT_FILENAME_OPTION.equalsIgnoreCase(optionFlag)) { + handleOutputFilenameOption(argValue); + } else if (ROOT_ELEMENT_NAMESPACE_URI_OPTION.equalsIgnoreCase(optionFlag)) { + setRootElementNamespaceURI(argValue); + } else if (ROOT_ELEMENT_LOCALNAME_OPTION.equalsIgnoreCase(optionFlag)) { + setRootElementLocalName(argValue); + } else if (SCHEMA_TYPE_NAME.equalsIgnoreCase(optionFlag)) { + setSchemaTypeName(argValue); + } else if (SCHEMA_TYPE_NAMESPACE_URI.equalsIgnoreCase(optionFlag)) { + setSchemaTypeNamespaceURI(argValue); + } else if (GENERATE_SAMPLE_DATA.equalsIgnoreCase(optionFlag)) { + setGenerateSampleData(true); + } + } catch (Exception e) { + throw new IllegalArgumentException("Exception due to - " + e); + } + } + + public String getRootElementLocalName() { + if (rootElementLocalName == null) { + rootElementLocalName = schemaTypeName.toLowerCase(); + } + return rootElementLocalName; + } + + public void setRootElementLocalName(String rootElementLocalName) { + this.rootElementLocalName = rootElementLocalName; + } + + public String getRootElementNamespaceURI() { + if (rootElementNamespaceURI == null) { + rootElementNamespaceURI = schemaTypeNamespaceURI; + } + return rootElementNamespaceURI; + } + + public void setRootElementNamespaceURI(String rootElementNamespaceURI) { + this.rootElementNamespaceURI = rootElementNamespaceURI; + } + + public String getXmlFileName() { + if (xmlFileName == null) { + xmlFileName = getXsdFileName() + ".xml"; + } + return xmlFileName; + } + + public void setXmlFileName(String xmlFileName) { + this.xmlFileName = xmlFileName; + } + + public File getXmlOutputLocation() { + return xmlOutputDirectory; + } + + public void setXmlOutputLocation(File xmlOutputLocation) { + this.xmlOutputDirectory = xmlOutputLocation; + } + + public OutputStream getXmlOutputStream() throws Exception { + if (xmlOutputStream == null) { + if (xmlOutputDirectory == null) { + handleXMLOutputLocationOption(System.getProperty("user.dir")); + } + handleOutputFilenameOption(getXmlFileName()); + } + return xmlOutputStream; + } + + public void setXmlOutputStream(OutputStream xmlOutputStream) { + this.xmlOutputStream = xmlOutputStream; + } + + public String getXsdFileName() { + return xsdFileName; + } + + public void setXsdFileName(String xsdFileName) throws Exception { + this.xsdFileName = xsdFileName; + handleXSDInputFileOption(xsdFileName); + } + + public InputStream getXsdInputStream() throws Exception { + if (xsdInputStream == null) { + throw new IllegalArgumentException("XSD Input Source not set....!"); + } + return xsdInputStream; + } + + public void setXsdInputStream(InputStream xsdInputStream) { + this.xsdInputStream = xsdInputStream; + } + + public String getSchemaTypeName() { + return schemaTypeName; + } + + public void setSchemaTypeName(String schemaTypeName) { + this.schemaTypeName = schemaTypeName; + } + + public String getSchemaTypeNamespaceURI() { + return schemaTypeNamespaceURI; + } + + public void setSchemaTypeNamespaceURI(String schemaTypeNamespaceURI) { + this.schemaTypeNamespaceURI = schemaTypeNamespaceURI; + } + + public void setXmlOutputLocation(String xmlOutputLocation) throws Exception { + this.xmlOutputLocation = xmlOutputLocation; + handleXMLOutputLocationOption(xmlOutputLocation); + } + + public boolean isGenerateSampleData() { + return generateSampleData; + } + + public void setGenerateSampleData(boolean generateSampleData) { + this.generateSampleData = generateSampleData; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLfromXSDGenerator.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLfromXSDGenerator.java new file mode 100644 index 0000000000..357d4203fe --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLfromXSDGenerator.java @@ -0,0 +1,82 @@ +/* + * 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.container.javascript.utils.xmlfromxsd; + +/** + * This class provides a command line tooling functinality for creating an XML + * instance from an input XSD. + */ +public class XMLfromXSDGenerator { + public static int generatorType = XMLGenerator.XMLBEANS_BASED; + + /** + * @param args + */ + public static void main(String[] args) { + try { + new XMLfromXSDGenerator().generateXMLInstance(args); + } catch (Exception e) { + e.printStackTrace(); + System.out.println(getPrintUsageMessage()); + } + } + + public void generateXMLInstance(String args[]) throws Exception { + // create a configuration object to hold settings for this generation + XMLfromXSDConfiguration config = new XMLfromXSDConfiguration(); + + // create an argument processor to process the input arguments + CmdLineArgsProcessor argsProcessor = new CmdLineArgsProcessor(); + + // configure the args processor with the 'config' object that must be populated + // with values from the proecessed input arguments + argsProcessor.setArgsHandler(config); + + // set the usage message to be output by the args processor if input arguments are not proper + argsProcessor.setPrintUsageMessage(getPrintUsageMessage()); + + // start processing the arguments + argsProcessor.processArgs(args); + + // now that the configuration settings are populated from the input arguments + // instantiate the xmlfromsdogenerator with this config object + + XMLGenerator generator = new XMLGeneratorFactory().createGenerator(generatorType); + // XBbasedXMLGenerator generator = new XBbasedXMLGenerator(config); + + // generate the xml instance + generator.generateXML(config); + } + + protected static String getPrintUsageMessage() { + StringBuffer strBuffer = new StringBuffer(); + strBuffer.append("Usage arguments:\n"); + strBuffer.append(" [ -rns <root element namespace URI> ]\n"); + strBuffer.append(" [ -rn <root element name> ]\n"); + strBuffer.append(" [ -xsd <xsd file> ]\n"); + strBuffer.append(" [ -of <output xml filename> ]\n"); + strBuffer.append(" [ -o <output location> ]\n"); + strBuffer.append(" [ -st <name of the schema type to be instantiated as xml> ]\n"); + strBuffer.append(" [ -stn <namespace URI of the schema type> ]\n"); + strBuffer.append(" [ -sd (provide this flag if sample data is to be generated)\n"); + + return strBuffer.toString(); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XmlInstanceCreationException.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XmlInstanceCreationException.java new file mode 100644 index 0000000000..140d3efdb4 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XmlInstanceCreationException.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.container.javascript.utils.xmlfromxsd; + +/** + * The Exception wrapper class for encasulating exceptions that occur during xml instance creation + * + */ +public class XmlInstanceCreationException extends Exception { + + public XmlInstanceCreationException(String message) { + super(message); + } + + public XmlInstanceCreationException(Exception e) { + super(e); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XmlInstanceRegistry.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XmlInstanceRegistry.java new file mode 100644 index 0000000000..15f0fcfb73 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XmlInstanceRegistry.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.container.javascript.utils.xmlfromxsd; + +import java.util.Map; + +import org.apache.xmlbeans.XmlObject; + +/** + * Interface for system registry of xml instances + * + */ +public interface XmlInstanceRegistry { + public Map<String, XmlObject> getXmlInstance(String wsdlPath) throws XmlInstanceCreationException; +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XmlInstanceRegistryImpl.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XmlInstanceRegistryImpl.java new file mode 100644 index 0000000000..73b7232eae --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XmlInstanceRegistryImpl.java @@ -0,0 +1,68 @@ +/* + * 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.container.javascript.utils.xmlfromxsd; + +import java.util.Hashtable; +import java.util.Map; + +import org.apache.xmlbeans.XmlObject; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; + +/** + * An implementation for the XMLInstnaceRegistry + * + */ +@Scope("MODULE") +public class XmlInstanceRegistryImpl implements XmlInstanceRegistry { + + private Hashtable<String, Map<String, XmlObject>> wsdlXmlInstances; + + private XMLGenerator xmlGenerator; + + public XmlInstanceRegistryImpl() { + wsdlXmlInstances = new Hashtable<String, Map<String, XmlObject>>(); + + XMLfromXSDConfiguration generationConfig = new XMLfromXSDConfiguration(); + xmlGenerator = XMLGeneratorFactory.getInstance().createGenerator(XMLGenerator.XMLBEANS_BASED); + xmlGenerator.setConfig(generationConfig); + } + + @Init(eager = true) + public void init() { + } + + /* (non-Javadoc) + * @see org.apache.tuscany.container.javascript.XmlInstanceRegistry#getXmlInstance(java.lang.String, java.lang.String, java.lang.String) + */ + public Map<String, XmlObject> getXmlInstance(String wsdlPath) throws XmlInstanceCreationException { + Map<String, XmlObject> xmlInstanceMap = null; + if ((xmlInstanceMap = wsdlXmlInstances.get(wsdlPath)) == null) { + try { + xmlGenerator.getConfig().setXsdFileName(wsdlPath); + xmlInstanceMap = xmlGenerator.generateXmlAll(); + wsdlXmlInstances.put(wsdlPath, xmlInstanceMap); + } catch (Exception e) { + throw new XmlInstanceCreationException(e); + } + } + return xmlInstanceMap; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/resources/META-INF/sca/default.scdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/resources/META-INF/sca/default.scdl new file mode 100644 index 0000000000..c579693474 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/resources/META-INF/sca/default.scdl @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<!-- + JavaScript configuration for the launcher environment. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://incubator.apache.org/tuscany/xmlns/system/1.0-incubator-M2" + + name="org.apache.tuscany.launcher.JavaScriptImplementation"> + + <dependency xmlns="http://incubator.apache.org/tuscany/xmlns/1.0-incubator-M2"> + <group>org.apache.tuscany.sca.services.containers</group> + <name>javascript</name> + <version>1.0-incubator-M2</version> + </dependency> + + <component name="javascript.implementationLoader"> + <system:implementation.system class="org.apache.tuscany.container.javascript.JavaScriptImplementationLoader"/> + </component> + + <component name="javascript.componentTypeLoader"> + <system:implementation.system class="org.apache.tuscany.container.javascript.JavaScriptComponentTypeLoader"/> + </component> + + <component name="javascript.componentBuilder"> + <system:implementation.system class="org.apache.tuscany.container.javascript.JavaScriptComponentBuilder"/> + </component> + + <!-- Xml Instance Registry service --> + <component name="xmlInstRegistry"> + <system:implementation.system class="org.apache.tuscany.container.javascript.utils.xmlfromxsd.XmlInstanceRegistryImpl"/> + </component> + +</composite> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/resources/META-INF/sca/js.system.scdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/resources/META-INF/sca/js.system.scdl new file mode 100644 index 0000000000..914c53c10c --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/main/resources/META-INF/sca/js.system.scdl @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<!-- + JavaScript configuration for the launcher environment. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://incubator.apache.org/tuscany/xmlns/system/1.0-incubator-M2" + + name="org.apache.tuscany.launcher.JavaScriptImplementation"> + + <component name="javascript.implementationLoader"> + <system:implementation.system class="org.apache.tuscany.container.javascript.JavaScriptImplementationLoader"/> + </component> + + <component name="javascript.componentTypeLoader"> + <system:implementation.system class="org.apache.tuscany.container.javascript.JavaScriptComponentTypeLoader"/> + </component> + + <component name="javascript.componentBuilder"> + <system:implementation.system class="org.apache.tuscany.container.javascript.JavaScriptComponentBuilder"/> + </component> + + <!-- Xml Instance Registry service --> + <component name="xmlInstRegistry"> + <system:implementation.system class="org.apache.tuscany.container.javascript.utils.xmlfromxsd.XmlInstanceRegistryImpl"/> + </component> + +</composite> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/helloworld/HelloWorldService.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/helloworld/HelloWorldService.java new file mode 100644 index 0000000000..e0b1ab2303 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/helloworld/HelloWorldService.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 helloworld; + +import org.apache.axiom.om.OMElement; + +public interface HelloWorldService { + + String sayHello(String s); + OMElement sayE4XHello(OMElement xmlObject); +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/helloworld/HelloWorldServiceImpl.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/helloworld/HelloWorldServiceImpl.java new file mode 100644 index 0000000000..ac17e29eb0 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/helloworld/HelloWorldServiceImpl.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 helloworld; + +import java.io.ByteArrayInputStream; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.axiom.om.OMAbstractFactory; +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.impl.builder.StAXOMBuilder; +import org.apache.axiom.om.util.StAXUtils; + +public class HelloWorldServiceImpl implements HelloWorldService { + + public OMElement sayE4XHello(OMElement xmlObject) { + + String helloString = "<hel:getGreetingsResponse xmlns:hel=\"http://helloworld\">" + + "<hel:getGreetingsReturn>Hello from Java Implementation to </hel:getGreetingsReturn>NoString</hel:getGreetingsResponse>"; + + try { + String inputValue = xmlObject.getFirstElement().getText(); + + XMLStreamReader xmlReader = StAXUtils.createXMLStreamReader(new ByteArrayInputStream(helloString.getBytes())); + + StAXOMBuilder staxOMBuilder = new StAXOMBuilder(OMAbstractFactory.getOMFactory(), xmlReader); + OMElement response = staxOMBuilder.getDocumentElement(); + response.getFirstElement().setText(response.getFirstElement().getText() + inputValue); + + return response; + } catch (Exception e) { + return null; + } + } + + public String sayHello(String s) { + return "Hello " + s; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/JavaScriptImplementationLoaderTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/JavaScriptImplementationLoaderTestCase.java new file mode 100644 index 0000000000..b7f081bb70 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/JavaScriptImplementationLoaderTestCase.java @@ -0,0 +1,107 @@ +/* + * 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.container.javascript; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.MissingResourceException; + +import junit.framework.TestCase; +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; + +/** + * Tests for JavaScriptImplementationLoader + */ +public class JavaScriptImplementationLoaderTestCase extends TestCase { + private CompositeComponent parent; + + private XMLStreamReader reader; + + private DeploymentContext deploymentContext; + + private ClassLoader classLoader; + + private LoaderRegistry registry; + + private JavaScriptImplementationLoader loader; + + public void testNoScriptAttribute() throws LoaderException, XMLStreamException { + expect(reader.getAttributeValue(null, "script")).andReturn(null); + replay(reader); + replay(deploymentContext); + + try { + loader.load(parent, reader, deploymentContext); + fail(); + } catch (MissingResourceException e) { + // ok + } + verify(reader); + verify(deploymentContext); + } + + public void testNoScriptPresent() throws LoaderException, XMLStreamException { + expect(reader.getAttributeValue(null, "script")).andReturn("foo.groovy"); + expect(deploymentContext.getClassLoader()).andReturn(classLoader); + + replay(reader); + replay(deploymentContext); + + JavaScriptImplementationLoader mockLoader = new JavaScriptImplementationLoader(registry) { + protected String loadSource(ClassLoader cl, String resource) throws LoaderException { + assertSame(classLoader, cl); + assertEquals("foo.groovy", resource); + throw new MissingResourceException(resource); + } + }; + try { + mockLoader.load(parent, reader, deploymentContext); + fail(); + } catch (MissingResourceException e) { + assertEquals("foo.groovy", e.getMessage()); + } + verify(reader); + verify(deploymentContext); + } + + public void testLoadScript() throws LoaderException { + String script = + loader.loadSource(getClass().getClassLoader(), "org/apache/tuscany/container/javascript/mock/test.js"); + assertEquals("//Test Script", script); + } + + protected void setUp() throws Exception { + super.setUp(); + registry = createMock(LoaderRegistry.class); + loader = new JavaScriptImplementationLoader(registry); + + parent = createMock(CompositeComponent.class); + reader = createMock(XMLStreamReader.class); + deploymentContext = createMock(DeploymentContext.class); + classLoader = createMock(ClassLoader.class); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/PropertyTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/PropertyTestCase.java new file mode 100644 index 0000000000..7287d7833f --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/PropertyTestCase.java @@ -0,0 +1,65 @@ +/* + * 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.container.javascript; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.apache.tuscany.container.javascript.mock.Greeting; +import org.apache.tuscany.container.javascript.rhino.RhinoScript; +import org.apache.tuscany.core.component.scope.ModuleScopeContainer; +import org.apache.tuscany.spi.wire.WireService; +import org.apache.tuscany.test.ArtifactFactory; + +/** + * Tests for component properties + */ +public class PropertyTestCase extends TestCase { + + private static final String SCRIPT = "function greet(name){ return property; }"; + + private RhinoScript implClass; + + /** + * Tests injecting a simple property type on a Javascript implementation instance + */ + public void testPropertyInjection() throws Exception { + /*ModuleScopeContainer scope = new ModuleScopeContainer(null); + scope.start(); + List<Class<?>> services = new ArrayList<Class<?>>(); + services.add(Greeting.class); + Map<String, Object> properties = new HashMap<String, Object>(); + properties.put("property", "bar"); + WireService wireService = ArtifactFactory.createWireService(); + JavaScriptComponent<Greeting> context = new JavaScriptComponent<Greeting>("source", implClass, services, properties, null, scope, wireService, null); + scope.register(context); + Greeting greeting = context.getServiceInstance(); + assertEquals("bar", greeting.greet("foo")); + scope.stop();*/ + } + + protected void setUp() throws Exception { + super.setUp(); + implClass = new RhinoScript("test", SCRIPT); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/RhinoScriptIntrospectorTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/RhinoScriptIntrospectorTestCase.java new file mode 100644 index 0000000000..3a51a8f619 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/RhinoScriptIntrospectorTestCase.java @@ -0,0 +1,114 @@ +/* + * 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.container.javascript; + +import java.io.IOException; +import java.net.URL; +import java.util.Map; +import javax.wsdl.WSDLException; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.loader.MissingResourceException; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import helloworld.HelloWorldService; +import junit.framework.TestCase; +import org.apache.tuscany.container.javascript.rhino.RhinoSCAConfig; +import org.apache.tuscany.container.javascript.rhino.RhinoScript; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.idl.wsdl.WSDLDefinitionRegistryImpl; +import org.apache.tuscany.idl.wsdl.WSDLServiceContract; +import org.apache.tuscany.idl.wsdl.XMLSchemaRegistryImpl; + +public class RhinoScriptIntrospectorTestCase extends TestCase { + + private static final WSDLDefinitionRegistryImpl.Monitor NULL_MONITOR = new WSDLDefinitionRegistryImpl.Monitor() { + public void readingWSDL(String namespace, URL location) { + } + + public void cachingDefinition(String namespace, URL location) { + } + }; + + public void testJavaInterface() throws MissingResourceException, InvalidServiceContractException { + RhinoScript rs = + new RhinoScript("javaInterfaceTest", "SCA = { javaInterface : 'helloworld.HelloWorldService',};", + null, getClass().getClassLoader()); + RhinoSCAConfig scaConfig = new RhinoSCAConfig(rs.getScriptScope()); + JavaScriptIntrospector introspector = + new JavaScriptIntrospector(null, new JavaInterfaceProcessorRegistryImpl()); + ComponentType comonentType = introspector.introspectScript(scaConfig, rs.getClassLoader()); + assertNotNull(comonentType); + Map services = comonentType.getServices(); + assertEquals(1, services.size()); + ServiceDefinition serviceDefinition = (ServiceDefinition) services.values().iterator().next(); + ServiceContract serviceContract = serviceDefinition.getServiceContract(); + assertTrue(serviceContract instanceof JavaServiceContract); + JavaServiceContract javaServiceContract = (JavaServiceContract) serviceContract; + assertEquals(HelloWorldService.class, javaServiceContract.getInterfaceClass()); + } + + public void testWSDLLocation() throws WSDLException { +// RhinoScript rs = new RhinoScript("wsdlLocation", +// "SCA = { wsdlLocation : 'src/test/resources/org/apache/tuscany/container/javascript/rhino/helloworld.wsdl',};", null, getClass() +// .getClassLoader()); +// RhinoSCAConfig scaConfig = new RhinoSCAConfig(rs.getScriptScope()); +// JavaScriptIntrospector introspector = new JavaScriptIntrospector(null); +// ComponentType comonentType = introspector.introspectScript(scaConfig, rs.getClassLoader()); +// assertNotNull(comonentType); +// Map services = comonentType.getServices(); +// assertEquals(1, services.size()); +// ServiceDefinition serviceDefinition = (ServiceDefinition) services.values().iterator().next(); +// ServiceContract serviceContract = serviceDefinition.getServiceContract(); +// assertTrue(serviceContract instanceof WSDLServiceContract); +// WSDLServiceContract wsdlServiceContract = (WSDLServiceContract) serviceContract; +// assertEquals(new QName("http://helloworld", "HelloWorld"), wsdlServiceContract.getPortType().getQName()); + } + + public void testWSDLPortType() throws WSDLException, IOException, MissingResourceException, + InvalidServiceContractException { + RhinoScript rs = new RhinoScript("wsdlPortType", + "SCA = { wsdlPortType : 'HelloWorld', wsdlNamespace : 'http://helloworld',};", null, + getClass().getClassLoader()); + RhinoSCAConfig scaConfig = new RhinoSCAConfig(rs.getScriptScope()); + + WSDLDefinitionRegistryImpl wsdlReg = new WSDLDefinitionRegistryImpl(); + wsdlReg.setSchemaRegistry(new XMLSchemaRegistryImpl()); + wsdlReg.setMonitor(NULL_MONITOR); + URL wsdlURL = + getClass().getClassLoader().getResource("org/apache/tuscany/container/javascript/rhino/helloworld.wsdl"); + wsdlReg.loadDefinition("http://helloworld", wsdlURL); + + JavaScriptIntrospector introspector = + new JavaScriptIntrospector(wsdlReg, new JavaInterfaceProcessorRegistryImpl()); + ComponentType comonentType = introspector.introspectScript(scaConfig, rs.getClassLoader()); + assertNotNull(comonentType); + Map services = comonentType.getServices(); + assertEquals(1, services.size()); + ServiceDefinition serviceDefinition = (ServiceDefinition) services.values().iterator().next(); + ServiceContract serviceContract = serviceDefinition.getServiceContract(); + assertTrue(serviceContract instanceof WSDLServiceContract); + WSDLServiceContract wsdlServiceContract = (WSDLServiceContract) serviceContract; + assertEquals(new QName("http://helloworld", "HelloWorld"), wsdlServiceContract.getPortType().getQName()); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/ScriptInvokeTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/ScriptInvokeTestCase.java new file mode 100644 index 0000000000..94835591df --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/ScriptInvokeTestCase.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.container.javascript; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.tuscany.container.javascript.mock.Greeting; +import org.apache.tuscany.container.javascript.rhino.RhinoScript; +import org.apache.tuscany.core.component.scope.ModuleScopeContainer; +import org.apache.tuscany.test.ArtifactFactory; + +/** + * Tests for invoker JavaScriptComponents + */ +public class ScriptInvokeTestCase extends TestCase { + + private static final String SCRIPT = "function greet(name) { return name }"; + + private RhinoScript rhinoScript; + + /** + * Tests the invocation of a Groovy "script" as opposed to a class + */ + public void testBasicScriptInvocation() throws Exception { +// ModuleScopeContainer scope = new ModuleScopeContainer(null); +// scope.start(); +// List<Class<?>> services = new ArrayList<Class<?>>(); +// services.add(Greeting.class); +// JavaScriptComponent<Greeting> context = new JavaScriptComponent<Greeting>("source", rhinoScript, services, new HashMap<String, Object>(), +// null, scope, ArtifactFactory.createWireService(), null); +// scope.register(context); +// Greeting object = (Greeting) context.getServiceInstance(); +// assertEquals("foo", object.greet("foo")); +// scope.stop(); + } + + protected void setUp() throws Exception { + super.setUp(); + rhinoScript = new RhinoScript("test", SCRIPT); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/WireTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/WireTestCase.java new file mode 100644 index 0000000000..8bf7f8e74a --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/WireTestCase.java @@ -0,0 +1,161 @@ +/* + * 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.container.javascript; + +import static org.easymock.EasyMock.reportMatcher; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.tuscany.container.javascript.mock.Greeting; +import org.apache.tuscany.container.javascript.rhino.RhinoScript; +import org.apache.tuscany.core.component.scope.ModuleScopeContainer; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InboundInvocationChain; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.test.ArtifactFactory; +import org.easymock.IArgumentMatcher; + +/** + * Tests for JavaScript component wiring + */ +public class WireTestCase extends TestCase { + + private static final String SCRIPT = + " function setWire(ref){" + + " wire = ref;" + " }" + + " " + + " function greet(name){" + + " return wire.greet(name); " + + " }"; + + private static final String SCRIPT2 = + " function greet(name){" + + " return name; " + + " }"; + + private RhinoScript implClass1; + + private RhinoScript implClass2; + + /** + * Tests a basic invocation down a source wire + */ + public void testReferenceWireInvocation() throws Exception { +// ModuleScopeContainer scope = new ModuleScopeContainer(null); +// scope.start(); +// +// List<Class<?>> services = new ArrayList<Class<?>>(); +// services.add(Greeting.class); +// JavaScriptComponent<Greeting> context = new JavaScriptComponent<Greeting>("source", implClass1, services, properties, null, scope, +// ArtifactFactory.createWireService(), null); +// OutboundWire wire = ArtifactFactory.createOutboundWire("wire", Greeting.class); +// ArtifactFactory.terminateWire(wire); +// +// TargetInvoker invoker = createMock(TargetInvoker.class); +// expect(invoker.isCacheable()).andReturn(false); +// Message response = new MessageImpl(); +// response.setBody("foo"); +// expect(invoker.invoke(eqMessage())).andReturn(response); +// replay(invoker); +// +// for (OutboundInvocationChain chain : wire.getInvocationChains().values()) { +// chain.setTargetInvoker(invoker); +// } +// scope.register(context); +// context.addOutboundWire(wire); +// Greeting greeting = context.getServiceInstance(); +// assertEquals("foo", greeting.greet("foo")); +// verify(invoker); +// +// scope.stop(); + } + + // todo this could be generalized and moved to test module + public static Message eqMessage() { + reportMatcher(new IArgumentMatcher() { + public boolean matches(Object object) { + if (!(object instanceof Message)) { + return false; + } + final Message msg = (Message) object; + Object[] body = (Object[]) msg.getBody(); + return "foo".equals(body[0]); + } + + public void appendTo(StringBuffer stringBuffer) { + } + }); + return null; + } + + /** + * Tests a basic invocation to a target + */ + public void testTargetInvocation() throws Exception { + ModuleScopeContainer scope = new ModuleScopeContainer(null); + scope.start(); + List<Class<?>> services = new ArrayList<Class<?>>(); + services.add(Greeting.class); + JavaScriptComponent context = + new JavaScriptComponent("source", implClass2, new HashMap<String, Object>(), services, null, scope, + ArtifactFactory.createWireService(), null); + scope.register(context); + Operation<Type> operation = new Operation<Type>("greet", null, null, null, false, null); + TargetInvoker invoker = context.createTargetInvoker(null, operation); + assertEquals("foo", invoker.invokeTarget(new String[]{"foo"})); + scope.stop(); + } + + /** + * Tests a basic invocation down a target wire + */ + public void testTargetWireInvocation() throws Exception { + ModuleScopeContainer scope = new ModuleScopeContainer(null); + scope.start(); + List<Class<?>> services = new ArrayList<Class<?>>(); + services.add(Greeting.class); + JavaScriptComponent context = + new JavaScriptComponent("source", implClass2, new HashMap<String, Object>(), services, null, scope, + ArtifactFactory.createWireService(), null); + scope.register(context); + + InboundWire wire = ArtifactFactory.createInboundWire("Greeting", Greeting.class); + ArtifactFactory.terminateWire(wire); + for (InboundInvocationChain chain : wire.getInvocationChains().values()) { + chain.setTargetInvoker(context.createTargetInvoker(null, chain.getOperation())); + } + context.addInboundWire(wire); + Greeting greeting = (Greeting) context.getServiceInstance("Greeting"); + assertEquals("foo", greeting.greet("foo")); + scope.stop(); + } + + protected void setUp() throws Exception { + super.setUp(); + implClass1 = new RhinoScript("script1", SCRIPT); + implClass2 = new RhinoScript("script2", SCRIPT2); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/function/HelloWorldTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/function/HelloWorldTestCase.java new file mode 100644 index 0000000000..3db49618e2 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/function/HelloWorldTestCase.java @@ -0,0 +1,104 @@ +/* + * 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.container.javascript.function; + +import helloworld.HelloWorldService; + +import java.io.ByteArrayInputStream; +import java.net.URL; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.axiom.om.OMAbstractFactory; +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.impl.builder.StAXOMBuilder; +import org.apache.axiom.om.util.StAXUtils; +import org.apache.tuscany.test.SCATestCase; +import org.osoa.sca.CompositeContext; +import org.osoa.sca.CurrentCompositeContext; + +/** + * This shows how to test the HelloWorld service component. + */ +public class HelloWorldTestCase extends SCATestCase { + + private CompositeContext context; + + protected void setUp() throws Exception { + URL base = getClass().getResource("/META-INF/sca/js.system.scdl"); + addExtension("JavaScriptContainer", new URL(base, "default.scdl")); + setApplicationSCDL(getClass().getResource("helloworld.scdl")); + super.setUp(); + + context = CurrentCompositeContext.getContext(); + } + + public void testHelloWorld() throws Exception { + HelloWorldService helloWorldService = context.locateService(HelloWorldService.class, "HelloWorldComponent"); + assertEquals(helloWorldService.sayHello("petra"), "Hello petra"); + } + + public void testIntrospectedHelloWorld() throws Exception { + HelloWorldService introspectableService = context.locateService(HelloWorldService.class, "IntrospectableHelloWorldComponent"); + assertEquals(introspectableService.sayHello("petra"), "Hello petra"); + } + + public void testE4XImplInvocation() throws Exception { + HelloWorldService e4xHelloWorldService = context.locateService(HelloWorldService.class, "HelloWorldComponentE4X"); + String xmlInput = "<hel:getGreetings xmlns:hel=\"http://helloworld\"> " + + "<hel:name>TuscanyWorld</hel:name> " + + "</hel:getGreetings>"; + + XMLStreamReader xmlReader = StAXUtils.createXMLStreamReader( + new ByteArrayInputStream(xmlInput.getBytes())); + StAXOMBuilder staxOMBuilder = new StAXOMBuilder(OMAbstractFactory.getOMFactory(), xmlReader); + Object response = e4xHelloWorldService.sayE4XHello(staxOMBuilder.getDocumentElement()); + assertNotNull(response); + assertTrue(response instanceof OMElement); + assertEquals("e4xHello TuscanyWorld", ((OMElement)response).getFirstElement().getText()); + //System.out.println(response); + } + + public void testE4XRefInvocation() throws Exception + { + HelloWorldService e4xHelloWorldService = context.locateService(HelloWorldService.class, "HelloWorldComponentE4X"); + + String initialInput = "JavaClient"; + String jsAddition = " thro e4x reference"; + String endSvcImplResponse = "Hello from Java Implementation to "; + + Object response = e4xHelloWorldService.sayHello(initialInput); + assertNotNull(response); + assertTrue(response instanceof String); + assertEquals(endSvcImplResponse + initialInput + jsAddition, response.toString()); + //System.out.println(response); + } + + public void testHelloWorldProperty() throws Exception { + HelloWorldService helloWorldService = context.locateService(HelloWorldService.class, "HelloWorldProperty"); + assertEquals(helloWorldService.sayHello("petra"), "Kia ora petra"); + System.out.println(helloWorldService.sayHello("petra")); + } + + public void testHelloWorldPropertyDefault() throws Exception { + HelloWorldService helloWorldService = context.locateService(HelloWorldService.class, "HelloWorldPropertyDefault"); + assertEquals(helloWorldService.sayHello("petra"), "Hi petra"); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/function/ScopeTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/function/ScopeTestCase.java new file mode 100644 index 0000000000..b823939e6c --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/function/ScopeTestCase.java @@ -0,0 +1,65 @@ +/* + * 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.container.javascript.function; + +import java.net.URL; + +import helloworld.HelloWorldService; + +import org.apache.tuscany.test.SCATestCase; +import org.osoa.sca.CompositeContext; +import org.osoa.sca.CurrentCompositeContext; + +/** + * This shows how to test the HelloWorld service component. + */ +public class ScopeTestCase extends SCATestCase { + + private CompositeContext context; + + protected void setUp() throws Exception { + URL base = getClass().getResource("/META-INF/sca/js.system.scdl"); + addExtension("JavaScriptContainer", new URL(base, "default.scdl")); + setApplicationSCDL(getClass().getResource("scopeTest.scdl")); + super.setUp(); + + context = CurrentCompositeContext.getContext(); + } + +// Composite scope not implemented in core yet +// public void testComposite() throws Exception { +// HelloWorldService composoteScopeService = context.locateService(HelloWorldService.class, "ComposoteScopeService"); +// assertEquals("1", composoteScopeService.sayHello("")); +// assertEquals("2", composoteScopeService.sayHello("")); +// } + + public void testStateless() throws Exception { + HelloWorldService statelessService = context.locateService(HelloWorldService.class, "StatelessComponent"); + assertEquals("1", statelessService.sayHello("")); + // stateless gives a new instance for each request + assertEquals("1", statelessService.sayHello("")); + } + +// Request scope not implemented in core yet +// public void testRequestState() throws Exception { +// HelloWorldService requestService = context.locateService(HelloWorldService.class, "RequestComponent"); +// assertEquals("1", requestService.sayHello("")); +// assertEquals("1", requestService.sayHello("")); +// } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/mock/Greeting.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/mock/Greeting.java new file mode 100644 index 0000000000..e300f73469 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/mock/Greeting.java @@ -0,0 +1,26 @@ +/* + * 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.container.javascript.mock; + +public interface Greeting { + + String setWire(Greeting ref); + + String greet(String name); +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/Foo.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/Foo.java new file mode 100644 index 0000000000..397501a23b --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/Foo.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.container.javascript.rhino; + +class Foo { + private String s; + + public Foo() { + } + + public String getS() { + return s; + } + + public void setS(String s) { + this.s = s; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/RhinoFunctionInvokerTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/RhinoFunctionInvokerTestCase.java new file mode 100644 index 0000000000..dad61659f3 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/RhinoFunctionInvokerTestCase.java @@ -0,0 +1,174 @@ +/* + * 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.container.javascript.rhino; + +import java.io.IOException; + +import junit.framework.TestCase; + +import org.apache.axiom.om.OMElement; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; + +/** + * Tests for the RhinoFunctionInvoker + */ +public class RhinoFunctionInvokerTestCase extends TestCase { + + public RhinoFunctionInvokerTestCase() { + } + + protected void setUp() throws Exception { + super.setUp(); + } + + public void testNoArgsInvoke() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getPetra() {return 'petra';}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getPetra"); + assertNotNull(invoker); + assertEquals("petra", invoker.invoke(null)); + } + + public void testOneArgInvoke() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getS(s) {return s;}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getS"); + assertNotNull(invoker); + assertEquals("petra", invoker.invoke(new Object[] { "petra" })); + } + + public void testMultiArgsInvoke() { + RhinoScript rhinoScript = new RhinoScript("foo", "function concat(x, y) {return x + y}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("concat"); + assertNotNull(invoker); + assertEquals("petrasue", invoker.invoke(new Object[] { "petra", "sue" })); + } + + public void testNoResponseInvoke() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getNull() {}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getNull"); + assertNotNull(invoker); + assertEquals(null, invoker.invoke(new Object[0])); + } + + public void testNullResponseInvoke() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getNull() {return null;}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getNull"); + assertNotNull(invoker); + assertEquals(null, invoker.invoke(new Object[0])); + } + + public void testResponseTypeDefaultString() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getTrue() {return true;}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getTrue"); + assertNotNull(invoker); + Object o = invoker.invoke(new Object[0]); + assertTrue(o instanceof String); + assertEquals("true", o); + } + + public void testResponseTypeBoolean() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getTrue() {return true;}"); + //rhinoScript.setResponseClass("getTrue", Boolean.class); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getTrue", Boolean.class); + assertNotNull(invoker); + assertTrue((Boolean) invoker.invoke(new Object[0])); + } + + public void testResponseTypeStringArray() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getAs() {var as = new Array(1);as[0]='petra';return as;}"); + //rhinoScript.setResponseClass("getAs", new String[0].getClass()); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getAs", new String[0].getClass()); + assertNotNull(invoker); + Object o = invoker.invoke(new Object[0]); + assertNotNull(o); + assertTrue(o.getClass().isArray()); + assertEquals("petra", ((Object[]) o)[0]); + } + + public void testResponseTypeBooleanArray() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getBs() {var bs = new Array(1);bs[0]=true;return bs;}"); + rhinoScript.setResponseClass("getBs", new Boolean[0].getClass()); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getBs", new Boolean[0].getClass()); + assertNotNull(invoker); + Object o = invoker.invoke(new Object[0]); + assertNotNull(o); + assertTrue(o.getClass().isArray()); + assertTrue(((Boolean[]) o)[0]); + } + + public void testRequestCustomType() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getFooS(foo) {return foo.getS();}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getFooS"); + assertNotNull(invoker); + + Foo foo = new Foo(); + foo.setS("petra"); + Object o = invoker.invoke(new Object[] { foo }); + assertEquals(foo.getS(), o); + } + + public void testResponseCustomType() { + RhinoScript rhinoScript = new RhinoScript("foo", + "importClass(Packages.org.apache.tuscany.container.javascript.rhino.Foo);function getFoo(s) {var foo = new Foo(); foo.setS(s);return foo;}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getFoo"); + assertNotNull(invoker); + + Object o = invoker.invoke(new Object[] { "petra" }); + assertNotNull(o); + assertEquals("petra", ((Foo) o).getS()); + } + + public void testXMLRequest() throws XmlException, IOException { + RhinoScript rhinoScript = new RhinoScript("foo", "function isXML(x) {return 'xml' == (typeof x);}"); + //rhinoScript.setResponseClass("isXML", Boolean.class); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("isXML", Boolean.class); + assertNotNull(invoker); + + Object xml = XmlObject.Factory.parse("<a><b/></a>"); + assertTrue((Boolean) invoker.invoke(new Object[] { xml })); + + Object notXML = "notXML"; + assertFalse((Boolean) invoker.invoke(new Object[] { notXML })); + } + + public void testXMLResponse() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getXML(s) {return <a> { s } </a>;}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getXML"); + assertNotNull(invoker); + + Object xml = invoker.invoke(new Object[] { "petra" }); + assertNotNull(xml); + assertTrue(xml instanceof OMElement); + assertEquals("<a>petra</a>", ((OMElement) xml).toString()); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/RhinoSCAConfigTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/RhinoSCAConfigTestCase.java new file mode 100644 index 0000000000..cddaa9c46f --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/RhinoSCAConfigTestCase.java @@ -0,0 +1,116 @@ +/* + * 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.container.javascript.rhino; + +import junit.framework.TestCase; + +import org.apache.tuscany.spi.model.Scope; + +public class RhinoSCAConfigTestCase extends TestCase { + + public void testJavaInteface() { + RhinoScript rs = new RhinoScript("javaInterface", "SCA = { javaInterface : 'Test' }"); + RhinoSCAConfig scaConfig = rs.getSCAConfig(); + assertTrue(scaConfig.hasSCAConfig()); + assertEquals("Test", scaConfig.getJavaInterface()); + } + + public void testWSDLLocation() { + RhinoScript rs = new RhinoScript("wsdlLocation", "SCA = { wsdlLocation : 'Test' }"); + RhinoSCAConfig scaConfig = rs.getSCAConfig(); + assertTrue(scaConfig.hasSCAConfig()); + assertEquals("Test", scaConfig.getWSDLLocation()); + } + + public void testWSDLNamespace() { + RhinoScript rs = new RhinoScript("wsdlNamespace", "SCA = { wsdlNamespace : 'Test' }"); + RhinoSCAConfig scaConfig = rs.getSCAConfig(); + assertTrue(scaConfig.hasSCAConfig()); + assertEquals("Test", scaConfig.getWSDLNamespace()); + } + + public void testWSDLPortType() { + RhinoScript rs = new RhinoScript("wsdlPortType", "SCA = { wsdlPortType : 'Test' }"); + RhinoSCAConfig scaConfig = rs.getSCAConfig(); + assertTrue(scaConfig.hasSCAConfig()); + assertEquals("Test", scaConfig.getWSDLPortType()); + } + + public void testScopeStateless() { + RhinoScript rs = new RhinoScript("testScopeStateless", "SCA = { scope : 'stateless', javaInterface : 'helloworld.HelloWorldService'}"); + RhinoSCAConfig scaConfig = rs.getSCAConfig(); + assertTrue(scaConfig.hasSCAConfig()); + assertEquals(Scope.STATELESS, scaConfig.getScope()); + } + + public void testScopeComposite() { + RhinoScript rs = new RhinoScript("testScopeComposite", "SCA = { scope : 'composite', javaInterface : 'helloworld.HelloWorldService'}"); + RhinoSCAConfig scaConfig = rs.getSCAConfig(); + assertTrue(scaConfig.hasSCAConfig()); + assertEquals(Scope.MODULE, scaConfig.getScope()); // TODO + } + + public void testScopeConversational() { + RhinoScript rs = new RhinoScript("testScopeConversational", "SCA = { scope : 'conversational', javaInterface : 'helloworld.HelloWorldService'}"); + RhinoSCAConfig scaConfig = rs.getSCAConfig(); + assertTrue(scaConfig.hasSCAConfig()); + assertEquals(Scope.SESSION, scaConfig.getScope()); + } + + public void testScopeRequest() { + RhinoScript rs = new RhinoScript("testScopeRequest", "SCA = { scope : 'request', javaInterface : 'helloworld.HelloWorldService'}"); + RhinoSCAConfig scaConfig = rs.getSCAConfig(); + assertTrue(scaConfig.hasSCAConfig()); + assertEquals(Scope.REQUEST, scaConfig.getScope()); + } + + public void testBadScope() { + RhinoScript rs = new RhinoScript("testScopeStateless", "SCA = { scope : 'rubbish', javaInterface : 'helloworld.HelloWorldService'}"); + try { + RhinoSCAConfig scaConfig = rs.getSCAConfig(); + fail("expecting bad scope exception: " + scaConfig); + } catch (IllegalArgumentException e) { + } + } + + public void testNoConfig() { + RhinoScript rs = new RhinoScript("javaInterface", ""); + RhinoSCAConfig scaConfig = rs.getSCAConfig(); + assertTrue(!scaConfig.hasSCAConfig()); + } + + public void testNoService() { + RhinoScript rs = new RhinoScript("javaInterface", "SCA = {}"); + try { + RhinoSCAConfig scaConfig = rs.getSCAConfig(); + fail("expecting no service exception: " + scaConfig); + } catch (IllegalArgumentException e) { + } + } + + public void testDupicateInteface() { + RhinoScript rs = new RhinoScript("javaInterface", "SCA = { javaInterface : 'Test', wsdlLocation : 'Test' }"); + try { + RhinoSCAConfig scaConfig = rs.getSCAConfig(); + fail("expecting multiple service exception: " + scaConfig); + } catch (IllegalArgumentException e) { + } + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/RhinoScriptInstanceTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/RhinoScriptInstanceTestCase.java new file mode 100644 index 0000000000..76d6c7c49d --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/RhinoScriptInstanceTestCase.java @@ -0,0 +1,50 @@ +/* + * 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.container.javascript.rhino; + +import junit.framework.TestCase; + +/** + * Tests for the RhinoScriptInstance + */ +public class RhinoScriptInstanceTestCase extends TestCase { + + public RhinoScriptInstanceTestCase() { + + } + + protected void setUp() throws Exception { + super.setUp(); + } + + public void testInvokeFunction() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getPetra() {return 'petra';}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + assertEquals("petra", instance.invokeFunction("getPetra", new Object[0])); + } + + public void testCreateRhinoFunctionInvoker() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getPetra() {return 'petra';}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + RhinoFunctionInvoker invoker = instance.createRhinoFunctionInvoker("getPetra"); + assertNotNull(invoker); + assertEquals("petra", invoker.invoke(new Object[0])); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/RhinoScriptTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/RhinoScriptTestCase.java new file mode 100644 index 0000000000..ab684c39ce --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/rhino/RhinoScriptTestCase.java @@ -0,0 +1,83 @@ +/* + * 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.container.javascript.rhino; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +/** + * Tests for the RhinoScript + */ +public class RhinoScriptTestCase extends TestCase { + + public RhinoScriptTestCase() { + + } + + protected void setUp() throws Exception { + super.setUp(); + } + + public void testSimpleConstructor() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getPetra() {return 'petra';}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + assertEquals("petra", instance.invokeFunction("getPetra", new Object[0])); + } + + public void testFullConstructor() { + ClassLoader cl = getClass().getClassLoader(); + Map<String, Object> contexts = new HashMap<String, Object>(); + contexts.put("name", "petra"); + RhinoScript rhinoScript = new RhinoScript("foo", "function getName() {return name;}", contexts, cl); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + assertEquals("petra", instance.invokeFunction("getName", new Object[0])); + } + + public void testCreateInstance() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getPetra() {return 'petra';}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + assertNotNull(instance); + } + + public void testCreateInstanceWithContext() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getName() {return name;}"); + Map<String, Object> contexts = new HashMap<String, Object>(); + contexts.put("name", "petra"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(contexts); + assertEquals("petra", instance.invokeFunction("getName", new Object[0])); + } + + public void testDefaultResponseType() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getX() {return 42;}"); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + assertEquals("42", instance.invokeFunction("getX", new Object[0])); + } + + public void testSetResponseType() { + RhinoScript rhinoScript = new RhinoScript("foo", "function getX() {return 42;}"); + rhinoScript.setResponseClass("getX", Integer.class); + RhinoScriptInstance instance = rhinoScript.createRhinoScriptInstance(); + Object x = instance.invokeFunction("getX", new Object[0], Integer.class); + assertTrue(x instanceof Integer); + assertEquals(new Integer(42), x); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLfromXSDGeneratorTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLfromXSDGeneratorTestCase.java new file mode 100644 index 0000000000..15752bdaa1 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/XMLfromXSDGeneratorTestCase.java @@ -0,0 +1,129 @@ +/* + * 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.container.javascript.utils.xmlfromxsd; + +import junit.framework.TestCase; + +public class XMLfromXSDGeneratorTestCase extends TestCase { + + protected void setUp() throws Exception { + super.setUp(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + /*public void testXMLInstance_SDO_based_1() + { + String[] arguments = new String[] { "-xsd", "sequences.xsd", + "-st", "MixedQuote", + "-stn", "http://www.example.com/sequences", + "-o", "target/xmlFromxsd-source", + "-of", "sequences_sdo.xml" + }; + + XMLfromXSDGenerator.main(arguments); + //File file = new File("target/java2wsdl-source/CustomerValue.wsdl"); + //assertTrue(file.exists() && file.isFile()); + } + + public void testXMLInstance_SDO_based_2() + { + try + { + XMLfromXSDConfiguration config = new XMLfromXSDConfiguration(); + config.setXsdFileName("interopdoc.wsdl"); + config.setSchemaTypeName("ComplexDocument"); + config.setSchemaTypeNamespaceURI("http://soapinterop.org/"); + config.setXmlOutputLocation("target/xmlFromxsd-source"); + config.setXmlFileName("interopdoc_sdo.xml"); + + XMLGeneratorFactory.getInstance().createGenerator(XMLGenerator.SDO_BASED).generateXML(config); + //XMLGeneratorFactory.getInstance().createGenerator(XMLGenerator.XMLBEANS_BASED).generateXML(config); + } + catch ( Exception e ) + { + e.printStackTrace(); + } + } + + public void testXMLInstance_SDO_based_3() + { + try + { + XMLfromXSDConfiguration config = new XMLfromXSDConfiguration(); + config.setXsdFileName("helloworld.wsdl"); + //config.setSchemaTypeName("getGreetings"); + config.setSchemaTypeName("ComplexGreetings"); + config.setSchemaTypeNamespaceURI("http://helloworldaxis.samples.tuscany.apache.org"); + config.setXmlOutputLocation("target/xmlFromxsd-source"); + config.setXmlFileName("helloworld_sdo.xml"); + + XMLGeneratorFactory.getInstance().createGenerator(XMLGenerator.SDO_BASED).generateXML(config); + } + catch ( Exception e ) + { + e.printStackTrace(); + } + }*/ + + public void testXMLInstance_XB_based_1() { + String[] arguments = new String[] { "-xsd", "src/test/resources/sequences.xsd", "-st", "mixedStockQuote", "-stn", + "http://www.example.com/sequences", "-o", "target/xmlFromxsd-source", "-of", "sequences_xb.xml" }; + + XMLfromXSDGenerator.generatorType = XMLGenerator.XMLBEANS_BASED; + XMLfromXSDGenerator.main(arguments); + /* + * File file = new File("target/java2wsdl-source/CustomerValue.wsdl"); assertTrue(file.exists() && file.isFile()); + */ + } + + public void testXMLInstance_XB_based_2() { + try { + XMLfromXSDConfiguration config = new XMLfromXSDConfiguration(); + config.setXsdFileName("interopdoc.wsdl"); + config.setSchemaTypeName("ComplexDocument"); + config.setSchemaTypeNamespaceURI("http://soapinterop.org/"); + config.setXmlOutputLocation("target/xmlFromxsd-source"); + config.setXmlFileName("interopdoc_xb.xml"); + + XMLGeneratorFactory.getInstance().createGenerator(XMLGenerator.XMLBEANS_BASED).generateXML(config); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void testXMLInstance_XB_based_3() { + try { + XMLfromXSDConfiguration config = new XMLfromXSDConfiguration(); + config.setXsdFileName("org/apache/tuscany/container/javascript/rhino/helloworld.wsdl"); + // config.setXsdFileName("helloworld.wsdl"); + config.setSchemaTypeName("getGreetings"); + // config.setSchemaTypeName("ComplexGreetings"); + config.setSchemaTypeNamespaceURI("http://helloworld"); + config.setXmlOutputLocation("target/xmlFromxsd-source"); + config.setXmlFileName("helloworld_xb.xml"); + + XMLGeneratorFactory.getInstance().createGenerator(XMLGenerator.XMLBEANS_BASED).generateXML(config); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/AccountService.wsdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/AccountService.wsdl new file mode 100644 index 0000000000..2a56a3c496 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/AccountService.wsdl @@ -0,0 +1,242 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. + --> +<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:tns="http://www.bigbank.com/Account/" + xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:account="http://www.bigbank.com/Account/" + targetNamespace="http://www.bigbank.com/Account/" + name="AccountService"> + + <wsdl:types> + <xsd:schema targetNamespace="http://www.bigbank.com/Account/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:account="http://www.bigbank.com/Account/" + xmlns:sdojava="commonj.sdo/java" + sdojava:package="org.apache.tuscany.samples.bigbank.account"> + + <xsd:element name="getAccountReportWrapped0"> + <xsd:complexType> + <xsd:sequence> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="getAccountReportWrapped0Response"> + <xsd:complexType> + <xsd:sequence> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="getAccountReportWrapped1"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="customerID" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="getAccountReportWrapped1Response"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="accountReport" type="account:AccountReport"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="getAccountReportWrappedN"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="customerID" type="xsd:string"/> + <xsd:element name="customerID2" type="xsd:int"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="getAccountReportWrappedNResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="accountReport" type="account:AccountReport"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="getAccountReportBare0" type="xsd:string"/> + <xsd:element name="getAccountReportBare0Response" type="xsd:int"/> + + <xsd:element name="getAccountReportBare1Simple" type="xsd:string"/> + <xsd:element name="getAccountReportBare1SimpleResponse" type="xsd:int"/> + + <xsd:element name="getAccountReportBare1Complex" type="account:AccountRequest"/> + <xsd:element name="getAccountReportBare1ComplexResponse" type="account:AccountReport"/> + + <xsd:complexType name="AccountRequest"> + <xsd:sequence> + <xsd:element name="customerID" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="AccountReport"> + <xsd:sequence> + <xsd:element name="accountSummaries" type="account:AccountSummary" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="AccountSummary"> + <xsd:attribute name="accountNumber" type="xsd:string"/> + <xsd:attribute name="accountType" type="xsd:string"/> + <xsd:attribute name="balance" type="xsd:float"/> + </xsd:complexType> + + </xsd:schema> + </wsdl:types> + + <wsdl:message name="getAccountReportWrapped0Request"> + <wsdl:part element="account:getAccountReportWrapped0" name="getAccountReportWrapped0Request"/> + </wsdl:message> + <wsdl:message name="getAccountReportWrapped0Response"> + <wsdl:part element="account:getAccountReportWrapped0Response" name="getAccountReportWrapped0Response"/> + </wsdl:message> + + <wsdl:message name="getAccountReportWrapped1Request"> + <wsdl:part element="account:getAccountReportWrapped1" name="getAccountReportWrapped1Request"/> + </wsdl:message> + <wsdl:message name="getAccountReportWrapped1Response"> + <wsdl:part element="account:getAccountReportWrapped1Response" name="getAccountReportWrapped1Response"/> + </wsdl:message> + + <wsdl:message name="getAccountReportWrappedNRequest"> + <wsdl:part element="account:getAccountReportWrappedN" name="getAccountReportWrappedNRequest"/> + </wsdl:message> + <wsdl:message name="getAccountReportWrappedNResponse"> + <wsdl:part element="account:getAccountReportWrappedNResponse" name="getAccountReportWrappedNResponse"/> + </wsdl:message> + + <wsdl:message name="getAccountReportBare0Request"> + </wsdl:message> + <wsdl:message name="getAccountReportBare0Response"> + </wsdl:message> + + <wsdl:message name="getAccountReportBare1SimpleRequest"> + <wsdl:part element="account:getAccountReportBare1Simple" name="getAccountReportBare1SimpleRequest"/> + </wsdl:message> + <wsdl:message name="getAccountReportBare1SimpleResponse"> + <wsdl:part element="account:getAccountReportBare1SimpleResponse" name="getAccountReportBare1SimpleResponse"/> + </wsdl:message> + + <wsdl:message name="getAccountReportBare1ComplexRequest"> + <wsdl:part element="account:getAccountReportBare1Complex" name="getAccountReportBare1ComplexRequest"/> + </wsdl:message> + <wsdl:message name="getAccountReportBare1ComplexResponse"> + <wsdl:part element="account:getAccountReportBare1ComplexResponse" name="getAccountReportBare1ComplexResponse"/> + </wsdl:message> + + <wsdl:portType name="Account_Service"> + <wsdl:operation name="getAccountReportWrapped0"> + <wsdl:input message="tns:getAccountReportWrapped0Request"/> + <wsdl:output message="tns:getAccountReportWrapped0Response"/> + </wsdl:operation> + <wsdl:operation name="getAccountReportWrapped1"> + <wsdl:input message="tns:getAccountReportWrapped1Request"/> + <wsdl:output message="tns:getAccountReportWrapped1Response"/> + </wsdl:operation> + <wsdl:operation name="getAccountReportWrappedN"> + <wsdl:input message="tns:getAccountReportWrappedNRequest"/> + <wsdl:output message="tns:getAccountReportWrappedNResponse"/> + </wsdl:operation> + <wsdl:operation name="getAccountReportBare0"> + <wsdl:input message="tns:getAccountReportBare0Request"/> + <wsdl:output message="tns:getAccountReportBare0Response"/> + </wsdl:operation> + <wsdl:operation name="getAccountReportBare1Simple"> + <wsdl:input message="tns:getAccountReportBare1SimpleRequest"/> + <wsdl:output message="tns:getAccountReportBare1SimpleResponse"/> + </wsdl:operation> + <wsdl:operation name="getAccountReportBare1Complex"> + <wsdl:input message="tns:getAccountReportBare1ComplexRequest"/> + <wsdl:output message="tns:getAccountReportBare1ComplexResponse"/> + </wsdl:operation> + </wsdl:portType> + <wsdl:binding name="AccountServiceSOAP" type="tns:Account_Service"> + <soap:binding style="document" + transport="http://schemas.xmlsoap.org/soap/http"/> + <wsdl:operation name="getAccountReportWrapped0"> + <soap:operation + soapAction="http://www.bigbank.com/Account/getAccountReportWrapped0"/> + <wsdl:input> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + <wsdl:operation name="getAccountReportWrapped1"> + <soap:operation + soapAction="http://www.bigbank.com/Account/getAccountReportWrapped1"/> + <wsdl:input> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + <wsdl:operation name="getAccountReportWrappedN"> + <soap:operation + soapAction="http://www.bigbank.com/Account/getAccountReportWrappedN"/> + <wsdl:input> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + <wsdl:operation name="getAccountReportBare0"> + <soap:operation + soapAction="http://www.bigbank.com/Account/getAccountReportBare0"/> + <wsdl:input> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + <wsdl:operation name="getAccountReportBare1Simple"> + <soap:operation + soapAction="http://www.bigbank.com/Account/getAccountReportBare1Simple"/> + <wsdl:input> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + <wsdl:operation name="getAccountReportBare1Complex"> + <soap:operation + soapAction="http://www.bigbank.com/Account/getAccountReportBare1Complex"/> + <wsdl:input> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + </wsdl:binding> + <wsdl:service name="AccountService"> + <wsdl:port binding="tns:AccountServiceSOAP" + name="AccountServiceSOAP"> + <soap:address location="http://localhost:8080/sample-account/services/AccountService"/> + </wsdl:port> + </wsdl:service> +</wsdl:definitions> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/interopdoc.wsdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/interopdoc.wsdl new file mode 100644 index 0000000000..820c26ca34 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/interopdoc.wsdl @@ -0,0 +1,180 @@ +<?xml version="1.0"?> +<!-- + * 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. + --> +<definitions name="InteropTestDoc" targetNamespace="http://soapinterop.org/" + xmlns="http://schemas.xmlsoap.org/wsdl/" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:tns="http://soapinterop.org/" + xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> + + <types> + + <xsd:schema elementFormDefault="qualified" targetNamespace="http://soapinterop.org/" xmlns:interop="http://soapinterop.org/"> + + <xsd:element name="SingleTag"> + <xsd:complexType> + <xsd:sequence> + <xsd:element minOccurs="0" maxOccurs="1" name="SingleTag" type="interop:SingleTag"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="SingleTag"/> + <xsd:element name="SingleTagResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element minOccurs="0" maxOccurs="1" name="SingleTag" type="interop:SingleTag"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="SimpleDocument"> + <xsd:complexType> + <xsd:sequence> + <xsd:element minOccurs="0" maxOccurs="1" name="SimpleDocument" type="interop:SimpleDocument"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:complexType name="SimpleDocument"> + <xsd:simpleContent> + <xsd:extension base="xsd:string"/> + </xsd:simpleContent> + </xsd:complexType> + <xsd:element name="SimpleDocumentResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element minOccurs="0" maxOccurs="1" name="SimpleDocument" type="interop:SimpleDocument"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="ComplexDocument"> + <xsd:complexType> + <xsd:sequence> + <xsd:element minOccurs="0" maxOccurs="1" name="ComplexDocument" type="interop:ComplexDocument"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:complexType name="ComplexDocument"> + <xsd:sequence> + <xsd:element minOccurs="0" maxOccurs="1" name="simpleDoc" type="interop:ArrayOfSimpleDocument"/> + <xsd:element minOccurs="0" maxOccurs="1" name="child" type="interop:ChildDocument"/> + </xsd:sequence> + <xsd:attribute name="AnAttribute" type="xsd:string"/> + </xsd:complexType> + <xsd:complexType name="ArrayOfSimpleDocument"> + <xsd:sequence> + <xsd:element minOccurs="0" maxOccurs="unbounded" name="SimpleDocument" nillable="true" type="interop:SimpleDocument"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="ChildDocument"> + <xsd:sequence> + <xsd:element minOccurs="0" maxOccurs="1" name="childSimpleDoc" type="interop:ArrayOfSimpleDocument"/> + </xsd:sequence> + </xsd:complexType> + <xsd:element name="ComplexDocumentResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element minOccurs="0" maxOccurs="1" name="ComplexDocument" type="interop:ComplexDocument"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + </xsd:schema> + + </types> + + <message name="SingleTagSoapIn"> + <part name="parameters" element="tns:SingleTag"/> + </message> + <message name="SingleTagSoapOut"> + <part name="outputDoc" element="tns:SingleTagResponse"/> + </message> + <message name="SimpleDocumentSoapIn"> + <part name="parameters" element="tns:SimpleDocument"/> + </message> + <message name="SimpleDocumentSoapOut"> + <part name="outputDoc" element="tns:SimpleDocumentResponse"/> + </message> + <message name="ComplexDocumentSoapIn"> + <part name="parameters" element="tns:ComplexDocument"/> + </message> + <message name="ComplexDocumentSoapOut"> + <part name="outputDoc" element="tns:ComplexDocumentResponse"/> + </message> + + <portType name="DocTestPortType"> + + <operation name="SingleTag"> + <input message="tns:SingleTagSoapIn"/> + <output message="tns:SingleTagSoapOut"/> + </operation> + <operation name="SimpleDocument"> + <input message="tns:SimpleDocumentSoapIn"/> + <output message="tns:SimpleDocumentSoapOut"/> + </operation> + <operation name="ComplexDocument"> + <input message="tns:ComplexDocumentSoapIn"/> + <output message="tns:ComplexDocumentSoapOut"/> + </operation> + + </portType> + + <binding name="doc_test_binding" type="tns:DocTestPortType"> + <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> + + <operation name="SingleTag"> + <soap:operation soapAction="http://soapinterop.org/SingleTag"/> + <input> + <soap:body use="literal"/> + </input> + <output> + <soap:body use="literal"/> + </output> + </operation> + + <operation name="SimpleDocument"> + <soap:operation soapAction="http://soapinterop.org/SimpleDocument"/> + <input> + <soap:body use="literal"/> + </input> + <output> + <soap:body use="literal"/> + </output> + </operation> + + <operation name="ComplexDocument"> + <soap:operation soapAction="http://soapinterop.org/ComplexDocument"/> + <input> + <soap:body use="literal"/> + </input> + <output> + <soap:body use="literal"/> + </output> + </operation> + </binding> + + <service name="interopDocSvc"> + + <port name="interopDocPort" binding="tns:doc_test_binding"> + <soap:address location="http://www.whitemesa.net/interopdoc"/> + </port> + + </service> + +</definitions> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/HelloWorld.componentType b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/HelloWorld.componentType new file mode 100644 index 0000000000..bd1e9445c1 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/HelloWorld.componentType @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="ASCII"?> +<!-- + * 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. +--> + +<componentType xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + + <service name="HelloWorldService"> + <interface.java interface="helloworld.HelloWorldService"/> + </service> +</componentType> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/HelloWorld.js b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/HelloWorld.js new file mode 100644 index 0000000000..520153329e --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/HelloWorld.js @@ -0,0 +1,21 @@ +/* + * 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. + */ +function sayHello(s) { + return "Hello " + s; +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/IntrospectableHelloWorld.js b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/IntrospectableHelloWorld.js new file mode 100644 index 0000000000..2f6b7e0675 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/IntrospectableHelloWorld.js @@ -0,0 +1,25 @@ +/* + * 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. + */ +SCA = { + 'javaInterface' : 'helloworld.HelloWorldService' +} + +function sayHello(s) { + return "Hello " + s; +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/compositeScope.js b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/compositeScope.js new file mode 100644 index 0000000000..4684b89e66 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/compositeScope.js @@ -0,0 +1,29 @@ +/* + * 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. + */ +SCA = { + scope : 'composite', + javaInterface : 'helloworld.HelloWorldService' +} + +x = 0; + +function sayHello(s) { + x = x + 1; + return x; +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/e4x.componentType b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/e4x.componentType new file mode 100644 index 0000000000..8f2d906f58 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/e4x.componentType @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="ASCII"?> +<!-- + * 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. +--> + +<componentType xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + + <service name="HelloWorldService"> +<!-- <interface.wsdl interface="http://integration.rhino.container.tuscany.apache.org#HelloWorld"/> --> + <interface.java interface="helloworld.HelloWorldService"/> + </service> + + <reference name="extHelloWorldService"> + <interface.java interface="helloworld.HelloWorldService"/> + </reference> + + +</componentType> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/e4x.js b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/e4x.js new file mode 100644 index 0000000000..3e9c00fcb9 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/e4x.js @@ -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. + */ + +function sayE4XHello(xmlIn) { + + var greeting = "e4xHello " + xmlIn..*::name; + var xmlOut = getXmlObject("http://helloworld","getGreetingsResponse"); + + var ns = new Namespace("http://helloworld"); + xmlOut.ns::getGreetingsReturn = greeting; + + return xmlOut; +} + + + + function sayHello(name) { + //create XML Request Object + var xmlIn = getXmlObject("http://helloworld","getGreetings"); + var ns = new Namespace("http://helloworld"); + xmlIn.ns::name = name + " thro e4x reference"; + + //invoke service thro service reference and obtain XML Response + var xmlOut = extHelloWorldService.sayE4XHello(xmlIn); + + //extract the content of response XML and return as string + var greeting = "" + xmlOut..*::getGreetingsReturn; + return greeting; +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/helloworld.scdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/helloworld.scdl new file mode 100644 index 0000000000..c3c4f5c669 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/helloworld.scdl @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:js="http://incubator.apache.org/tuscany/xmlns/container/js/1.0-incubator-M2" + + name="HelloWorldComposite"> + + <component name="HelloWorldComponent"> + <js:implementation.js script="org/apache/tuscany/container/javascript/function/HelloWorld.js"/> + </component> + + <component name="IntrospectableHelloWorldComponent"> + <js:implementation.js script="org/apache/tuscany/container/javascript/function/IntrospectableHelloWorld.js"/> + </component> + + <component name="HelloWorldComponentE4X"> + <js:implementation.js script="org/apache/tuscany/container/javascript/function/e4x.js"/> + <reference name="extHelloWorldService" target="HelloWorldJavaReference">HelloWorldJavaReference</reference> + </component> + + <component name="HelloWorldJavaReference"> + <implementation.java class="helloworld.HelloWorldServiceImpl"/> + </component> + + <component name="HelloWorldProperty"> + <js:implementation.js script="org/apache/tuscany/container/javascript/function/propertyTest.js"/> + <property name="GREETING">Kia ora</property> + </component> + + <component name="HelloWorldPropertyDefault"> + <js:implementation.js script="org/apache/tuscany/container/javascript/function/propertyTest.js"/> + </component> +</composite> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/propertyTest.componentType b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/propertyTest.componentType new file mode 100644 index 0000000000..8e46971ea3 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/propertyTest.componentType @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="ASCII"?>
+<!--
+ * 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.
+-->
+<componentType xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <service name="HelloWorldService">
+ <interface.java interface="helloworld.HelloWorldService"/>
+ </service>
+
+ <property name="GREETING" type="xsd:string">Hi</property>
+
+</componentType>
diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/propertyTest.js b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/propertyTest.js new file mode 100644 index 0000000000..96e21d0c75 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/propertyTest.js @@ -0,0 +1,21 @@ +/*
+ * 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.
+ */
+function sayHello(s) {
+ return GREETING + ' ' + s;
+}
diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/requestScope.js b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/requestScope.js new file mode 100644 index 0000000000..bf8f840b91 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/requestScope.js @@ -0,0 +1,30 @@ +/* + * 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. + */ + +SCA = { + scope : 'request', + javaInterface : 'helloworld.HelloWorldService' +} + +x = 0; + +function sayHello(s) { + x = x + 1; + return x; +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/scopeTest.scdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/scopeTest.scdl new file mode 100644 index 0000000000..3754d69da1 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/scopeTest.scdl @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:js="http://incubator.apache.org/tuscany/xmlns/container/js/1.0-incubator-M2" + + name="HelloWorldComposite"> + + <component name="StatelessComponent"> + <js:implementation.js script="org/apache/tuscany/container/javascript/function/statelessScope.js"/> + </component> + + <!-- component name="RequestComponent"> + <js:implementation.js script="org/apache/tuscany/container/javascript/function/requestScope.js"/> + </component --> + + <!-- component name="CompositeScopeComponent"> + <js:implementation.js script="org/apache/tuscany/container/javascript/function/compositeScope.js"/> + </component --> + +</composite> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/statelessScope.js b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/statelessScope.js new file mode 100644 index 0000000000..21f5104859 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/function/statelessScope.js @@ -0,0 +1,29 @@ +/* + * 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. + */ +SCA = { + scope : 'stateless', + javaInterface : 'helloworld.HelloWorldService' +} + +x = 0; + +function sayHello(s) { + x = x + 1; + return x; +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/mock/test.js b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/mock/test.js new file mode 100644 index 0000000000..ef2694b475 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/mock/test.js @@ -0,0 +1 @@ +//Test Script
\ No newline at end of file diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/rhino/helloworld.wsdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/rhino/helloworld.wsdl new file mode 100644 index 0000000000..67067f044a --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/org/apache/tuscany/container/javascript/rhino/helloworld.wsdl @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. + --> +<wsdl:definitions targetNamespace="http://helloworld" xmlns:tns="http://helloworld" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" + name="helloworld"> + + <wsdl:types> + <schema elementFormDefault="qualified" targetNamespace="http://helloworld" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema"> + + <element name="getGreetings"> + <complexType> + <sequence> + <element name="name" type="xsd:string"/> + </sequence> + </complexType> + </element> + + <element name="getGreetingsResponse"> + <complexType> + <sequence> + <element name="getGreetingsReturn" type="xsd:string"/> + </sequence> + </complexType> + </element> + </schema> + </wsdl:types> + + <wsdl:message name="getGreetingsRequest"> + <wsdl:part element="tns:getGreetings" name="parameters"/> + </wsdl:message> + + <wsdl:message name="getGreetingsResponse"> + <wsdl:part element="tns:getGreetingsResponse" name="parameters"/> + </wsdl:message> + + <wsdl:portType name="HelloWorld"> + <wsdl:operation name="getGreetings"> + <wsdl:input message="tns:getGreetingsRequest" name="getGreetingsRequest"/> + <wsdl:output message="tns:getGreetingsResponse" name="getGreetingsResponse"/> + </wsdl:operation> + </wsdl:portType> + + <wsdl:binding name="HelloWorldSoapBinding" type="tns:HelloWorld"> + <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> + <wsdl:operation name="getGreetings"> + <wsdlsoap:operation soapAction=""/> + <wsdl:input name="getGreetingsRequest"> + <wsdlsoap:body use="literal"/> + </wsdl:input> + <wsdl:output name="getGreetingsResponse"> + <wsdlsoap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + </wsdl:binding> + + <wsdl:service name="HelloWorldService"> + <wsdl:port binding="tns:HelloWorldSoapBinding" name="HelloWorldSoapPort"> + <wsdlsoap:address location="http://localhost:8080/sample-helloworldws/services/HelloWorldWebService"/> + </wsdl:port> + </wsdl:service> + +</wsdl:definitions> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/sequences.xsd b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/sequences.xsd new file mode 100644 index 0000000000..a565f3fa65 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.javascript/src/test/resources/sequences.xsd @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. + --> +<xsd:schema xmlns:seq="http://www.example.com/sequences" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + targetNamespace="http://www.example.com/sequences"> + + <xsd:element name="mixedStockQuote" type="seq:MixedQuote" /> + <xsd:element name="rc" type="seq:RepeatingChoice" /> + <xsd:element name="mrc" type="seq:MixedRepeatingChoice" /> + <xsd:element name="rc2" type="seq:TwoRCs" /> + <xsd:element name="mrc2" type="seq:TwoRCsMixed" /> + + + + <xsd:complexType mixed="true" name="MixedQuote"> + <xsd:sequence> + <xsd:element name="symbol" type="xsd:string" /> + <xsd:element name="companyName" type="xsd:string" /> + <xsd:element name="price" type="xsd:decimal" /> + <xsd:element name="open1" type="xsd:decimal" /> + <xsd:element name="high" type="xsd:decimal" /> + <xsd:element name="low" type="xsd:decimal" /> + <xsd:element name="volume" type="xsd:double" /> + <xsd:element name="change1" type="xsd:double" /> + <xsd:element maxOccurs="unbounded" minOccurs="0" + name="quotes" type="seq:MixedQuote" /> + </xsd:sequence> + </xsd:complexType> + + + <xsd:complexType name="RepeatingChoice"> + <xsd:choice maxOccurs="unbounded" minOccurs="0"> + <xsd:element name="a" type="xsd:string" /> + <xsd:element name="b" type="xsd:int" /> + </xsd:choice> + </xsd:complexType> + + + <xsd:complexType mixed="true" name="MixedRepeatingChoice"> + <xsd:choice maxOccurs="unbounded" minOccurs="0"> + <xsd:element name="a" type="xsd:string" /> + <xsd:element name="b" type="xsd:int" /> + </xsd:choice> + </xsd:complexType> + + + <xsd:complexType name="TwoRCs"> + <xsd:sequence> + + <xsd:choice maxOccurs="unbounded" minOccurs="0"> + <xsd:element name="a" type="xsd:string" /> + <xsd:element name="b" type="xsd:int" /> + </xsd:choice> + + <xsd:element name="split" type="xsd:string" /> + + <xsd:choice maxOccurs="unbounded" minOccurs="0"> + <xsd:element name="y" type="xsd:string" /> + <xsd:element name="z" type="xsd:int" /> + </xsd:choice> + + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType mixed="true" name="TwoRCsMixed"> + <xsd:sequence> + + <xsd:choice maxOccurs="unbounded" minOccurs="0"> + <xsd:element name="a" type="xsd:string" /> + <xsd:element name="b" type="xsd:int" /> + </xsd:choice> + + <xsd:element name="split" type="xsd:string" /> + + <xsd:choice maxOccurs="unbounded" minOccurs="0"> + <xsd:element name="y" type="xsd:string" /> + <xsd:element name="z" type="xsd:int" /> + </xsd:choice> + + </xsd:sequence> + </xsd:complexType> + +</xsd:schema> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/LICENSE.txt b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/LICENSE.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/LICENSE.txt @@ -0,0 +1,202 @@ + + 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/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/NOTICE.txt b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/NOTICE.txt new file mode 100644 index 0000000000..d83ebbe236 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/NOTICE.txt @@ -0,0 +1,14 @@ +${pom.name} +Copyright (c) 2005 - 2006 The Apache Software Foundation + +Apache Tuscany is an effort undergoing incubation at The Apache Software +Foundation (ASF), sponsored by the Apache Web Services PMC. Incubation is +required of all newly accepted projects until a further review indicates that +the infrastructure, communications, and decision making process have stabilized +in a manner consistent with other successful ASF projects. While incubation +status is not necessarily a reflection of the completeness or stability of the +code, it does indicate that the project has yet to be fully endorsed by the ASF. + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/pom.xml b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/pom.xml new file mode 100644 index 0000000000..ebc911c10a --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/pom.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<project> + + <parent> + <groupId>org.apache.tuscany.sca.services.containers</groupId> + <artifactId>parent</artifactId> + <version>1.0-incubator-M2</version> + </parent> + + <modelVersion>4.0.0</modelVersion> + <artifactId>ruby</artifactId> + <name>Apache Tuscany Ruby Container</name> + <description>Apache Tuscany Ruby Container</description> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca.kernel</groupId> + <artifactId>tuscany-spi</artifactId> + <version>${sca.version}</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.jruby</groupId> + <artifactId>jruby</artifactId> + <version>0.9.1</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.tuscany.sca.services.idl</groupId> + <artifactId>wsdl</artifactId> + <version>${sca.version}</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>test</artifactId> + <version>${sca.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + </dependency> + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymockclassextension</artifactId> + </dependency> + <dependency> + <groupId>cglib</groupId> + <artifactId>cglib-nodep</artifactId> + <version>2.1_3</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.ws.commons.axiom</groupId> + <artifactId>axiom-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.ws.commons.axiom</groupId> + <artifactId>axiom-impl</artifactId> + </dependency> + </dependencies> +</project> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyComponent.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyComponent.java new file mode 100644 index 0000000000..7a244b828c --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyComponent.java @@ -0,0 +1,134 @@ +/* + * 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.container.ruby; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.container.ruby.rubyscript.RubyScript; +import org.apache.tuscany.container.ruby.rubyscript.RubyScriptInstance; +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.extension.AtomicComponentExtension; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.WireService; + +/** + * The Ruby component implementation. + */ +public class RubyComponent extends AtomicComponentExtension { + + private final List<Class<?>> services; + + private final Map<String, Object> properties; + + private RubyScript rubyScript; + + private String rubyClassName; + + public RubyComponent(String name, + RubyScript rubyScript, + String rubyClassName, + List<Class<?>> services, + Map<String, Object> propValues, + CompositeComponent parent, + ScopeContainer scopeContainer, + WireService wireService, + WorkContext workContext) { + super(name, parent, scopeContainer, wireService, workContext, null, 0); + + this.rubyScript = rubyScript; + this.rubyClassName = rubyClassName; + this.services = services; + this.scope = scopeContainer.getScope(); + //this.properties = new HashMap<String, Object>(); + this.properties = propValues; + } + + public Object createInstance() throws ObjectCreationException { + + Map<String, Object> context = new HashMap<String, Object>(getProperties()); + + for (List<OutboundWire> referenceWires : getOutboundWires().values()) { + for (OutboundWire wire : referenceWires) { + Object wireProxy = wireService.createProxy(wire); + //since all types that may be used in the reference interface may not be known to Rhino + //using the wireProxy as is will fail result in type conversion exceptions in cases where + //Rhino does not know enough of the tpypes used. Hence introduce a interceptor proxy, + //with weak typing (java.lang.Object) so that Rhino's call to the proxy succeeds. Then + //within this interceptor proxy perform data mediations required to correctly call the + //referenced service. + Class<?> businessInterface = wire.getServiceContract().getInterfaceClass(); + RubyReferenceProxy interceptingProxy = new RubyReferenceProxy(businessInterface, + wireProxy, + rubyScript.getRubyEngine()); + context.put(wire.getReferenceName(), interceptingProxy.createProxy()); + } + } + + Object instance = rubyScript.createScriptInstance(context, rubyClassName); + + return instance; + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) { + /*Method[] methods = operation.getServiceContract().getInterfaceClass().getMethods(); + Method method = findMethod(operation, + methods);*/ + return new RubyInvoker(operation.getName(), this, operation.getOutputType().getPhysical().getClass()); + } + + // TODO: move all the following up to AtomicComponentExtension? + + public List<Class<?>> getServiceInterfaces() { + return services; + } + + public Map<String, Object> getProperties() { + return properties; + } + + public RubyScriptInstance getTargetInstance() throws TargetException { + return (RubyScriptInstance) scopeContainer.getInstance(this); + } + + public Object getServiceInstance() throws TargetException { + return getServiceInstance(null); + } + + @SuppressWarnings("unchecked") + public Object getServiceInstance(String service) throws TargetException { + InboundWire wire = getInboundWire(service); + if (wire == null) { + TargetException e = new TargetException("ServiceDefinition not found"); // TODO better error message + e.setIdentifier(service); + throw e; + } + return wireService.createProxy(wire); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyComponentBuilder.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyComponentBuilder.java new file mode 100644 index 0000000000..bdbbd1871c --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyComponentBuilder.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.container.ruby; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.container.ruby.rubyscript.RubyScript; +import org.apache.tuscany.spi.builder.BuilderConfigException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentBuilderExtension; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.PropertyValue; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * Extension point for creating {@link RubyComponent}s from an assembly configuration + */ +public class RubyComponentBuilder extends ComponentBuilderExtension<RubyImplementation> { + + protected Class<RubyImplementation> getImplementationType() { + return RubyImplementation.class; + } + + @SuppressWarnings("unchecked") + public Component build(CompositeComponent parent, + ComponentDefinition<RubyImplementation> componentDefinition, + DeploymentContext deploymentContext) throws BuilderConfigException { + + String name = componentDefinition.getName(); + RubyImplementation implementation = componentDefinition.getImplementation(); + RubyComponentType componentType = implementation.getComponentType(); + + // get list of services provided by this component + Collection<ServiceDefinition> collection = componentType.getServices().values(); + List<Class<?>> services = new ArrayList<Class<?>>(collection.size()); + for (ServiceDefinition serviceDefinition : collection) { + services.add(serviceDefinition.getServiceContract().getInterfaceClass()); + } + + Map<String, Object> propertyValues = new Hashtable<String, Object>(); + Collection<PropertyValue<?>> propValueSettings = componentDefinition.getPropertyValues().values(); + for (PropertyValue propertyValue : propValueSettings) { + propertyValues.put(propertyValue.getName(), + propertyValue.getValueFactory().getInstance()); + } + + RubyScript rubyScript = implementation.getRubyScript(); + + // TODO: have ComponentBuilderExtension pass ScopeContainer in on build method? + ScopeContainer scopeContainer; + Scope scope = componentType.getLifecycleScope(); + if (Scope.MODULE == scope) { + scopeContainer = deploymentContext.getModuleScope(); + } else { + scopeContainer = scopeRegistry.getScopeContainer(scope); + } + + return new RubyComponent(name, + rubyScript, + implementation.getRubyClassName(), + services, + propertyValues, + parent, + scopeContainer, + wireService, + workContext); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyComponentType.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyComponentType.java new file mode 100644 index 0000000000..1b98cf86d6 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyComponentType.java @@ -0,0 +1,58 @@ +/* + * 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.container.ruby; + +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceDefinition; + +public class RubyComponentType extends + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> { + + private Scope lifecycleScope = Scope.MODULE; + + public RubyComponentType() { + } + + @SuppressWarnings("unchecked") + public RubyComponentType(ComponentType ct) { + // TODO: A bit hacky but this is so the non-Ruby .componentType side file can be used for now + setInitLevel(ct.getInitLevel()); + for (Object property : ct.getProperties().values()) { + add((Property) property); + } + for (Object reference : ct.getReferences().values()) { + add((ReferenceDefinition) reference); + } + for (Object service : ct.getServices().values()) { + add((ServiceDefinition) service); + } + } + + public Scope getLifecycleScope() { + return lifecycleScope; + } + + public void setLifecycleScope(Scope lifecycleScope) { + this.lifecycleScope = lifecycleScope; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyComponentTypeLoader.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyComponentTypeLoader.java new file mode 100644 index 0000000000..6fc5f87c68 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyComponentTypeLoader.java @@ -0,0 +1,118 @@ +/* + * 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.container.ruby; + +import java.net.URL; + +import org.apache.tuscany.container.ruby.rubyscript.RubySCAConfig; +import org.apache.tuscany.container.ruby.rubyscript.RubyScript; +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.MissingResourceException; +import org.apache.tuscany.spi.model.ComponentType; + +/** + * @version $Rev$ $Date$ + */ +public class RubyComponentTypeLoader extends ComponentTypeLoaderExtension<RubyImplementation> { + + private JavaInterfaceProcessorRegistry processorRegistry; + + public RubyComponentTypeLoader(@Autowire + JavaInterfaceProcessorRegistry processorRegistry) { + this.processorRegistry = processorRegistry; + } + + @Override + protected Class<RubyImplementation> getImplementationClass() { + return RubyImplementation.class; + } + + protected RubyComponentType loadByIntrospection(CompositeComponent parent, + RubyImplementation implementation, + DeploymentContext deploymentContext) throws + MissingResourceException, + InvalidServiceContractException { + + RubyScript rubyScript = implementation.getRubyScript(); + RubySCAConfig scaConfig = rubyScript.getSCAConfig(); + if (!scaConfig.hasSCAConfig()) { + throw new IllegalArgumentException( + "must use either .componentType side file or Ruby Global variable $SCA definition"); + } + + // FIXME this should be a system service, not instantiated here + RubyComponentType componentType = new RubyIntrospector(null, processorRegistry) + .introspectScript(scaConfig, rubyScript.getClassLoader()); + + return componentType; + } + + protected String getResourceName(RubyImplementation implementation) { + return implementation.getRubyScript().getScriptName(); + } + + // TODO: must be possible to move all the following up in to ComponentTypeLoaderExtension + + public void load(CompositeComponent parent, + RubyImplementation implementation, + DeploymentContext deploymentContext) throws LoaderException { + + URL resource = implementation.getRubyScript().getClassLoader().getResource(getSideFileName(implementation)); + RubyComponentType componentType; + if (resource == null) { + try { + componentType = loadByIntrospection(parent, implementation, deploymentContext); + } catch (InvalidServiceContractException e) { + throw new LoaderException("Invalid service contract", e); + } + } else { + componentType = loadFromSidefile(resource, deploymentContext); + } + + implementation.setComponentType(componentType); + + + } + + protected RubyComponentType loadFromSidefile(URL url, DeploymentContext deploymentContext) throws LoaderException { + ComponentType ct = loaderRegistry.load(null, + url, + ComponentType.class, + deploymentContext); + RubyComponentType jsct = new RubyComponentType(ct); + return jsct; + } + + private String getSideFileName(RubyImplementation implementation) { + String baseName = getResourceName(implementation); + int lastDot = baseName.lastIndexOf('.'); + if (lastDot != -1) { + baseName = baseName.substring(0, + lastDot); + } + return baseName + ".componentType"; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyImplementation.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyImplementation.java new file mode 100644 index 0000000000..6f07399d0a --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyImplementation.java @@ -0,0 +1,48 @@ +/* + * 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.container.ruby; + +import org.apache.tuscany.container.ruby.rubyscript.RubyScript; +import org.apache.tuscany.spi.model.AtomicImplementation; + +/** + * Model object for a JavaScript implementation. + */ +public class RubyImplementation extends AtomicImplementation<RubyComponentType> { + + private RubyScript rubyScript; + + private String rubyClassName; + + public String getRubyClassName() { + return rubyClassName; + } + + public void setRubyClassName(String rubyClassName) { + this.rubyClassName = rubyClassName; + } + + public RubyScript getRubyScript() { + return rubyScript; + } + + public void setRubyScript(RubyScript rubyScript) { + this.rubyScript = rubyScript; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyImplementationLoader.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyImplementationLoader.java new file mode 100644 index 0000000000..322e3d84e8 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyImplementationLoader.java @@ -0,0 +1,123 @@ +/* + * 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.container.ruby; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.container.ruby.rubyscript.RubyScript; +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.LoaderExtension; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.LoaderUtil; +import org.apache.tuscany.spi.loader.MissingResourceException; +import org.osoa.sca.annotations.Constructor; + +/** + * Loader for handling JavaScript <js:implementation.js> elements. + */ +public class RubyImplementationLoader extends LoaderExtension<RubyImplementation> { + private static final QName IMPLEMENTATION_RUBY = new QName( + "http://incubator.apache.org/tuscany/xmlns/container/rb/1.0-incubator-M2", "implementation.rb"); + + @Constructor({"registry"}) + public RubyImplementationLoader(@Autowire + LoaderRegistry registry) { + super(registry); + } + + public QName getXMLType() { + return IMPLEMENTATION_RUBY; + } + + public RubyImplementation load(CompositeComponent parent, + XMLStreamReader reader, + DeploymentContext deploymentContext) throws XMLStreamException, + LoaderException { + + String script = reader.getAttributeValue(null, + "script"); + String rubyClassName = reader.getAttributeValue(null,"class"); + + if ( script == null ) { + throw new MissingResourceException("No script supplied"); + } + + ClassLoader cl = deploymentContext.getClassLoader(); + String source = loadSource(cl, + script); + + LoaderUtil.skipToEndElement(reader); + + RubyImplementation implementation = new RubyImplementation(); + RubyScript rubyScript = new RubyScript(script, source, null, cl); + implementation.setRubyScript(rubyScript); + implementation.setRubyClassName(rubyClassName); + registry.loadComponentType(parent, + implementation, + deploymentContext); + return implementation; + } + + protected String loadSource(ClassLoader cl, String resource) throws LoaderException { + URL url = cl.getResource(resource); + if (url == null) { + throw new MissingResourceException(resource); + } + InputStream is; + try { + is = url.openStream(); + } catch (IOException e) { + MissingResourceException mre = new MissingResourceException(resource, e); + mre.setIdentifier(resource); + throw mre; + } + try { + Reader reader = new InputStreamReader(is, "UTF-8"); + char[] buffer = new char[1024]; + StringBuilder source = new StringBuilder(); + int count; + while ((count = reader.read(buffer)) > 0) { + source.append(buffer, + 0, + count); + } + return source.toString(); + } catch (IOException e) { + LoaderException le = new LoaderException(e); + le.setIdentifier(resource); + throw le; + } finally { + try { + is.close(); + } catch (IOException e) { + // ignore + } + } + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyIntrospector.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyIntrospector.java new file mode 100644 index 0000000000..d5ef41d835 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyIntrospector.java @@ -0,0 +1,173 @@ +/* + * 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.container.ruby; + +import java.util.Iterator; +import java.util.Map; + +import javax.wsdl.Definition; +import javax.wsdl.PortType; +import javax.wsdl.WSDLException; +import javax.wsdl.factory.WSDLFactory; +import javax.wsdl.xml.WSDLReader; +import javax.xml.namespace.QName; + +import org.apache.tuscany.container.ruby.rubyscript.RubySCAConfig; +import org.apache.tuscany.idl.wsdl.WSDLDefinitionRegistry; +import org.apache.tuscany.idl.wsdl.WSDLServiceContract; +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.loader.MissingResourceException; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * Introspects JavaScript files for SCA configuration + */ +public class RubyIntrospector { + + private WSDLDefinitionRegistry wsdlRegistry; + private JavaInterfaceProcessorRegistry processorRegistry; + + public RubyIntrospector(@Autowire WSDLDefinitionRegistry wsdlRegistry, + @Autowire JavaInterfaceProcessorRegistry processorRegistry) { + this.wsdlRegistry = wsdlRegistry; + this.processorRegistry = processorRegistry; + } + + public RubyComponentType introspectScript(RubySCAConfig scaConfig, ClassLoader cl) + throws MissingResourceException, InvalidServiceContractException { + RubyComponentType componentType = new RubyComponentType(); + introspectJavaInterface(componentType, cl, scaConfig.getJavaInterface()); + introspectWSDLInterface(componentType, cl, scaConfig.getWSDLNamespace(), scaConfig.getWSDLPortType(), + scaConfig.getWSDLLocation()); + introspectReferences(componentType, cl, scaConfig.getReferences()); + introspectProperties(componentType, cl, scaConfig.getProperties()); + introspectScope(componentType, scaConfig.getScope()); + return componentType; + } + + private void introspectScope(RubyComponentType componentType, Scope scope) { + if (scope != null) { + componentType.setLifecycleScope(scope); + } + } + + @SuppressWarnings("unchecked") + private void introspectJavaInterface(ComponentType componentType, ClassLoader cl, String serviceClass) + throws MissingResourceException, InvalidServiceContractException { + if (serviceClass != null) { + ServiceDefinition service = new ServiceDefinition(); + try { + ServiceContract<?> sc = processorRegistry.introspect(Class.forName(serviceClass)); + service.setServiceContract(sc); + componentType.add(service); + } catch (ClassNotFoundException e) { + throw new MissingResourceException("Interface not found", e); + } + } + } + + @SuppressWarnings("unchecked") + private void introspectWSDLInterface(ComponentType componentType, ClassLoader cl, String wsdlNamespace, + String wsdlPortType, String wsdlLocation) { + if (wsdlNamespace == null && wsdlPortType == null && wsdlLocation == null) { + return; + } + + PortType portType = null; + if (wsdlLocation != null) { + portType = readWSDLPortType(wsdlNamespace, wsdlPortType, wsdlLocation, portType); + } else { + portType = getPortType(wsdlNamespace, wsdlPortType); + } + + ServiceDefinition service = new ServiceDefinition(); + WSDLServiceContract wsdlSC = new WSDLServiceContract(); + wsdlSC.setPortType(portType); + service.setServiceContract(wsdlSC); + componentType.add(service); + } + + private PortType readWSDLPortType(String wsdlNamespace, String wsdlPortType, String wsdlLocation, + PortType portType) { + Definition wsdlDefinition; + try { + WSDLReader reader = WSDLFactory.newInstance().newWSDLReader(); + reader.setFeature("javax.wsdl.verbose", false); + wsdlDefinition = reader.readWSDL(wsdlLocation.toString()); + } catch (WSDLException e) { + throw new RuntimeException(e); + + } + Map portTypes = wsdlDefinition.getPortTypes(); + for (Iterator i = portTypes.keySet().iterator(); i.hasNext();) { + QName portTypeQN = (QName) i.next(); + if (wsdlNamespace != null) { + if (!portTypeQN.getNamespaceURI().equals(wsdlNamespace)) { + continue; + } + } + if (wsdlPortType != null) { + if (!portTypeQN.getLocalPart().equals(wsdlPortType)) { + continue; + } + } + if (portType != null) { + throw new RuntimeException("multiple matching portTypes in wsdl: " + wsdlLocation); + } + portType = (PortType) portTypes.get(portTypeQN); + } + if (portType == null) { + throw new RuntimeException("portType not found in wsdl: " + wsdlLocation); + } + return portType; + } + + private PortType getPortType(String wsdlNamespace, String wsdlPortType) { + if (wsdlPortType == null) { + throw new IllegalArgumentException("must specify the wsdlPortType in script SCA config"); + } + PortType portType = null; + if (wsdlNamespace != null) { + QName portTypeQN = new QName(wsdlNamespace.toString(), wsdlPortType.toString()); + portType = wsdlRegistry.getPortType(portTypeQN); + if (portType == null) { + throw new IllegalArgumentException("no WSDL registered for portType: " + portTypeQN); + } + } else { + // wsdlRegistry.getPortType(wsdlPortType.toString()); + if (portType == null) { + throw new IllegalArgumentException("no WSDL registered for portType:" + wsdlPortType); + } + } + return portType; + } + + + private void introspectProperties(ComponentType componentType, ClassLoader cl, Map properties) { + } + + private void introspectReferences(ComponentType componentType, ClassLoader cl, Map references) { + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyInvoker.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyInvoker.java new file mode 100644 index 0000000000..a40f04612e --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyInvoker.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.container.ruby; + +import java.lang.reflect.InvocationTargetException; + +import org.apache.tuscany.container.ruby.rubyscript.RubyScriptInstance; +import org.apache.tuscany.spi.extension.TargetInvokerExtension; + +/** + * Dispatches to a JavaScript implementation instance + * + * @version $$Rev$$ $$Date$$ + */ +public class RubyInvoker extends TargetInvokerExtension { + + private RubyComponent context; + + private String functionName; + + private Class returnType; + + public RubyInvoker(String functionName, RubyComponent context, Class returnType) { + this.functionName = functionName; + this.context = context; + this.returnType = returnType; + } + + /** + * Invokes a function on a script instance + */ + public Object invokeTarget(final Object payload) throws InvocationTargetException { + RubyScriptInstance target = context.getTargetInstance(); + return target.invokeFunction(functionName, + (Object[]) payload, + returnType); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyRefInvocInterceptor.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyRefInvocInterceptor.java new file mode 100644 index 0000000000..bf62d1fcab --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyRefInvocInterceptor.java @@ -0,0 +1,92 @@ +/*
+ * 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.container.ruby;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+import org.jruby.IRuby;
+import org.jruby.RubyObject;
+import org.jruby.javasupport.JavaUtil;
+
+/**
+ * This Interceptor encasulates the data mediation required by the JavaScriptReferenceProxy. The
+ * invocation handler of this class traps the javascript reference calls, performs data mediation
+ * and calls then calls the actual referred service. This classes implementation is subject to
+ * review and change when the DataMediation infrastructure of Tuscany is ready.
+ *
+ */
+public class RubyRefInvocInterceptor implements InvocationHandler {
+ private Object actualProxy;
+
+ private Class wireInterface;
+
+ private IRuby rubyEngine;
+
+ RubyRefInvocInterceptor(Object wireProxy, Class wireIfc, IRuby rubyEng) {
+ this.actualProxy = wireProxy;
+ this.wireInterface = wireIfc;
+ this.rubyEngine = rubyEng;
+ }
+
+ public Object invoke(Object arg0, Method method, Object[] args) throws Throwable {
+ if ( method.getName().equals("hashCode"))
+ return new Integer(1);
+
+ Method invokedMethod = getInvokedMethod(method.getName());
+ Object[] tranformedArgs = new Object[args.length];
+ for (int count = 0; count < args.length; ++count) {
+ tranformedArgs[count] = fromRubyToJava(invokedMethod.getParameterTypes()[count], args[count]);
+ }
+
+ Object response = invokedMethod.invoke(actualProxy, tranformedArgs);
+ response = fromJavaToRuby(response);
+ return response;
+ }
+
+ private Method getInvokedMethod(String methodName) {
+ Method[] methods = wireInterface.getMethods();
+
+ for (int count = 0; count < methods.length; ++count) {
+ if (methods[count].getName().equals(methodName)) {
+ return methods[count];
+ }
+ }
+ throw new RuntimeException("Unable to find invocation method");
+ }
+
+ protected Object fromRubyToJava(Class reqArgType, Object rubyArg) throws Exception {
+ Object javaArg = null;
+
+ //for known cases the JRuby runtime handles the conversion before calling the Java objects
+ //so nothing to do. When it cannot convert it simply passed the instance of RubyObject
+ if ( rubyArg instanceof RubyObject ) {
+ //need to deal with this
+ } else {
+ javaArg = rubyArg;
+ }
+
+ return javaArg;
+ }
+
+ protected Object fromJavaToRuby(Object retVal) throws RuntimeException {
+ Object rubyRetVal = JavaUtil.convertJavaToRuby(rubyEngine, retVal, retVal.getClass());
+ return rubyRetVal;
+ }
+}
diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyReferenceProxy.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyReferenceProxy.java new file mode 100644 index 0000000000..4d91194484 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/RubyReferenceProxy.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.container.ruby;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.jruby.IRuby;
+import org.jruby.RubyException;
+
+import net.sf.cglib.asm.ClassWriter;
+import net.sf.cglib.asm.CodeVisitor;
+import net.sf.cglib.asm.Constants;
+import net.sf.cglib.asm.Type;
+
+/**
+ * This is a proxy that will mediate reference calls from the JavaScript. The mediation code here will be reviewed when the DataMediation
+ * infrastructure is ready. This proxy assmes that there is no verloading of service methods on the reference interface i.e. there are no two service
+ * methods that have the same method name or operation name.
+ */
+public class RubyReferenceProxy {
+
+ private Class interfaze;
+
+ private Object wireProxy;
+
+ private IRuby rubyEngine;
+
+ public RubyReferenceProxy(Class interfaze, Object wireProxy, IRuby rubyEng) {
+ this.interfaze = interfaze;
+ this.wireProxy = wireProxy;
+ this.rubyEngine = rubyEng;
+ }
+
+ public Object createProxy() {
+ try {
+ GenericProxyClassLoader classloader = new GenericProxyClassLoader();
+ final byte[] byteCode = generateGenericInterface(interfaze);
+
+ Class genericInterface = classloader.defineClass(byteCode);
+ InvocationHandler proxyHandler = new RubyRefInvocInterceptor(wireProxy, interfaze, rubyEngine);
+ // return genericInterface.cast(Proxy.newProxyInstance(classloader, new Class[]{genericInterface}, proxyHandler));
+ return Proxy.newProxyInstance(classloader,
+ new Class[]{genericInterface},
+ proxyHandler);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private static byte[] generateGenericInterface(Class serviceInterface) {
+ String interfazeName = serviceInterface.getCanonicalName();
+ ClassWriter cw = new ClassWriter(false);
+
+ cw.visit(Constants.V1_5,
+ Constants.ACC_PUBLIC + Constants.ACC_ABSTRACT + Constants.ACC_INTERFACE,
+ interfazeName.replace('.',
+ '/'),
+ "java/lang/Object",
+ null,
+ serviceInterface.getSimpleName() + ".java");
+
+ StringBuffer argsAndReturn = new StringBuffer("(");
+ Method[] methods = serviceInterface.getMethods();
+ for (int count = 0; count < methods.length; ++count) {
+ argsAndReturn = new StringBuffer("(");
+ Class[] paramTypes = methods[count].getParameterTypes();
+ Class returnType = methods[count].getReturnType();
+
+ for (int paramCount = 0; paramCount < paramTypes.length; ++paramCount) {
+ argsAndReturn.append(Type.getType(Object.class));
+ }
+ argsAndReturn.append(")");
+ argsAndReturn.append(Type.getType(Object.class));
+
+ Class[] exceptionTypes = methods[count].getExceptionTypes();
+ String[] exceptions = new String[exceptionTypes.length];
+ for (int excCount = 0; excCount < exceptionTypes.length; ++excCount) {
+ exceptions[excCount] = exceptionTypes[excCount].getName();
+ exceptions[excCount] = exceptions[excCount].replace('.',
+ '/');
+ }
+
+ CodeVisitor cv = cw.visitMethod(Constants.ACC_PUBLIC + Constants.ACC_ABSTRACT,
+ methods[count].getName(),
+ argsAndReturn.toString(),
+ exceptions,
+ null);
+ cw.visitEnd();
+ }
+
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+
+ private class GenericProxyClassLoader extends ClassLoader {
+ public Class defineClass(byte[] byteArray) {
+ try {
+ return defineClass(null,
+ byteArray,
+ 0,
+ byteArray.length);
+ } catch (Throwable e) {
+ return null;
+ }
+ }
+
+ }
+}
diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/rubyscript/RubySCAConfig.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/rubyscript/RubySCAConfig.java new file mode 100644 index 0000000000..4d14d8a56a --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/rubyscript/RubySCAConfig.java @@ -0,0 +1,159 @@ +/* + * 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.container.ruby.rubyscript; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.model.Scope; +import org.jruby.RubyHash; +import org.jruby.RubyObject; +import org.jruby.internal.runtime.GlobalVariables; +import org.jruby.runtime.builtin.IRubyObject; + +/** + * Represents the variable defining the SCA aspects of the script + * <code> + * SCA = { + * javaInterface : "my.pkg.ClassName", + * wsdlPortType : "wsdlPortTypeName", + * wsdlNameSpace : "http://my.namespace.com", + * wsdlLocation : "\wsdl\mywsdl.txt", + * properties : { "foo" : ["java.lang.String", "defaultValue"],}, + * references : {}, + * scope : 'stateless'|'request'|'conversational'|'composite', + * } + * </code> + * The config must define the service with either javaInterface or wsdl. When + * using wsdl the three parameters are optional. If wsdlLocation is used that is the + * WSDL document used, and the namespace and portType parameters are only required if + * the WSDL definition defines multiple portTypes. + */ +public class RubySCAConfig { + + private boolean hasSCAConfig; + + private String javaInterface; + + private String wsdlLocation; + + private String wsdlNamespace; + + private String wsdlPortType; + + private Map properties; + + private Map references; + + private Scope scope; + + public RubySCAConfig(GlobalVariables globalVariables) { + IRubyObject rubyObject = globalVariables.get("$SCA"); + if (rubyObject != null && !rubyObject.isNil()) { + hasSCAConfig = true; + RubyHash scaVar = (RubyHash) rubyObject; + Object o = scaVar.get("javaInterface"); + if ( o != null ) { + this.javaInterface = o.toString(); + } + o = scaVar.get("wsdlLocation"); + if (o != null ) { + this.wsdlLocation = o.toString(); + } + o = scaVar.get("wsdlPortType"); + if (o != null ) { + this.wsdlPortType = o.toString(); + } + o = scaVar.get("wsdlNamespace"); + if (o != null ) { + this.wsdlNamespace = o.toString(); + } + if (javaInterface != null) { + if (wsdlLocation != null || wsdlPortType != null || wsdlNamespace != null) { + throw new IllegalArgumentException("script SCA config defines both Java and WSDL service interface"); + } + } else { + if (wsdlLocation == null && wsdlPortType == null && wsdlNamespace == null) { + throw new IllegalArgumentException("script SCA config must define either Java or WSDL service interface"); + } + } + + this.properties = new HashMap(); + o = scaVar.get("properties"); + if (o != null ) { + // TODO parse properties + } + + this.references = new HashMap(); + o = scaVar.get("references"); + if (o != null ) { + // TODO parse references + } + + o = scaVar.get("scope"); + if (o != null ) { + if ("stateless".equalsIgnoreCase(String.valueOf(o))) { + this.scope = Scope.STATELESS; + } else if ("request".equalsIgnoreCase(String.valueOf(o))) { + this.scope = Scope.REQUEST; + } else if ("conversational".equalsIgnoreCase(String.valueOf(o))) { + this.scope = Scope.SESSION; // TODO: where's CONVERSATIONAL? + } else if ("composite".equalsIgnoreCase(String.valueOf(o))) { + this.scope = Scope.MODULE; // TODO: composite = MODULE for now? + } else { + throw new IllegalArgumentException("invalid scope value: " + o); + } + } + + } + } + + public boolean hasSCAConfig() { + return hasSCAConfig; + } + + public String getJavaInterface() { + return javaInterface; + } + + public Map getProperties() { + return properties; + } + + public Map getReferences() { + return references; + } + + public String getWSDLLocation() { + return wsdlLocation; + } + + public String getWSDLNamespace() { + return wsdlNamespace; + } + + public String getWSDLPortType() { + return wsdlPortType; + } + + public Scope getScope() { + return scope; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/rubyscript/RubyScript.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/rubyscript/RubyScript.java new file mode 100644 index 0000000000..87d995eabd --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/rubyscript/RubyScript.java @@ -0,0 +1,160 @@ +/* + * 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.container.ruby.rubyscript; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Vector; + +import org.jruby.IRuby; +import org.jruby.RubyString; +import org.jruby.javasupport.JavaEmbedUtils; +import org.jruby.javasupport.JavaUtil; +import org.jruby.runtime.builtin.IRubyObject; + +/** + * A RhinoScript represents a compiled JavaScript script + */ +public class RubyScript { + protected final String NEW = ".new"; + protected final String EQUAL = "="; + + protected String scriptName; + + protected String script; + + protected Map<String, Class> responseClasses; + + protected ClassLoader classLoader; + + private IRuby rubyEngine = JavaEmbedUtils.initialize(new Vector()); + + /** + * Create a new RubyScript. + * + * @param scriptName + * the name of the script. Can be anything, only used in messages to identify the script + * @param script + * the complete script + */ + public RubyScript(String scriptName, String script) { + this(scriptName, script, (Map) null, null); + } + + /** + * Create a new RubyScript. + * + * @param scriptName + * the name of the script. Can be anything, only used in messages to identify the script + * @param script + * the complete script + * @param context + * name-value pairs that are added in to the scope where the script is compiled. May be null. The value objects are made available to + * the script by using a variable with the name. + * @param classLoader + * the ClassLoader to be used to locate any user Java classes used in the script + */ + public RubyScript(String scriptName, String script, Map context, ClassLoader classLoader) { + this.scriptName = scriptName; + this.script = script; + this.responseClasses = new HashMap<String, Class>(); + this.classLoader = classLoader; + rubyEngine.loadScript((RubyString) JavaUtil.convertJavaToRuby(rubyEngine, + "MyScript.rb", + String.class), + (RubyString) JavaUtil.convertJavaToRuby(rubyEngine, + this.script, + String.class), + false); + } + + /** + * Create a new invokeable instance of the script + * + * @return a IRubyObject + */ +public RubyScriptInstance createScriptInstance(Map<String, Object> context, String rubyClassName) { + if ( rubyClassName == null ) { + return new RubyScriptInstance(rubyEngine.evalScript(script), responseClasses); + } + else { + IRubyObject rubyObject = rubyEngine.evalScript(rubyClassName + NEW); + + Iterator<String> keyIterator = context.keySet().iterator(); + String key = null; + Object value = null; + while ( keyIterator.hasNext()) { + key = keyIterator.next(); + value = JavaUtil.convertJavaToRuby(rubyEngine, + context.get(key), + context.get(key).getClass()); + + JavaEmbedUtils.invokeMethod(rubyEngine, + rubyObject, + key + EQUAL, + new Object[]{value}, null); + } + + return new RubyScriptInstance(rubyObject, responseClasses); + } + } + public String getScript() { + return script; + } + + public String getScriptName() { + return scriptName; + } + + public Map<String, Class> getResponseClasses() { + return responseClasses; + } + + public ClassLoader getClassLoader() { + return classLoader; + } + + /** + * Set the Java type of a response value. JavaScript is dynamically typed so Rhino cannot always work out what the intended Java type of a + * response should be, for example should the statement "return 42" be a Java int, or Integer or Double etc. When Rhino can't determine the type + * it will default to returning a String, using this method enables overriding the Rhino default to use a specific Java type. + */ + public void setResponseClass(String functionName, Class responseClasses) { + this.responseClasses.put(functionName, + responseClasses); + } + + public RubySCAConfig getSCAConfig() { + return new RubySCAConfig(rubyEngine.getGlobalVariables()); + } + + public void setScript(String script) { + this.script = script; + } + + public IRuby getRubyEngine() { + return rubyEngine; + } + + public void setRubyEngine(IRuby rubyEngine) { + this.rubyEngine = rubyEngine; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/rubyscript/RubyScriptInstance.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/rubyscript/RubyScriptInstance.java new file mode 100644 index 0000000000..2d93c57fc9 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/rubyscript/RubyScriptInstance.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.container.ruby.rubyscript; + +import java.util.HashMap; +import java.util.Map; + +import org.jruby.javasupport.JavaEmbedUtils; +import org.jruby.runtime.builtin.IRubyObject; + +/** + * An invokeable instance of a JavaScript script. + */ +public class RubyScriptInstance { + + private IRubyObject rubyInstance; + + private Map<String, Class> responseClasses; + + public RubyScriptInstance(IRubyObject rubyInstance, Map<String, Class> responseClasses) { + this.rubyInstance = rubyInstance; + this.responseClasses = responseClasses; + if (this.responseClasses == null) { + this.responseClasses = new HashMap<String, Class>(); + } + } + + public Object invokeFunction(String functionName, Object[] args, Class returnType) { + Object[] rubyArgs = RubyUtils.fromJavaToRuby(rubyInstance.getRuntime(), args); + + Object rubyResponse = JavaEmbedUtils.invokeMethod(rubyInstance.getRuntime(), + rubyInstance, + functionName, + rubyArgs, + returnType); + Object response = RubyUtils.fromRubyToJava(rubyInstance.getRuntime(), + returnType, + rubyResponse); + return response; + } + + + + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/rubyscript/RubyUtils.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/rubyscript/RubyUtils.java new file mode 100644 index 0000000000..c19f233b94 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/java/org/apache/tuscany/container/ruby/rubyscript/RubyUtils.java @@ -0,0 +1,71 @@ +/*
+ * 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.container.ruby.rubyscript;
+
+import java.io.ByteArrayInputStream;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.util.StAXUtils;
+import org.jruby.IRuby;
+import org.jruby.RubyObject;
+import org.jruby.javasupport.JavaUtil;
+
+/**
+ * @author administrator
+ *
+ */
+public class RubyUtils {
+ public static Object fromRubyToJava(IRuby rubyEngine, Class reqArgType, Object rubyArg) {
+ Object javaArg = null;
+
+ //for known cases the JRuby runtime handles the conversion before calling the Java objects
+ //so nothing to do. When it cannot convert it simply passed the instance of RubyObject
+ if ( rubyArg instanceof RubyObject ) {
+ //need to deal with this
+ } else {
+ javaArg = rubyArg;
+ }
+
+ return javaArg;
+ }
+
+ public static Object[] fromJavaToRuby(IRuby rubyEngine, Object[] arg) {
+ Object[] jsArgs;
+ if (arg == null) {
+ jsArgs = new Object[0];
+ } else {
+ jsArgs = new Object[arg.length];
+ for (int i = 0; i < jsArgs.length; i++) {
+ jsArgs[i] = fromJavaToRuby(rubyEngine, arg[i]);
+ }
+ }
+
+ return jsArgs;
+ }
+
+ public static Object fromJavaToRuby(IRuby rubyEngine, Object javaObj) {
+ Object rubyObj = JavaUtil.convertJavaToRuby(rubyEngine, javaObj, javaObj.getClass());
+ return rubyObj;
+ }
+
+}
diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/resources/META-INF/sca/default.scdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/resources/META-INF/sca/default.scdl new file mode 100644 index 0000000000..4b4289f9e4 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/resources/META-INF/sca/default.scdl @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<!-- + Ruby configuration for the launcher environment. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://incubator.apache.org/tuscany/xmlns/system/1.0-incubator-M2" + + name="org.apache.tuscany.launcher.RubyImplementation"> + + <dependency xmlns="http://incubator.apache.org/tuscany/xmlns/1.0-incubator-M2"> + <group>org.apache.tuscany.sca.services.containers</group> + <name>ruby</name> + <version>1.0-incubator-M2</version> + </dependency> + + <component name="ruby.implementationLoader"> + <system:implementation.system class="org.apache.tuscany.container.ruby.RubyImplementationLoader"/> + </component> + + <component name="ruby.componentTypeLoader"> + <system:implementation.system class="org.apache.tuscany.container.ruby.RubyComponentTypeLoader"/> + </component> + + <component name="ruby.componentBuilder"> + <system:implementation.system class="org.apache.tuscany.container.ruby.RubyComponentBuilder"/> + </component> + +</composite> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/resources/META-INF/sca/ruby.system.scdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/resources/META-INF/sca/ruby.system.scdl new file mode 100644 index 0000000000..686e1ea308 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/main/resources/META-INF/sca/ruby.system.scdl @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<!--
+ Ruby configuration for the launcher environment.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://incubator.apache.org/tuscany/xmlns/system/1.0-incubator-M2"
+
+ name="org.apache.tuscany.launcher.RubyImplementation">
+
+ <component name="ruby.implementationLoader">
+ <system:implementation.system class="org.apache.tuscany.container.ruby.RubyImplementationLoader"/>
+ </component>
+
+ <component name="ruby.componentTypeLoader">
+ <system:implementation.system class="org.apache.tuscany.container.ruby.RubyComponentTypeLoader"/>
+ </component>
+
+ <component name="ruby.componentBuilder">
+ <system:implementation.system class="org.apache.tuscany.container.ruby.RubyComponentBuilder"/>
+ </component>
+
+</composite>
diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/helloworld/HelloWorldService.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/helloworld/HelloWorldService.java new file mode 100644 index 0000000000..7e99f6f720 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/helloworld/HelloWorldService.java @@ -0,0 +1,24 @@ +/* + * 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 helloworld; + + +public interface HelloWorldService { + String sayHello(String s); +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/helloworld/HelloWorldServiceImpl.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/helloworld/HelloWorldServiceImpl.java new file mode 100644 index 0000000000..be804d3540 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/helloworld/HelloWorldServiceImpl.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 helloworld; + +import org.osoa.sca.annotations.Property; + + +public class HelloWorldServiceImpl implements HelloWorldService { + + @Property + public String greeting = "Default hello"; + + public String getGreeting() { + return greeting; + } + + + public void setGreeting(String greeting) { + this.greeting = greeting; + } + + public String sayHello(String s) { + //return greeting + s + " from the JavaWorld!"; + return greeting + " from Java Reference " + s ; //+ " from " + helloSayer.firstName + " " + helloSayer.lastName; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/RubyImplementationLoaderTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/RubyImplementationLoaderTestCase.java new file mode 100644 index 0000000000..289a187461 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/RubyImplementationLoaderTestCase.java @@ -0,0 +1,109 @@ +/* + * 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.container.ruby; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.MissingResourceException; + +import junit.framework.TestCase; +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; + +/** + * Tests for RubyImplementationLoader + */ +public class RubyImplementationLoaderTestCase extends TestCase { + private CompositeComponent parent; + + private XMLStreamReader reader; + + private DeploymentContext deploymentContext; + + private ClassLoader classLoader; + + private LoaderRegistry registry; + + private RubyImplementationLoader loader; + + public void testNoScriptAttribute() throws LoaderException, XMLStreamException { + expect(reader.getAttributeValue(null, "script")).andReturn(null); + expect(reader.getAttributeValue(null, "class")).andReturn(null); + replay(reader); + replay(deploymentContext); + + try { + loader.load(parent, reader, deploymentContext); + fail(); + } catch (MissingResourceException e) { + // ok + } + verify(reader); + verify(deploymentContext); + } + + public void testNoScriptPresent() throws LoaderException, XMLStreamException { + expect(reader.getAttributeValue(null, "script")).andReturn("foo.groovy"); + expect(reader.getAttributeValue(null, "class")).andReturn(null); + expect(deploymentContext.getClassLoader()).andReturn(classLoader); + + replay(reader); + replay(deploymentContext); + + RubyImplementationLoader mockLoader = new RubyImplementationLoader(registry) { + protected String loadSource(ClassLoader cl, String resource) throws LoaderException { + assertSame(classLoader, cl); + assertEquals("foo.groovy", resource); + throw new MissingResourceException(resource); + } + }; + try { + mockLoader.load(parent, reader, deploymentContext); + fail(); + } catch (MissingResourceException e) { + assertEquals("foo.groovy", e.getMessage()); + } + verify(reader); + verify(deploymentContext); + } + + public void testLoadScript() throws LoaderException { + String script = + loader.loadSource(getClass().getClassLoader(), "org/apache/tuscany/container/ruby/mock/test.rb"); + assertEquals("//Test Script", script); + } + + protected void setUp() throws Exception { + super.setUp(); + registry = createMock(LoaderRegistry.class); + loader = new RubyImplementationLoader(registry); + + parent = createMock(CompositeComponent.class); + reader = createMock(XMLStreamReader.class); + deploymentContext = createMock(DeploymentContext.class); + classLoader = createMock(ClassLoader.class); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/RubyScriptIntrospectorTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/RubyScriptIntrospectorTestCase.java new file mode 100644 index 0000000000..4f4869355d --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/RubyScriptIntrospectorTestCase.java @@ -0,0 +1,130 @@ +/* + * 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.container.ruby; + +import helloworld.HelloWorldService; + +import java.io.IOException; +import java.net.URL; +import java.util.Map; + +import javax.wsdl.WSDLException; +import javax.xml.namespace.QName; + +import junit.framework.TestCase; + +import org.apache.tuscany.container.ruby.rubyscript.RubySCAConfig; +import org.apache.tuscany.container.ruby.rubyscript.RubyScript; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.idl.wsdl.WSDLDefinitionRegistryImpl; +import org.apache.tuscany.idl.wsdl.WSDLServiceContract; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.loader.MissingResourceException; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +public class RubyScriptIntrospectorTestCase extends TestCase { + + private static final WSDLDefinitionRegistryImpl.Monitor NULL_MONITOR = new WSDLDefinitionRegistryImpl.Monitor() { + public void readingWSDL(String namespace, URL location) { + } + + public void cachingDefinition(String namespace, URL location) { + } + }; + + public void testJavaInterface() throws MissingResourceException, + InvalidServiceContractException { + RubyScript rs = new RubyScript("javaInterfaceTest", + "$SCA = { 'javaInterface' => 'helloworld.HelloWorldService'}", + null, + getClass().getClassLoader()); + RubySCAConfig scaConfig = new RubySCAConfig(rs.getRubyEngine().getGlobalVariables()); + RubyIntrospector introspector = new RubyIntrospector(null, + new JavaInterfaceProcessorRegistryImpl()); + ComponentType comonentType = introspector.introspectScript(scaConfig, + rs.getClassLoader()); + assertNotNull(comonentType); + Map services = comonentType.getServices(); + assertEquals(1, + services.size()); + ServiceDefinition serviceDefinition = (ServiceDefinition) services.values() + .iterator() + .next(); + ServiceContract serviceContract = serviceDefinition.getServiceContract(); + assertTrue(serviceContract instanceof JavaServiceContract); + JavaServiceContract javaServiceContract = (JavaServiceContract) serviceContract; + assertEquals(HelloWorldService.class, + javaServiceContract.getInterfaceClass()); + } + + public void testWSDLLocation() throws WSDLException { + // RhinoScript rs = new RhinoScript("wsdlLocation", + // "SCA = { wsdlLocation : 'src/test/resources/org/apache/tuscany/container/javascript/rhino/helloworld.wsdl',};", null, getClass() + // .getClassLoader()); + // RhinoSCAConfig scaConfig = new RhinoSCAConfig(rs.getScriptScope()); + // JavaScriptIntrospector introspector = new JavaScriptIntrospector(null); + // ComponentType comonentType = introspector.introspectScript(scaConfig, rs.getClassLoader()); + // assertNotNull(comonentType); + // Map services = comonentType.getServices(); + // assertEquals(1, services.size()); + // ServiceDefinition serviceDefinition = (ServiceDefinition) services.values().iterator().next(); + // ServiceContract serviceContract = serviceDefinition.getServiceContract(); + // assertTrue(serviceContract instanceof WSDLServiceContract); + // WSDLServiceContract wsdlServiceContract = (WSDLServiceContract) serviceContract; + // assertEquals(new QName("http://helloworld", "HelloWorld"), wsdlServiceContract.getPortType().getQName()); + } + + public void testWSDLPortType() throws WSDLException, + IOException, + MissingResourceException, + InvalidServiceContractException { + RubyScript rs = new RubyScript("wsdlPortType", + "$SCA = { 'wsdlPortType' => 'HelloWorld', 'wsdlNamespace' => 'http://helloworld'}", + null, + getClass().getClassLoader()); + RubySCAConfig scaConfig = new RubySCAConfig(rs.getRubyEngine().getGlobalVariables()); + + WSDLDefinitionRegistryImpl wsdlReg = new WSDLDefinitionRegistryImpl(); + wsdlReg.setMonitor(NULL_MONITOR); + URL wsdlURL = getClass().getClassLoader() + .getResource("org/apache/tuscany/container/ruby/jruby/helloworld.wsdl"); + wsdlReg.loadDefinition("http://helloworld", + wsdlURL); + + RubyIntrospector introspector = new RubyIntrospector(wsdlReg, + new JavaInterfaceProcessorRegistryImpl()); + ComponentType comonentType = introspector.introspectScript(scaConfig, + rs.getClassLoader()); + assertNotNull(comonentType); + Map services = comonentType.getServices(); + assertEquals(1, + services.size()); + ServiceDefinition serviceDefinition = (ServiceDefinition) services.values() + .iterator() + .next(); + ServiceContract serviceContract = serviceDefinition.getServiceContract(); + assertTrue(serviceContract instanceof WSDLServiceContract); + WSDLServiceContract wsdlServiceContract = (WSDLServiceContract) serviceContract; + assertEquals(new QName("http://helloworld", "HelloWorld"), + wsdlServiceContract.getPortType().getQName()); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/ScriptInvokeTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/ScriptInvokeTestCase.java new file mode 100644 index 0000000000..c83605eecb --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/ScriptInvokeTestCase.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.container.ruby; + +import junit.framework.TestCase; + +import org.apache.tuscany.container.ruby.rubyscript.RubyScript; + +/** + * Tests for invoker JavaScriptComponents + */ +public class ScriptInvokeTestCase extends TestCase { + + private static final String SCRIPT = "def greet(name) \n return name \n end \n"; + + private RubyScript rubyScript; + + /** + * Tests the invocation of a Groovy "script" as opposed to a class + */ + public void testBasicScriptInvocation() throws Exception { +// ModuleScopeContainer scope = new ModuleScopeContainer(null); +// scope.start(); +// List<Class<?>> services = new ArrayList<Class<?>>(); +// services.add(Greeting.class); +// RubyComponent<Greeting> context = new RubyComponent<Greeting>("source", rhinoScript, services, new HashMap<String, Object>(), +// null, scope, ArtifactFactory.createWireService(), null); +// scope.register(context); +// Greeting object = (Greeting) context.getServiceInstance(); +// assertEquals("foo", object.greet("foo")); +// scope.stop(); + } + + protected void setUp() throws Exception { + super.setUp(); + rubyScript = new RubyScript("test", SCRIPT); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/WireTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/WireTestCase.java new file mode 100644 index 0000000000..3794eb82f7 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/WireTestCase.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.container.ruby; + +import static org.easymock.EasyMock.reportMatcher; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.apache.tuscany.container.ruby.mock.Greeting; +import org.apache.tuscany.container.ruby.rubyscript.RubyScript; +import org.apache.tuscany.core.component.scope.ModuleScopeContainer; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InboundInvocationChain; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.test.ArtifactFactory; +import org.easymock.IArgumentMatcher; + +/** + * Tests for JavaScript component wiring + */ +public class WireTestCase extends TestCase { + + private static final String SCRIPT = " def setWire(ref)\n" + " wire = ref\n" + + "end \n" + " def greet(name)\n" + " return wire.greet(name) \n" + + " end\n"; + + private static final String SCRIPT2 = " def greet(name)\n" + " return name \n" + + "end \n"; + + private RubyScript implClass1; + + private RubyScript implClass2; + + /** + * Tests a basic invocation down a source wire + */ + public void testReferenceWireInvocation() throws Exception { + // ModuleScopeContainer scope = new ModuleScopeContainer(null); + // scope.start(); + // + // List<Class<?>> services = new ArrayList<Class<?>>(); + // services.add(Greeting.class); + // JavaScriptComponent<Greeting> context = new JavaScriptComponent<Greeting>("source", implClass1, services, properties, null, scope, + // ArtifactFactory.createWireService(), null); + // OutboundWire<?> wire = ArtifactFactory.createOutboundWire("wire", Greeting.class); + // ArtifactFactory.terminateWire(wire); + // + // TargetInvoker invoker = createMock(TargetInvoker.class); + // expect(invoker.isCacheable()).andReturn(false); + // Message response = new MessageImpl(); + // response.setBody("foo"); + // expect(invoker.invoke(eqMessage())).andReturn(response); + // replay(invoker); + // + // for (OutboundInvocationChain chain : wire.getInvocationChains().values()) { + // chain.setTargetInvoker(invoker); + // } + // scope.register(context); + // context.addOutboundWire(wire); + // Greeting greeting = context.getServiceInstance(); + // assertEquals("foo", greeting.greet("foo")); + // verify(invoker); + // + // scope.stop(); + } + + // todo this could be generalized and moved to test module + public static Message eqMessage() { + reportMatcher(new IArgumentMatcher() { + public boolean matches(Object object) { + if (!(object instanceof Message)) { + return false; + } + final Message msg = (Message) object; + Object[] body = (Object[]) msg.getBody(); + return "foo".equals(body[0]); + } + + public void appendTo(StringBuffer stringBuffer) { + } + }); + return null; + } + + /** + * Tests a basic invocation to a target + */ + public void testTargetInvocation() throws Exception { + ModuleScopeContainer scope = new ModuleScopeContainer(null); + scope.start(); + List<Class<?>> services = new ArrayList<Class<?>>(); + services.add(Greeting.class); + Map<String, Object> properties = new Hashtable<String,Object>(); + properties.put("greeting","HeyThere"); + + RubyComponent context = new RubyComponent("source", + implClass2, + null, + services, + properties, + null, + scope, + ArtifactFactory.createWireService(), + null); + scope.register(context); + DataType<String> returnDataType = new DataType<String>(String.class, String.class.getName()); +// Operation<String> operation = new Operation<String>("greet", +// returnDataType, +// null, +// null, +// false, +// null); +// +// TargetInvoker invoker = context.createTargetInvoker(null, +// operation); +// assertEquals("foo", +// invoker.invokeTarget(new String[]{"foo"})); + scope.stop(); + } + + /** + * Tests a basic invocation down a target wire + */ + public void testTargetWireInvocation() throws Exception { + ModuleScopeContainer scope = new ModuleScopeContainer(null); + scope.start(); + List<Class<?>> services = new ArrayList<Class<?>>(); + services.add(Greeting.class); + Map<String, Object> properties = new Hashtable<String,Object>(); + properties.put("greeting","HeyThere"); + RubyComponent context = new RubyComponent("source", + implClass2, + null, + services, + properties, + null, + scope, + ArtifactFactory.createWireService(), + null); + scope.register(context); + + InboundWire wire = ArtifactFactory.createInboundWire("Greeting", + Greeting.class); + ArtifactFactory.terminateWire(wire); + for (InboundInvocationChain chain : wire.getInvocationChains().values()) { + chain.setTargetInvoker(context.createTargetInvoker(null, + chain.getOperation())); + } + context.addInboundWire(wire); + Greeting greeting = (Greeting) context.getServiceInstance("Greeting"); + assertEquals("foo", + greeting.greet("foo")); + scope.stop(); + } + + protected void setUp() throws Exception { + super.setUp(); + implClass1 = new RubyScript("script1", SCRIPT); + implClass2 = new RubyScript("script2", SCRIPT2); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/function/HelloWorldTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/function/HelloWorldTestCase.java new file mode 100644 index 0000000000..c2af5b9b10 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/function/HelloWorldTestCase.java @@ -0,0 +1,75 @@ +/* + * 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.container.ruby.function; + +import java.net.URL; + +import helloworld.HelloWorldService; + +import org.apache.tuscany.test.SCATestCase; +import org.osoa.sca.CompositeContext; +import org.osoa.sca.CurrentCompositeContext; + +/** + * This shows how to test the HelloWorld service component. + */ +public class HelloWorldTestCase extends SCATestCase { + + private HelloWorldService helloWorldService; + private CompositeContext context = null; + + + protected void setUp() throws Exception { + URL base = getClass().getResource("/META-INF/sca/ruby.system.scdl"); + addExtension("RubyContainer", new URL(base, "default.scdl")); + setApplicationSCDL(getClass().getResource("helloworld.scdl")); + super.setUp(); + + context = CurrentCompositeContext.getContext(); + helloWorldService = context.locateService(HelloWorldService.class, "HelloWorldRubyComponent"); + + //helloWorldService = context.locateService(HelloWorldService.class, "HelloWorldJavaReference"); + } + + public void testHelloWorldWithClass() throws Exception { + assertEquals(helloWorldService.sayHello("petra"), "Hey Howdy from Java Reference petra"); + //System.out.println(helloWorldService.sayHello("petra")); + } + + public void testHelloWorldGlobal() throws Exception { + assertEquals(helloWorldService.sayHello("artep"), "Hey Howdy from Java Reference artep"); + //System.out.println(helloWorldService.sayHello("artep")); + } + + public void testHelloWorldProperty() throws Exception { + HelloWorldService helloWorldService = context.locateService(HelloWorldService.class, "HelloWorldProperty"); + assertEquals(helloWorldService.sayHello("petra"), "Namaskaar petra"); + //System.out.println(helloWorldService.sayHello("petra")); + } + + public void testHelloWorldPropertyDefault() throws Exception { + HelloWorldService helloWorldService = context.locateService(HelloWorldService.class, "HelloWorldPropertyDefault"); + assertEquals(helloWorldService.sayHello("petra"), "Bow Wow petra"); + //System.out.println(helloWorldService.sayHello("petra")); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/mock/Greeting.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/mock/Greeting.java new file mode 100644 index 0000000000..acf71f152b --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/java/org/apache/tuscany/container/ruby/mock/Greeting.java @@ -0,0 +1,26 @@ +/* + * 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.container.ruby.mock; + +public interface Greeting { + + String setWire(Greeting ref); + + String greet(String name); +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/HelloWorld.componentType b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/HelloWorld.componentType new file mode 100644 index 0000000000..d52b63226c --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/HelloWorld.componentType @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="ASCII"?>
+<!--
+ * 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.
+-->
+<componentType xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <service name="HelloWorldService">
+ <interface.java interface="helloworld.HelloWorldService"/>
+ </service>
+ <reference name="extHelloWorld">
+ <interface.java interface="helloworld.HelloWorldService"/>
+ </reference>
+ <property name="greeting" type="xsd:string">Hullow</property>
+</componentType>
diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/HelloWorld.rb b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/HelloWorld.rb new file mode 100644 index 0000000000..3f1a053b15 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/HelloWorld.rb @@ -0,0 +1,33 @@ + # 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.
+
+class Helloworld
+
+ def sayHello(s)
+ return "Hello to " + s + " from the Ruby World!"
+ end
+
+end
+
+class HelloWorldServiceRubyImpl
+ attr_writer :extHelloWorld
+ attr_writer :greeting
+
+ def sayHello(s)
+ return @greeting + " " + @extHelloWorld.sayHello(s);
+ end
+end
diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/IntrospectableHelloWorld.rb b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/IntrospectableHelloWorld.rb new file mode 100644 index 0000000000..d4edb7a100 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/IntrospectableHelloWorld.rb @@ -0,0 +1,30 @@ + # 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.
+
+$SCA = {
+ 'javaInterface' => 'helloworld.HelloWorldService'
+}
+
+def sayHello(s)
+ return "Hello to " + s + " from the Ruby World!"
+end
+
+class HelloWorldServiceRubyImpl
+ def sayHello(s)
+ return "Hello to " + s + " from the Ruby World!"
+ end
+end
diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/helloworld.scdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/helloworld.scdl new file mode 100644 index 0000000000..222beac543 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/helloworld.scdl @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:rb="http://incubator.apache.org/tuscany/xmlns/container/rb/1.0-incubator-M2" + + name="HelloWorldComposite"> + + <component name="HelloWorldRubyComponent"> + <rb:implementation.rb script="org/apache/tuscany/container/ruby/function/HelloWorld.rb" class="HelloWorldServiceRubyImpl"/> + <reference name="extHelloWorld" target="HelloWorldJavaReference">HelloWorldJavaReference</reference> + <property name="greeting">Hey</property> + </component> + + <component name="HelloWorldJavaReference"> + <implementation.java class="helloworld.HelloWorldServiceImpl"/> + <property name="greeting">Howdy</property> + </component> + + <component name="HelloWorldProperty"> + <rb:implementation.rb script="org/apache/tuscany/container/ruby/function/propertyTest.rb" class="HelloWorldPropertyTest"/> + <property name="GREETING">Namaskaar</property> + </component> + + <component name="HelloWorldPropertyDefault"> + <rb:implementation.rb script="org/apache/tuscany/container/ruby/function/propertyTest.rb" class="HelloWorldPropertyTest"/> + </component> +</composite> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/propertyTest.componentType b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/propertyTest.componentType new file mode 100644 index 0000000000..6b37990b8b --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/propertyTest.componentType @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="ASCII"?>
+<!--
+ * 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.
+-->
+
+<componentType xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <service name="HelloWorldService">
+ <interface.java interface="helloworld.HelloWorldService"/>
+ </service>
+ <property name="GREETING" type="xsd:string">Bow Wow</property>
+</componentType>
diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/propertyTest.rb b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/propertyTest.rb new file mode 100644 index 0000000000..7aa0f3e8ea --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/function/propertyTest.rb @@ -0,0 +1,24 @@ + # 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.
+
+class HelloWorldPropertyTest
+ attr_writer :GREETING
+
+ def sayHello(s)
+ return @GREETING + " " + s;
+ end
+end
\ No newline at end of file diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/jruby/helloworld.wsdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/jruby/helloworld.wsdl new file mode 100644 index 0000000000..67067f044a --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/jruby/helloworld.wsdl @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. + --> +<wsdl:definitions targetNamespace="http://helloworld" xmlns:tns="http://helloworld" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" + name="helloworld"> + + <wsdl:types> + <schema elementFormDefault="qualified" targetNamespace="http://helloworld" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema"> + + <element name="getGreetings"> + <complexType> + <sequence> + <element name="name" type="xsd:string"/> + </sequence> + </complexType> + </element> + + <element name="getGreetingsResponse"> + <complexType> + <sequence> + <element name="getGreetingsReturn" type="xsd:string"/> + </sequence> + </complexType> + </element> + </schema> + </wsdl:types> + + <wsdl:message name="getGreetingsRequest"> + <wsdl:part element="tns:getGreetings" name="parameters"/> + </wsdl:message> + + <wsdl:message name="getGreetingsResponse"> + <wsdl:part element="tns:getGreetingsResponse" name="parameters"/> + </wsdl:message> + + <wsdl:portType name="HelloWorld"> + <wsdl:operation name="getGreetings"> + <wsdl:input message="tns:getGreetingsRequest" name="getGreetingsRequest"/> + <wsdl:output message="tns:getGreetingsResponse" name="getGreetingsResponse"/> + </wsdl:operation> + </wsdl:portType> + + <wsdl:binding name="HelloWorldSoapBinding" type="tns:HelloWorld"> + <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> + <wsdl:operation name="getGreetings"> + <wsdlsoap:operation soapAction=""/> + <wsdl:input name="getGreetingsRequest"> + <wsdlsoap:body use="literal"/> + </wsdl:input> + <wsdl:output name="getGreetingsResponse"> + <wsdlsoap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + </wsdl:binding> + + <wsdl:service name="HelloWorldService"> + <wsdl:port binding="tns:HelloWorldSoapBinding" name="HelloWorldSoapPort"> + <wsdlsoap:address location="http://localhost:8080/sample-helloworldws/services/HelloWorldWebService"/> + </wsdl:port> + </wsdl:service> + +</wsdl:definitions> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/mock/test.rb b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/mock/test.rb new file mode 100644 index 0000000000..ef2694b475 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.ruby/src/test/resources/org/apache/tuscany/container/ruby/mock/test.rb @@ -0,0 +1 @@ +//Test Script
\ No newline at end of file diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/.ruleset b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/.ruleset new file mode 100644 index 0000000000..3886f07f2d --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/.ruleset @@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<ruleset name="pmd-eclipse"> + <description>PMD Plugin preferences rule set</description> + + + <rule ref="rulesets/basic.xml/BooleanInstantiation"/> + <rule ref="rulesets/basic.xml/CollapsibleIfStatements"/> + <rule ref="rulesets/basic.xml/DoubleCheckedLocking"/> +<!--<rule ref="rulesets/basic.xml/EmptyCatchBlock"/>--> +<!--<rule ref="rulesets/basic.xml/EmptyFinallyBlock"/>--> +<!--<rule ref="rulesets/basic.xml/EmptyIfStmt"/>--> + <rule ref="rulesets/basic.xml/EmptyStatementNotInLoop"/> +<!--<rule ref="rulesets/basic.xml/EmptyStaticInitializer"/>--> +<!--<rule ref="rulesets/basic.xml/EmptySwitchStatements"/>--> +<!--<rule ref="rulesets/basic.xml/EmptySynchronizedBlock"/>--> +<!--<rule ref="rulesets/basic.xml/EmptyTryBlock"/>--> +<!--<rule ref="rulesets/basic.xml/EmptyWhileStmt"/>--> + <rule ref="rulesets/basic.xml/ForLoopShouldBeWhileLoop"/> + <rule ref="rulesets/basic.xml/JumbledIncrementer"/> +<!--<rule ref="rulesets/basic.xml/OverrideBothEqualsAndHashcode"/>--> + <rule ref="rulesets/basic.xml/ReturnFromFinallyBlock"/> + <rule ref="rulesets/basic.xml/UnconditionalIfStatement"/> + <rule ref="rulesets/basic.xml/UnnecessaryConversionTemporary"/> + <rule ref="rulesets/basic.xml/UnnecessaryFinalModifier"/> + <rule ref="rulesets/basic.xml/UnnecessaryReturn"/> +<!--<rule ref="rulesets/basic.xml/UselessOverridingMethod"/>--> + +<!--<rule ref="rulesets/braces.xml/ForLoopsMustUseBraces"/>--> +<!--<rule ref="rulesets/braces.xml/IfElseStmtsMustUseBraces"/>--> +<!--<rule ref="rulesets/braces.xml/IfStmtsMustUseBraces"/>--> +<!--<rule ref="rulesets/braces.xml/WhileLoopsMustUseBraces"/>--> + +<!--<rule ref="rulesets/clone.xml/CloneMethodMustImplementCloneable"/>--> +<!--<rule ref="rulesets/clone.xml/CloneThrowsCloneNotSupportedException"/>--> +<!--<rule ref="rulesets/clone.xml/ProperCloneImplementation"/>--> + +<!--<rule ref="rulesets/codesize.xml/CyclomaticComplexity"/>--> +<!--<rule ref="rulesets/codesize.xml/ExcessiveClassLength"/>--> +<!--<rule ref="rulesets/codesize.xml/ExcessiveMethodLength"/>--> +<!--<rule ref="rulesets/codesize.xml/ExcessiveParameterList"/>--> +<!--<rule ref="rulesets/codesize.xml/ExcessivePublicCount"/>--> +<!--<rule ref="rulesets/codesize.xml/TooManyFields"/>--> + +<rule ref="rulesets/controversial.xml/AssignmentInOperand"/> +<!--<rule ref="rulesets/controversial.xml/AtLeastOneConstructor"/>--> +<!--<rule ref="rulesets/controversial.xml/CallSuperInConstructor"/>--> +<!--<rule ref="rulesets/controversial.xml/DontImportSun"/>--> +<!--<rule ref="rulesets/controversial.xml/NullAssignment"/>--> +<!--<rule ref="rulesets/controversial.xml/OnlyOneReturn"/>--> +<!--<rule ref="rulesets/controversial.xml/SingularField"/>--> +<!--<rule ref="rulesets/controversial.xml/SuspiciousOctalEscape"/>--> +<!--<rule ref="rulesets/controversial.xml/UnnecessaryConstructor"/>--> +<rule ref="rulesets/controversial.xml/UnnecessaryParentheses"/> +<!--<rule ref="rulesets/controversial.xml/UnusedModifier"/>--> + +<!--<rule ref="rulesets/coupling.xml/CouplingBetweenObjects"/>--> +<!--<rule ref="rulesets/coupling.xml/ExcessiveImports"/>--> +<!--<rule ref="rulesets/coupling.xml/LooseCoupling"/>--> + +<!--<rule ref="rulesets/design.xml/AbstractClassWithoutAbstractMethod"/>--> +<!--<rule ref="rulesets/design.xml/AccessorClassGeneration"/>--> +<!--<rule ref="rulesets/design.xml/AssignmentToNonFinalStatic"/>--> +<!--<rule ref="rulesets/design.xml/AvoidDeeplyNestedIfStmts"/>--> +<!--<rule ref="rulesets/design.xml/AvoidInstanceofChecksInCatchClause"/>--> +<rule ref="rulesets/design.xml/AvoidProtectedFieldInFinalClass"/> +<!--<rule ref="rulesets/design.xml/AvoidReassigningParameters"/>--> +<!--<rule ref="rulesets/design.xml/AvoidSynchronizedAtMethodLevel"/>--> +<!--<rule ref="rulesets/design.xml/BadComparison"/>--> +<!--<rule ref="rulesets/design.xml/CloseConnection"/>--> +<!--<rule ref="rulesets/design.xml/CompareObjectsWithEquals"/>--> +<!--<rule ref="rulesets/design.xml/ConfusingTernary"/>--> +<rule ref="rulesets/design.xml/ConstructorCallsOverridableMethod"/> +<!--<rule ref="rulesets/design.xml/DefaultLabelNotLastInSwitchStmt"/>--> +<!--<rule ref="rulesets/design.xml/FinalFieldCouldBeStatic"/>--> +<rule ref="rulesets/design.xml/IdempotentOperations"/> +<!--<rule ref="rulesets/design.xml/ImmutableField"/>--> +<!--<rule ref="rulesets/design.xml/InstantiationToGetClass"/>--> +<!--<rule ref="rulesets/design.xml/MissingBreakInSwitch"/>--> +<!--<rule ref="rulesets/design.xml/MissingStaticMethodInNonInstantiatableClass"/>--> +<!--<rule ref="rulesets/design.xml/NonCaseLabelInSwitchStatement"/>--> +<!--<rule ref="rulesets/design.xml/NonStaticInitializer"/>--> +<rule ref="rulesets/design.xml/OptimizableToArrayCall"/> +<rule ref="rulesets/design.xml/PositionLiteralsFirstInComparisons"/> +<rule ref="rulesets/design.xml/SimplifyBooleanExpressions"/> +<rule ref="rulesets/design.xml/SimplifyBooleanReturns"/> +<rule ref="rulesets/design.xml/SimplifyConditional"/> +<!--<rule ref="rulesets/design.xml/SwitchDensity"/>--> +<!--<rule ref="rulesets/design.xml/SwitchStmtsShouldHaveDefault"/>--> +<rule ref="rulesets/design.xml/UnnecessaryLocalBeforeReturn"/> +<!--<rule ref="rulesets/design.xml/UseLocaleWithCaseConversions"/>--> +<!--<rule ref="rulesets/design.xml/UseNotifyAllInsteadOfNotify"/>--> +<!--<rule ref="rulesets/design.xml/UseSingleton"/>--> + +<!--<rule ref="rulesets/finalizers.xml/EmptyFinalizer"/>--> +<!--<rule ref="rulesets/finalizers.xml/FinalizeOnlyCallsSuperFinalize"/>--> +<!--<rule ref="rulesets/finalizers.xml/FinalizeOverloaded"/>--> +<!--<rule ref="rulesets/finalizers.xml/FinalizeDoesNotCallSuperFinalize"/>--> +<!--<rule ref="rulesets/finalizers.xml/FinalizeShouldBeProtected"/>--> +<!--<rule ref="rulesets/finalizers.xml/AvoidCallingFinalize"/>--> + +<!--<rule ref="rulesets/imports.xml/DuplicateImports"/>--> +<!--<rule ref="rulesets/imports.xml/DontImportJavaLang"/>--> +<!--<rule ref="rulesets/imports.xml/UnusedImports"/>--> +<!--<rule ref="rulesets/imports.xml/ImportFromSamePackage"/>--> + +<!--<rule ref="rulesets/javabeans.xml/BeanMembersShouldSerialize"/>--> +<!--<rule ref="rulesets/javabeans.xml/MissingSerialVersionUID"/>--> + +<!--<rule ref="rulesets/junit.xml/JUnitStaticSuite"/>--> +<!--<rule ref="rulesets/junit.xml/JUnitSpelling"/>--> +<!--<rule ref="rulesets/junit.xml/JUnitAssertionsShouldIncludeMessage"/>--> +<!--<rule ref="rulesets/junit.xml/JUnitTestsShouldIncludeAssert"/>--> +<!--<rule ref="rulesets/junit.xml/TestClassWithoutTestCases"/>--> +<!--<rule ref="rulesets/junit.xml/UnnecessaryBooleanAssertion"/>--> +<!--<rule ref="rulesets/junit.xml/UseAssertEqualsInsteadOfAssertTrue"/>--> +<!--<rule ref="rulesets/junit.xml/UseAssertSameInsteadOfAssertTrue"/>--> + + <!--<rule ref="rulesets/logging-java.xml/AvoidPrintStackTrace"/>--> + <!--<rule ref="rulesets/logging-java.xml/LoggerIsNotStaticFinal"/>--> + <!--<rule ref="rulesets/logging-java.xml/MoreThanOneLogger"/>--> + <!--<rule ref="rulesets/logging-java.xml/LoggerIsNotStaticFinal"/>--> + <!--<rule ref="rulesets/logging-java.xml/LogBlockWithoutIf"/>--> + <!--<rule ref="rulesets/logging-java.xml/SystemPrintln"/>--> + <!--<rule ref="rulesets/logging-jakarta-commons.xml/UseCorrectExceptionLogging"/>--> + <!--<rule ref="rulesets/logging-jakarta-commons.xml/ProperLogger"/>--> + + <!--<rule ref="rulesets/naming.xml/ShortVariable"/>--> + <!--<rule ref="rulesets/naming.xml/LongVariable"/>--> + <!--<rule ref="rulesets/naming.xml/ShortMethodName"/>--> + <!--<rule ref="rulesets/naming.xml/VariableNamingConventions"/>--> + <!--<rule ref="rulesets/naming.xml/MethodNamingConventions"/>--> + <!--<rule ref="rulesets/naming.xml/ClassNamingConventions"/>--> + <!--<rule ref="rulesets/naming.xml/AbstractNaming"/>--> + <!--<rule ref="rulesets/naming.xml/AvoidDollarSigns"/>--> + <!--<rule ref="rulesets/naming.xml/MethodWithSameNameAsEnclosingClass"/>--> + <!--<rule ref="rulesets/naming.xml/SuspiciousHashcodeMethodName"/>--> + <!--<rule ref="rulesets/naming.xml/SuspiciousConstantFieldName"/>--> + <!--<rule ref="rulesets/naming.xml/AvoidFieldNameMatchingTypeName"/>--> + <!--<rule ref="rulesets/naming.xml/AvoidFieldNameMatchingMethodName"/>--> + <!--<rule ref="rulesets/naming.xml/AvoidNonConstructorMethodsWithClassName"/>--> + <!--<rule ref="rulesets/naming.xml/NoPackage"/>--> + <!--<rule ref="rulesets/naming.xml/PackageCase"/>--> + + <!--<rule ref="rulesets/optimizations.xml/LocalVariableCouldBeFinal"/>--> + <!--<rule ref="rulesets/optimizations.xml/MethodArgumentCouldBeFinal"/>--> + <!--<rule ref="rulesets/optimizations.xml/AvoidInstantiatingObjectsInLoops"/>--> + <!--<rule ref="rulesets/optimizations.xml/UseArrayListInsteadOfVector"/>--> + <!--<rule ref="rulesets/optimizations.xml/SimplifyStartsWith"/>--> + <!--<rule ref="rulesets/optimizations.xml/UseStringBufferForStringAppends"/>--> + + <!--<rule ref="rulesets/strictexception.xml/AvoidCatchingThrowable"/>--> + <!--<rule ref="rulesets/strictexception.xml/SignatureDeclareThrowsException"/>--> + <!--<rule ref="rulesets/strictexception.xml/ExceptionAsFlowControl"/>--> + <!--<rule ref="rulesets/strictexception.xml/AvoidCatchingNPE"/>--> + <!--<rule ref="rulesets/strictexception.xml/AvoidThrowingRawExceptionTypes"/>--> + <!--<rule ref="rulesets/strictexception.xml/AvoidThrowingNullPointerException"/>--> + + <!--<rule ref="rulesets/strings.xml/AvoidDuplicateLiterals"/>--> + <!--<rule ref="rulesets/strings.xml/StringInstantiation"/>--> + <!--<rule ref="rulesets/strings.xml/StringToString"/>--> + <!--<rule ref="rulesets/strings.xml/AvoidConcatenatingNonLiteralsInStringBuffer"/>--> + <!--<rule ref="rulesets/strings.xml/UnnecessaryCaseChange"/>--> + + <!--<rule ref="rulesets/sunsecure.xml/MethodReturnsInternalArray"/>--> + <!--<rule ref="rulesets/sunsecure.xml/ArrayIsStoredDirectly"/>--> + + <rule ref="rulesets/unusedcode.xml/UnusedLocalVariable"/> + <rule ref="rulesets/unusedcode.xml/UnusedPrivateField"/> + <rule ref="rulesets/unusedcode.xml/UnusedPrivateMethod"/> + <!--<rule ref="rulesets/unusedcode.xml/UnusedFormalParameter"/>--> + +</ruleset> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/LICENSE.txt b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/LICENSE.txt new file mode 100755 index 0000000000..0084319535 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/LICENSE.txt @@ -0,0 +1,202 @@ + + 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, serviceDefinition 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/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/NOTICE.txt b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/NOTICE.txt new file mode 100644 index 0000000000..d83ebbe236 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/NOTICE.txt @@ -0,0 +1,14 @@ +${pom.name} +Copyright (c) 2005 - 2006 The Apache Software Foundation + +Apache Tuscany is an effort undergoing incubation at The Apache Software +Foundation (ASF), sponsored by the Apache Web Services PMC. Incubation is +required of all newly accepted projects until a further review indicates that +the infrastructure, communications, and decision making process have stabilized +in a manner consistent with other successful ASF projects. While incubation +status is not necessarily a reflection of the completeness or stability of the +code, it does indicate that the project has yet to be fully endorsed by the ASF. + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/README.txt b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/README.txt new file mode 100755 index 0000000000..9b26d1690a --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/README.txt @@ -0,0 +1,35 @@ +Apache Tuscany M1 build (May, 2006) +=================================== + +http://incubator.apache.org/tuscany/ + +Tuscany is an effort undergoing incubation at the Apache Software Foundation +(ASF), sponsored by the Web Services PMC. + +Incubation is required of all newly accepted projects until a further review +indicates that the infrastructure, communications, and decision making process +have stabilized in a manner consistent with other successful ASF projects. + +While incubation status is not necessarily a reflection of the completeness or +stability of the code, it does indicate that the project has yet to be fully +endorsed by the ASF. + + +Support +------- + +Any problem with this release can be reported to the Tuscany mailing list +or in the JIRA issue tracker. + +Mailing list subscription: + tuscany-dev-subscribe@ws.apache.org + +Jira: + http://issues.apache.org/jira/browse/Tuscany + + +Thank you for using Tuscany! + + +The Tuscany Team. + diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/pom.xml b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/pom.xml new file mode 100755 index 0000000000..b628bd03d5 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/pom.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<project> + + <parent> + <groupId>org.apache.tuscany.sca.services.containers</groupId> + <artifactId>parent</artifactId> + <version>1.0-incubator-M2</version> + </parent> + + <modelVersion>4.0.0</modelVersion> + <artifactId>spring</artifactId> + <name>Apache Tuscany Spring Framework Container</name> + <description>Container for managing Spring composites</description> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca.kernel</groupId> + <artifactId>tuscany-spi</artifactId> + <version>${sca.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca.runtime</groupId> + <artifactId>webapp</artifactId> + <version>${sca.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring</artifactId> + <version>2.0</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.0.4</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>test</artifactId> + <version>${sca.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymockclassextension</artifactId> + </dependency> + + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + </dependency> + + </dependencies> + +</project> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/config/SCANamespaceHandlerResolver.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/config/SCANamespaceHandlerResolver.java new file mode 100644 index 0000000000..047d2b4ad1 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/config/SCANamespaceHandlerResolver.java @@ -0,0 +1,59 @@ +/* + * 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.container.spring.config; + +import org.apache.tuscany.spi.model.CompositeComponentType; + +import org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver; +import org.springframework.beans.factory.xml.NamespaceHandler; +import org.springframework.sca.config.ScaNamespaceHandler; + +/** + * Overrides the default Spring namespace resolver to automatically register {@link SCANamespaceHandler} instead of + * requiring a value to be supplied in a Spring configuration + * <p/> + * TODO: Figure out how to activate this impl + * + * @version $$Rev$$ $$Date$$ + */ +public class SCANamespaceHandlerResolver extends DefaultNamespaceHandlerResolver { + + private static final String SCA_NAMESPACE = "http://www.springframework.org/schema/sca"; + + private ScaNamespaceHandler handler; + + public SCANamespaceHandlerResolver(ClassLoader classLoader, CompositeComponentType componentType) { + super(classLoader); + handler = new ScaNamespaceHandler(/*componentType*/); + } + + public SCANamespaceHandlerResolver(String handlerMappingsLocation, + ClassLoader classLoader, + CompositeComponentType componentType) { + super(classLoader, handlerMappingsLocation); + handler = new ScaNamespaceHandler(/*componentType*/); + } + + public NamespaceHandler resolve(String namespaceUri) { + if (SCA_NAMESPACE.equals(namespaceUri)) { + return handler; + } + return super.resolve(namespaceUri); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/config/ScaApplicationContext.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/config/ScaApplicationContext.java new file mode 100644 index 0000000000..cdf33b0ea1 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/config/ScaApplicationContext.java @@ -0,0 +1,68 @@ +/* + * 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.container.spring.config; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.AbstractXmlApplicationContext; +import org.springframework.core.io.Resource; +import org.springframework.sca.ScaAdapterAware; +import org.springframework.sca.ScaAdapterPostProcessor; + +import org.apache.tuscany.container.spring.impl.SpringScaAdapter; +import org.apache.tuscany.container.spring.model.SpringComponentType; + +/** + * @author Andy Piper + * @since 2.1 + */ +public class ScaApplicationContext extends AbstractXmlApplicationContext { + public static final String APP_CONTEXT_PROP = "org.springframework.sca.application.context"; + private Resource appXml; + private SpringComponentType componentType; + + public ScaApplicationContext(Resource appXml, SpringComponentType componentType) { + this(null, appXml, componentType); + } + + public ScaApplicationContext(ApplicationContext parent, Resource appXml, SpringComponentType componentType) { + super(parent); + this.appXml = appXml; + this.componentType = componentType; + refresh(); + } + + protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) { + // beanDefinitionReader.setEntityResolver(null); + beanDefinitionReader + .setNamespaceHandlerResolver(new SCANamespaceHandlerResolver(getClassLoader(), componentType)); + } + + protected Resource[] getConfigResources() { + return new Resource[]{appXml}; + } + + protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + super.postProcessBeanFactory(beanFactory); + beanFactory.addBeanPostProcessor(new ScaAdapterPostProcessor(new SpringScaAdapter(componentType))); + beanFactory.ignoreDependencyInterface(ScaAdapterAware.class); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringComponentTypeLoader.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringComponentTypeLoader.java new file mode 100644 index 0000000000..fa815eee78 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringComponentTypeLoader.java @@ -0,0 +1,109 @@ +/* + * 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.container.spring.impl; + +import org.springframework.context.support.AbstractRefreshableApplicationContext; +import org.springframework.core.io.Resource; +import org.springframework.sca.ScaServiceExporter; + +import org.apache.tuscany.container.spring.config.ScaApplicationContext; +import org.apache.tuscany.container.spring.model.SpringComponentType; +import org.apache.tuscany.container.spring.model.SpringImplementation; +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.host.RuntimeInfo; + +/** + * Loads a component type for a Spring <code>ApplicationContext</code>. The implementation creates a new instance of a + * Spring application context which is configured with SCA namespace handlers for generating component type information + * + * @version $$Rev$$ $$Date$$ + */ + +public class SpringComponentTypeLoader extends ComponentTypeLoaderExtension<SpringImplementation> { + public static final String SERVICE_BEAN_SUFFIX = ".SCAService"; + + private org.apache.tuscany.host.RuntimeInfo runtimeInfo; + + public SpringComponentTypeLoader(@Autowire LoaderRegistry loaderRegistry, @Autowire RuntimeInfo runtimeInfo) { + super(loaderRegistry); + this.runtimeInfo = runtimeInfo; + } + + @Override + protected Class<SpringImplementation> getImplementationClass() { + return SpringImplementation.class; + } + + /** + * Responsible for loading the Spring composite component type. The the application context is instantiated here as + * it is needed to derive component type information. Since the component type is loaded per SCDL entry (i.e. + * composite use) one application context instance will be created per Spring composite instance. + */ + @SuppressWarnings("unchecked") + public void load(CompositeComponent parent, + SpringImplementation implementation, + DeploymentContext deploymentContext) throws LoaderException { + if (implementation.getComponentType() != null) { + // FIXME hack since the builder registry loads the implementation type and the Spring implementation loader + // needs to as well. The second call is done by the builder registry and we just ignore it. + return; + } + Resource resource = implementation.getApplicationResource(); + SpringComponentType componentType = new SpringComponentType(); + // REVIEW andyp -- pass in deploymentContext.getClassLoader()? + AbstractRefreshableApplicationContext ctx; + if (runtimeInfo instanceof SpringRuntimeInfo) { + ctx = ((SpringRuntimeInfo) runtimeInfo).getApplicationContext(); + } else { + ctx = new ScaApplicationContext(resource, componentType); + } + componentType.setApplicationContext(ctx); // FIXME andyp@bea.com -- don't do this! + + // If there are <sca:service> elements, they define (and limit) the services exposed + // in the componentType. + String [] serviceBeanNames = ctx.getBeanNamesForType(ScaServiceExporter.class); + for (String serviceBeanName : serviceBeanNames) { + int nSuffix = serviceBeanName.indexOf(SERVICE_BEAN_SUFFIX); + if (nSuffix == -1) { + continue; + } + + String serviceName = serviceBeanName.substring(0, nSuffix); + ScaServiceExporter serviceBean = (ScaServiceExporter) ctx.getBean(serviceName); + // REVIEW andyp -- use the class directly? + String serviceTypeName = serviceBean.getServiceType().getName(); + try { + Class serviceInterface = Class.forName(serviceTypeName, true, deploymentContext.getClassLoader()); + componentType.addServiceType(serviceName, serviceInterface); + //ServiceDefinition service = createService(serviceInterface); + //componentType.getServices().put(serviceName, service); + } catch (ClassNotFoundException e) { + throw new LoaderException(e); + } + } + // if no service tags are specified, expose all beans + componentType.setExposeAllBeans(componentType.getServiceTypes().isEmpty()); + implementation.setComponentType(componentType); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringCompositeBuilder.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringCompositeBuilder.java new file mode 100644 index 0000000000..6ec5d8fdd7 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringCompositeBuilder.java @@ -0,0 +1,88 @@ +/* + * 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.container.spring.impl; + +import org.apache.tuscany.spi.QualifiedName; +import org.apache.tuscany.spi.builder.BuilderConfigException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentBuilderExtension; +import org.apache.tuscany.spi.model.Binding; +import org.apache.tuscany.spi.model.BoundReferenceDefinition; +import org.apache.tuscany.spi.model.BoundServiceDefinition; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.wire.InboundInvocationChain; +import org.apache.tuscany.spi.wire.InboundWire; + +import org.apache.tuscany.container.spring.model.SpringImplementation; +import org.springframework.context.support.AbstractApplicationContext; + +/** + * Creates a {@link org.apache.tuscany.container.spring.impl.SpringCompositeComponent} from an assembly model + * + * @version $$Rev$$ $$Date$$ + */ +public class SpringCompositeBuilder extends ComponentBuilderExtension<SpringImplementation> { + + public Component build(CompositeComponent parent, + ComponentDefinition<SpringImplementation> componentDefinition, + DeploymentContext deploymentContext) throws BuilderConfigException { + String name = componentDefinition.getName(); + SpringImplementation implementation = componentDefinition.getImplementation(); + AbstractApplicationContext applicationContext = implementation.getComponentType().getApplicationContext(); + SpringCompositeComponent component = + new SpringCompositeComponent(name, applicationContext, parent, connector, null); + CompositeComponentType<BoundServiceDefinition<? extends Binding>, + BoundReferenceDefinition<? extends Binding>, + ? extends Property> componentType = implementation.getComponentType(); + + // We still need to set the target invoker as opposed to having the connector do it since the + // Spring context is "opaque" to the wiring fabric. In other words, the Spring context does not expose + // its beans as SCA components to the connector to wire the services to + for (BoundServiceDefinition<? extends Binding> serviceDefinition : componentType.getServices().values()) { + // call back into builder registry to handle building of services + Service service = (Service) builderRegistry.build(parent, serviceDefinition, deploymentContext); + // wire serviceDefinition to bean invokers + InboundWire wire = service.getInboundWire(); + QualifiedName targetName = new QualifiedName(serviceDefinition.getTarget().getPath()); + for (InboundInvocationChain chain : wire.getInvocationChains().values()) { + // FIXME this should go to the connector and get policy and be invoked from SpringComposite.prepare() + chain.addInterceptor(new SpringInterceptor()); + chain.setTargetInvoker(component.createTargetInvoker(targetName.getPartName(), chain.getOperation())); + } + component.register(service); + } + for (BoundReferenceDefinition<?> referenceDefinition : componentType.getReferences().values()) { + // call back into builder registry to handle building of references + Reference reference = (Reference) builderRegistry.build(parent, referenceDefinition, deploymentContext); + connector.connect(reference); + component.register(reference); + } + return component; + } + + protected Class<SpringImplementation> getImplementationType() { + return SpringImplementation.class; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringCompositeComponent.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringCompositeComponent.java new file mode 100644 index 0000000000..b30202cb96 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringCompositeComponent.java @@ -0,0 +1,252 @@ +/* + * 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.container.spring.impl; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Locale; +import java.util.Map; + +import org.w3c.dom.Document; + +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.SCAObject; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.extension.CompositeComponentExtension; +import static org.apache.tuscany.spi.idl.java.JavaIDLUtils.findMethod; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.TargetInvoker; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanNotOfRequiredTypeException; +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.ConfigurableApplicationContext; +import org.springframework.context.MessageSourceResolvable; +import org.springframework.context.NoSuchMessageException; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.core.io.Resource; + +/** + * A composite implementation responsible for managing Spring application contexts. + * + * @version $$Rev$$ $$Date$$ + */ +public class SpringCompositeComponent extends CompositeComponentExtension { + private static final String[] EMPTY_ARRAY = new String[0]; + private AbstractApplicationContext springContext; + + /** + * Creates a new composite + * + * @param name the name of the SCA composite + * @param springContext the pre-instantiated Spring applicaiton context + * @param parent the SCA composite parent + * @param connector the connector to use for wiring children + * @param propertyValues the values of this composite's Properties + */ + public SpringCompositeComponent(String name, + AbstractApplicationContext springContext, + CompositeComponent parent, + Connector connector, + Map<String, Document> propertyValues) { + super(name, parent, connector, propertyValues); + SCAApplicationContext scaApplicationContext = new SCAApplicationContext(); + springContext.setParent(scaApplicationContext); + // REVIEW we need to refresh to pick up the parent but this is not optimal + springContext.refresh(); + this.springContext = springContext; + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) { + ServiceContract contract = operation.getServiceContract(); + Method[] methods = contract.getInterfaceClass().getMethods(); + Method method = findMethod(operation, methods); + // FIXME test m == null + // Treat the serviceName as the Spring bean name to look up + return new SpringInvoker(targetName, method, springContext); + } + + public void setScopeContainer(ScopeContainer scopeContainer) { + // not needed + } + + public ConfigurableApplicationContext getApplicationContext() { + return springContext; + } + + public void prepare() { + // TODO handle only references with a composite binding + } + + public void start() { + super.start(); + for (SCAObject child : children.values()) { + child.start(); + } + springContext.start(); + } + + public void stop() { + super.stop(); + springContext.stop(); + } + + public <T> T locateService(Class<T> serviceInterface, String name) { + return serviceInterface.cast(springContext.getBean(name)); + } + + /** + * An inner class is required to act as the Spring application context parent as opposed to implementing the + * interface since the return types for {@link org.springframework.context.ApplicationContext#getParent()} and + * {@link org.apache.tuscany.spi.component.CompositeComponent#getParent()} clash + */ + private class SCAApplicationContext implements ApplicationContext { + + public Object getBean(String name) throws BeansException { + return getBean(name, null); + } + + public Object getBean(String name, Class requiredType) throws BeansException { + SCAObject object = children.get(name); // keep cast due to compiler error + if (object == null) { + return null; + } + Class<?> type; + if (object instanceof Reference) { + type = ((Reference) object).getInterface(); + } else if (object instanceof Service) { + type = ((Service) object).getInterface(); + } else { + throw new AssertionError("Illegal object type [" + name + "]"); + } + if (requiredType != null && requiredType.isAssignableFrom(type)) { + // need null check since Spring may pass in a null + throw new BeanNotOfRequiredTypeException(name, requiredType, type); + } + return object.getServiceInstance(); + } + + public boolean containsBean(String name) { + return children.get(name) != null; + } + + public boolean isSingleton(String name) throws NoSuchBeanDefinitionException { + return children.get(name) != null; + } + + 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 getDisplayName() { + return getName(); + } + + 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 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/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringImplementationLoader.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringImplementationLoader.java new file mode 100644 index 0000000000..c95375cad2 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringImplementationLoader.java @@ -0,0 +1,196 @@ +/* + * 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.container.spring.impl; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +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 static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import static org.osoa.sca.Version.XML_NAMESPACE_1_0; + +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.LoaderExtension; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.MissingResourceException; +import org.apache.tuscany.spi.model.BoundReferenceDefinition; +import org.apache.tuscany.spi.model.BoundServiceDefinition; + +import org.apache.tuscany.container.spring.model.SpringComponentType; +import org.apache.tuscany.container.spring.model.SpringImplementation; +import org.apache.tuscany.host.RuntimeInfo; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; + +/** + * Loader for handling Spring <spring:implementation.spring> elements. + */ +public class SpringImplementationLoader extends LoaderExtension<SpringImplementation> { + private static final QName IMPLEMENTATION_SPRING = new QName("http://www.osoa.org/xmlns/sca/1.0", + "implementation.spring"); + + private static final String APPLICATION_CONTEXT = "application-context.xml"; + + private static final QName SERVICE_ELEMENT = new QName(XML_NAMESPACE_1_0, "service"); + private static final QName REFERENCE_ELEMENT = new QName(XML_NAMESPACE_1_0, "reference"); + + private final RuntimeInfo runtimeInfo; + + public SpringImplementationLoader(@Autowire LoaderRegistry registry, @Autowire RuntimeInfo runtimeInfo) { + super(registry); + this.runtimeInfo = runtimeInfo; + } + + public QName getXMLType() { + return IMPLEMENTATION_SPRING; + } + + @SuppressWarnings("unchecked") + public SpringImplementation load(CompositeComponent parent, + XMLStreamReader reader, + DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException { + + String locationAttr = reader.getAttributeValue(null, "location"); + if (locationAttr == null && !contextProvided()) { + throw new MissingResourceException("No location supplied"); + } + + SpringImplementation implementation = new SpringImplementation(); + ClassLoader classLoader = deploymentContext.getClassLoader(); + if (!contextProvided()) { + implementation.setApplicationResource(getApplicationContextResource(locationAttr, classLoader)); + } + registry.loadComponentType(parent, implementation, deploymentContext); + SpringComponentType type = implementation.getComponentType(); + while (true) { + switch (reader.next()) { + case START_ELEMENT: + QName qname = reader.getName(); + if (SERVICE_ELEMENT.equals(qname)) { + BoundServiceDefinition service = + (BoundServiceDefinition) registry.load(parent, reader, deploymentContext); + if (!type.isExposeAllBeans()) { + String name = service.getName(); + if (!type.getServiceTypes().containsKey(name)) { + LoaderException e = new LoaderException("No service defined in Spring context for "); + e.setIdentifier(name); + throw e; + } + } + type.getDeclaredServices().put(service.getName(), service); + } else if (REFERENCE_ELEMENT.equals(qname)) { + BoundReferenceDefinition reference = + (BoundReferenceDefinition) registry.load(parent, reader, deploymentContext); + type.getDeclaredReferences().put(reference.getName(), reference); + } + break; + case END_ELEMENT: + if (IMPLEMENTATION_SPRING.equals(reader.getName())) { + return implementation; + } + } + } + } + + protected Resource getApplicationContextResource(String locationAttr, ClassLoader cl) throws LoaderException { + assert runtimeInfo != null; + File manifestFile = null; + File appXmlFile; + File locationFile = new File(locationAttr); + + if (!locationFile.isAbsolute()) { + locationFile = new File(runtimeInfo.getApplicationRootDirectory(), locationAttr); + } + if (!locationFile.exists()) { + // FIXME hack + URL url = cl.getResource(locationAttr); + if (url != null) { + return new UrlResource(url); + } + throw new MissingResourceException(locationFile.toString()); + } + + if (locationFile.isDirectory()) { + try { + manifestFile = new File(locationFile, "META-INF/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, APPLICATION_CONTEXT); + if (appXmlFile.exists()) { + return new UrlResource(appXmlFile.toURL()); + } + } catch (IOException e) { + throw new LoaderException("Error reading manifest " + manifestFile); + } + } else { + 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 Resouce type for jars + return new UrlResource(new URL("jar:" + locationFile.toURL() + "!/" + appCtxPath)); + } + } + } + je = jf.getJarEntry(APPLICATION_CONTEXT); + if (je != null) { + return new UrlResource(new URL("jar:" + locationFile.toURI().toURL() + "!" + APPLICATION_CONTEXT)); + } + } catch (IOException e) { + // bad archive + // TODO: create a more appropriate exception type + throw new MissingResourceException(locationAttr, e); + } + } + throw new MissingResourceException(APPLICATION_CONTEXT); + } + + private boolean contextProvided() { + return runtimeInfo instanceof SpringRuntimeInfo; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringInterceptor.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringInterceptor.java new file mode 100644 index 0000000000..fb7f0bd99c --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringInterceptor.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.container.spring.impl; + +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; + +/** + * A temporary interceptor until the connector is updated + * + * @version $Rev$ $Date$ + */ +public class SpringInterceptor implements Interceptor { + + public Message invoke(Message msg) throws InvocationRuntimeException { + TargetInvoker invoker = msg.getTargetInvoker(); + if (invoker == null) { + throw new InvocationRuntimeException("No target invoker specified on message"); + } + return invoker.invoke(msg); + } + + public void setNext(Interceptor next) { + throw new IllegalStateException("This interceptor must be the last one in an target interceptor chain"); + } + + public Interceptor getNext() { + return null; + } + + public boolean isOptimizable() { + return true; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringInvoker.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringInvoker.java new file mode 100644 index 0000000000..6e05c888ae --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringInvoker.java @@ -0,0 +1,104 @@ +/* + * 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.container.spring.impl; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; + +/** + * Dispatches to an operation on a Spring bean. Since Spring manages bean lifecycle and scope through resolution in the + * target proxy, the invoker can safely cache the target proxy. + * + * @version $$Rev$$ $$Date$$ + */ +public class SpringInvoker implements TargetInvoker { + private ApplicationContext springContext; + // default to true since Spring handles resolution + private boolean cacheable = true; + private String beanName; + private Method method; + // caching is thread-safe since Spring handles resolution + private Object bean; + + public SpringInvoker(String beanName, Method method, ApplicationContext context) { + this.beanName = beanName; + this.method = method; + springContext = context; + } + + public Object invokeTarget(final Object object) throws InvocationTargetException { + if (bean == null) { + try { + bean = springContext.getBean(beanName); + } catch (BeansException e) { + throw new TargetException(e); + } + } + try { + if (object != null && !object.getClass().isArray()) { + return method.invoke(bean, object); + } else { + return method.invoke(bean, (Object[]) object); + } + } catch (IllegalAccessException e) { + throw new InvocationTargetException(e); + } + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + Object resp = invokeTarget(msg.getBody()); + msg.setBody(resp); + } catch (InvocationTargetException e) { + msg.setBodyWithFault(e.getCause()); + } catch (Throwable e) { + msg.setBodyWithFault(e); + } + return msg; + } + + public boolean isCacheable() { + return cacheable; + } + + public void setCacheable(boolean cacheable) { + this.cacheable = cacheable; + } + + public boolean isOptimizable() { + return false; + } + + + public SpringInvoker clone() throws CloneNotSupportedException { + SpringInvoker invoker = (SpringInvoker) super.clone(); + invoker.bean = null; + return invoker; + } + + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringRuntimeInfo.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringRuntimeInfo.java new file mode 100644 index 0000000000..8b4f0ac905 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringRuntimeInfo.java @@ -0,0 +1,63 @@ +/* + * 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.container.spring.impl; + +import java.io.File; +import java.net.URL; + +import org.apache.tuscany.host.RuntimeInfo; +import org.springframework.context.support.AbstractRefreshableApplicationContext; + +/** + * @author Andy Piper + * @since 2.1 + */ +public class SpringRuntimeInfo implements RuntimeInfo { + private AbstractRefreshableApplicationContext applicationContext; + private File appRootDir; + + public SpringRuntimeInfo(File appRootDir, AbstractRefreshableApplicationContext applicationContext) { + this.appRootDir = appRootDir; + this.applicationContext = applicationContext; + } + + public AbstractRefreshableApplicationContext getApplicationContext() { + return applicationContext; + } + + public void setApplicationContext(AbstractRefreshableApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + public File getInstallDirectory() { + return null; + } + + public File getApplicationRootDirectory() { + return appRootDir; + } + + public URL getBaseURL() { + return null; + } + + public boolean isOnline() { + return true; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringScaAdapter.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringScaAdapter.java new file mode 100644 index 0000000000..ca645db823 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/impl/SpringScaAdapter.java @@ -0,0 +1,54 @@ +/* + * 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.container.spring.impl; + +import org.apache.tuscany.container.spring.model.SpringComponentType; +import org.springframework.sca.ScaAdapter; + +/** + * @author Andy Piper + * @since 2.1 + */ +public class SpringScaAdapter implements ScaAdapter { + //private final SpringComponentType componentType; + + public SpringScaAdapter(SpringComponentType componentType) { + //this.componentType = componentType; + } + + public Object getServiceReference(String referenceName, Class referenceType, String moduleName, + String defaultServiceName) { + /* + ReferenceDefinition reference = null; + componentType.getReferences().put(referenceName, reference); + */ + return null; + } + + public Object getPropertyReference(String propertyName, Class propertyType, String moduleName) { + return null; + } + + public void publishAsService(Object serviceImplementation, Class serviceInterface, String serviceName, + String moduleName) { + /* + componentType.addServiceType(serviceName, serviceInterface); + ServiceDefinition service = null; + componentType.getServices().put(serviceName, service); + */ + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/model/SpringComponentType.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/model/SpringComponentType.java new file mode 100644 index 0000000000..d8758ffdb7 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/model/SpringComponentType.java @@ -0,0 +1,101 @@ +/* + * 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.container.spring.model; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import org.springframework.context.support.AbstractApplicationContext; + +/** + * Component type information for a Spring composite component implementation type. A component type is associated with + * a Spring application context + * + * @version $Rev$ $Date$ + */ +public class SpringComponentType<S extends ServiceDefinition, + R extends ReferenceDefinition, + P extends Property<?>> extends CompositeComponentType<S, R, P> { + + private AbstractApplicationContext applicationContext; + private Map<String, Class<?>> serviceTypes = new HashMap<String, Class<?>>(); + private boolean exposeAllBeans; + + public SpringComponentType(AbstractApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + public SpringComponentType() { + } + + // FIXME andyp@bea.com -- this is a component type it should NOT contain bean instances! + + /** + * Returns the application context for the component type + */ + public AbstractApplicationContext getApplicationContext() { + return applicationContext; + } + + public void setApplicationContext(AbstractApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + /** + * Returns a collection of service types defined by <code>sca:service</code> elements in a Spring configuration. + * Service types define beans that can be targets of services defined in the SCDL Spring composite declaration. For + * each service type, there must be a corresponding service definition as part of the Spring composite declaration + * per the SCA specification. + */ + public Map<String, Class<?>> getServiceTypes() { + return serviceTypes; + } + + /** + * Adds a service type to the component declaration defined by <code>sca:service</code> elements in a Spring + * configuration. + * + * @param name the name of the service + * @param type the interface type of the target bean + */ + public void addServiceType(String name, Class<?> type) { + this.serviceTypes.put(name, type); + } + + /** + * Returns true if all beans in the Spring application context may be service targets or false if service types are + * defined + */ + public boolean isExposeAllBeans() { + return exposeAllBeans; + } + + /** + * Sets if all beans in the Spring application context may be service targets or false if service types are defined + */ + public void setExposeAllBeans(boolean exposeAllBeans) { + this.exposeAllBeans = exposeAllBeans; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/model/SpringImplementation.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/model/SpringImplementation.java new file mode 100644 index 0000000000..7780894f56 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/model/SpringImplementation.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.container.spring.model; + +import org.apache.tuscany.spi.model.Binding; +import org.apache.tuscany.spi.model.BoundReferenceDefinition; +import org.apache.tuscany.spi.model.BoundServiceDefinition; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.Property; + +import org.springframework.core.io.Resource; + +/** + * Represents a composite whose implementation type is a Spring application context. + * + * @version $$Rev$$ $$Date$$ + */ +public class SpringImplementation extends Implementation<SpringComponentType<BoundServiceDefinition<? extends Binding>, + BoundReferenceDefinition<? extends Binding>, ? extends Property>> { + + private String location; + private Resource applicationResource; + + public SpringImplementation() { + } + + public SpringImplementation(SpringComponentType< + BoundServiceDefinition<? extends Binding>, + BoundReferenceDefinition<? extends Binding>, + ? extends Property> componentType) { + super(componentType); + } + + /** + * Returns the path of the Spring application context configuration + */ + public String getLocation() { + return location; + } + + /** + * Sets the path of the Spring application context configuration + */ + public void setLocation(String location) { + this.location = location; + } + + /** + * Returns the Spring configuration resource for the application context + */ + public Resource getApplicationResource() { + return applicationResource; + } + + /** + * Sets the Spring configuration resource for the application context + */ + public void setApplicationResource(Resource applicationXml) { + this.applicationResource = applicationXml; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/model/SpringServiceContract.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/model/SpringServiceContract.java new file mode 100644 index 0000000000..3a88991e4b --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/model/SpringServiceContract.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.container.spring.model; + +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * @version $Rev$ $Date$ + */ +public class SpringServiceContract extends ServiceContract { + + public SpringServiceContract(String interfaceName) { + super(interfaceName); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/webapp/ScaWebApplicationContext.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/webapp/ScaWebApplicationContext.java new file mode 100644 index 0000000000..2284d32201 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/webapp/ScaWebApplicationContext.java @@ -0,0 +1,130 @@ +/* + * 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.container.spring.webapp; + +import java.io.File; +import java.net.URL; + +import javax.servlet.ServletContext; + +import org.apache.tuscany.api.TuscanyRuntimeException; +import org.apache.tuscany.container.spring.config.SCANamespaceHandlerResolver; +import org.apache.tuscany.container.spring.impl.SpringScaAdapter; +import org.apache.tuscany.container.spring.model.SpringComponentType; +import org.apache.tuscany.runtime.webapp.WebappRuntime; +import org.apache.tuscany.runtime.webapp.WebappUtil; +import org.apache.tuscany.runtime.webapp.WebappUtilImpl; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.core.io.Resource; +import org.springframework.sca.ScaAdapterAware; +import org.springframework.sca.ScaAdapterPostProcessor; +import org.springframework.util.Assert; +import org.springframework.web.context.ConfigurableWebApplicationContext; +import org.springframework.web.context.support.XmlWebApplicationContext; + +/** + * WebApplicationContext implementation that understands SCA extensions. + * This class is not very complicated, the key issue is getting hold of a reference + * to the Tuscany runtime which the webapp is using. + * + * @author Andy Piper + */ +public class ScaWebApplicationContext extends XmlWebApplicationContext + implements ConfigurableWebApplicationContext { + private WebappRuntime runtime; + private SpringComponentType componentType; + + public ScaWebApplicationContext() { + } + + protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) { +// beanDefinitionReader.setEntityResolver(null); + beanDefinitionReader + .setNamespaceHandlerResolver(new SCANamespaceHandlerResolver(getClassLoader(), componentType)); + } + + public Resource getResource(String location) { + Assert.notNull(location, "location is required"); + return super.getResource(location); + } + + /* (non-Javadoc) + * @see org.springframework.context.support.AbstractApplicationContext#postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory) + */ + protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + super.postProcessBeanFactory(beanFactory); + beanFactory.addBeanPostProcessor(new ScaAdapterPostProcessor + (new SpringScaAdapter(componentType))); + beanFactory.ignoreDependencyInterface(ScaAdapterAware.class); + } + + protected void onRefresh() { + if (runtime != null) { // egregious hack to prevent recursion in refresh() + return; + } + ServletContext servletContext = getServletContext(); + WebappUtil utils = getUtils(servletContext); + + try { + ClassLoader webappClassLoader = Thread.currentThread().getContextClassLoader(); + ClassLoader bootClassLoader = utils.getBootClassLoader(webappClassLoader); + runtime = utils.getRuntime(bootClassLoader); + URL systemScdl = utils.getSystemScdl(bootClassLoader); + URL applicationScdl = utils.getApplicationScdl(webappClassLoader); + + runtime.setMonitorFactory(runtime.createDefaultMonitorFactory()); + runtime.setApplicationName(utils.getApplicationName()); + runtime.setServletContext(servletContext); + runtime.setHostClassLoader(webappClassLoader); + runtime.setSystemScdl(systemScdl); + runtime.setApplicationScdl(applicationScdl); + runtime.setRuntimeInfo(new SpringWebappRuntimeInfo(getApplicationRootDirectory(), this)); + runtime.initialize(); + } catch (TuscanyRuntimeException e) { + servletContext.log(e.getMessage(), e); + throw e; + } + } + + protected WebappUtil getUtils(ServletContext servletContext) { + return new WebappUtilImpl(servletContext); + } + + protected void onClose() { + if (runtime != null) { + runtime.destroy(); + runtime = null; + } + } + + /** + * What does this do and why to we need it? + * @return + */ + private File getApplicationRootDirectory() { + String property = System.getProperty("tuscany.applicationRootDir"); + if (property != null) { + return new File(property); + } + + return new File(System.getProperty("user.dir")); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/webapp/SpringWebappRuntimeInfo.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/webapp/SpringWebappRuntimeInfo.java new file mode 100644 index 0000000000..a860049462 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/apache/tuscany/container/spring/webapp/SpringWebappRuntimeInfo.java @@ -0,0 +1,41 @@ +/* + * 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.container.spring.webapp; + +import java.io.File; +import javax.servlet.ServletContext; + +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.XmlWebApplicationContext; + +import org.apache.tuscany.container.spring.impl.SpringRuntimeInfo; +import org.apache.tuscany.runtime.webapp.WebappRuntimeInfo; + +/** + * @author Andy Piper + */ +public class SpringWebappRuntimeInfo extends SpringRuntimeInfo implements WebappRuntimeInfo { + public SpringWebappRuntimeInfo(File appRootDir, XmlWebApplicationContext applicationContext) { + super(appRootDir, applicationContext); + } + + public ServletContext getServletContext() { + return ((WebApplicationContext) getApplicationContext()).getServletContext(); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/DefaultScaAdapter.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/DefaultScaAdapter.java new file mode 100644 index 0000000000..e2071e27c3 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/DefaultScaAdapter.java @@ -0,0 +1,46 @@ +/* + * 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. + * + * Created on 11-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca; + +/** + * @author Adrian Colyer + * @since 2.0 + */ +public class DefaultScaAdapter implements ScaAdapter { + + public Object getServiceReference(String referenceName, + Class referenceType, + String moduleName, + String defaultServiceName) { + // TODO + return new Object(); + } + + public Object getPropertyReference(String propertyName, Class propertyType, String moduleName) { + // TODO + return new Object(); + } + + public void publishAsService(Object serviceImplementation, + Class serviceInterface, + String serviceName, + String moduleName) { + // TODO + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapter.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapter.java new file mode 100644 index 0000000000..e5aae6f0a2 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapter.java @@ -0,0 +1,45 @@ +/* + * 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. + * + * Created on 11-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca; + +/** + * Encapsulates interaction with an SCA runtime + * + * @author Adrian Colyer + * @since 2.0 + */ +public interface ScaAdapter { + + Object getServiceReference( + String referenceName, + Class referenceType, + String moduleName, + String defaultServiceName); + + Object getPropertyReference( + String propertyName, + Class propertyType, + String moduleName); + + void publishAsService( + Object serviceImplementation, + Class serviceInterface, + String serviceName, + String moduleName); + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapterAware.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapterAware.java new file mode 100644 index 0000000000..abe975c936 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapterAware.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.springframework.sca; + +/** + * /** Interface that enables beans to find the ScaAdapter they are defined with. + * <p/> + * Note that in most circumstances there is no need for a bean to implement this interface. + * + * @author Andy Piper + * @since 2.1 + */ +public interface ScaAdapterAware { + void setScaAdapter(ScaAdapter adapter); +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapterPostProcessor.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapterPostProcessor.java new file mode 100644 index 0000000000..b07be8f452 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapterPostProcessor.java @@ -0,0 +1,52 @@ +/* + * 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.springframework.sca; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; + +/** + * @author Andy Piper + * @since 2.1 + */ +public class ScaAdapterPostProcessor implements BeanPostProcessor { + private ScaAdapter scaAdapter; + + public ScaAdapterPostProcessor(ScaAdapter adapter) { + this.scaAdapter = adapter; + } + + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof ScaAdapterAware) { + if (this.scaAdapter == null) { + throw new IllegalStateException("Cannot satisfy ScaAdapterAware for bean '" + + beanName + "' without ScaAdapater"); + } + ((ScaAdapterAware) bean).setScaAdapter(scaAdapter); + } + return bean; + } + + public Object postProcessAfterInitialization(Object object, String string) throws BeansException { + return object; + } + + public ScaAdapter getScaAdapter() { + return scaAdapter; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaComposite.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaComposite.java new file mode 100644 index 0000000000..e12e763d9f --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaComposite.java @@ -0,0 +1,77 @@ +/* + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca; + +import org.springframework.beans.factory.InitializingBean; + +/** + * Bean that represents an Sca composite component. An instance of this bean is created when the <sca:composite + * module-id="xxx"/> element is declared. + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaComposite implements InitializingBean { + + private String component; + private ScaAdapter scaAdapter = new DefaultScaAdapter(); + + public String getComponent() { + return this.component; + } + + public void setComponent(String component) { + this.component = component; + } + + public void setScaAdapter(ScaAdapter scaAdapter) { + this.scaAdapter = scaAdapter; + } + + public void setScaAdapterClass(Class adapterClass) { + if (!ScaAdapter.class.isAssignableFrom(adapterClass)) { + throw new IllegalArgumentException( + "Adapter class '" + adapterClass + "' specified for ScaComposite bean " + + "does not implement the ScaApapter interface" + ); + } + try { + this.scaAdapter = (ScaAdapter) adapterClass.newInstance(); + } catch (Exception ex) { + // many exceptions may be thrown by the above, we treat them all + // the same + throw new IllegalStateException("Unable to create instance of ScaAdapter class '" + + adapterClass.getName() + "'", ex); + } + } + + public ScaAdapter getScaAdapter() { + return this.scaAdapter; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ + public void afterPropertiesSet() throws Exception { + if (this.component == null) { + throw new IllegalArgumentException("Required property moduleId was not set"); + } + } + + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaPostProcessor.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaPostProcessor.java new file mode 100644 index 0000000000..f96af00584 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaPostProcessor.java @@ -0,0 +1,147 @@ +/* + * 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.springframework.sca; + +import java.beans.PropertyDescriptor; + +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.PropertyValues; +import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.core.task.TaskExecutor; +import org.springframework.sca.intercept.OneWayAdvisor; +import org.springframework.sca.metadata.DeploymentMetadata; +import org.springframework.sca.metadata.Injection; +import org.springframework.sca.metadata.NoSuchServiceException; +import org.springframework.sca.metadata.ServiceMetadata; + +/** + * Spring bean post processor that looks up service metadata by name for each bean definition and performs SCA + * injection. + * <p/> + * Also performs proxying for OneWay. + * + * @author Rod Johnson + */ +public class ScaPostProcessor implements InstantiationAwareBeanPostProcessor, ApplicationContextAware { + + private DeploymentMetadata deploymentMetadata; + + private ApplicationContext applicationContext; + + private TaskExecutor taskExecutor; + + //private ScaAdapter scaAdapter; + + + /** + * @param taskExecutor The taskExecutor to set. + */ + public void setTaskExecutor(TaskExecutor taskExecutor) { + this.taskExecutor = taskExecutor; + } + + // TODO would process side files when container starts up + + public void setDeploymentMetadata(DeploymentMetadata deploymentMetadata) { + this.deploymentMetadata = deploymentMetadata; + } + + /** + * @param scaAdapter the ScaAdapter for use to export services if necessary + */ + public void setScaAdapter(ScaAdapter scaAdapter) { + //this.scaAdapter = scaAdapter; + } + + + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + public Object postProcessBeforeInstantiation(Class beanClass, + String beanName) throws BeansException { + return null; + } + + public boolean postProcessAfterInstantiation(Object bean, String beanName) + throws BeansException { + try { + ServiceMetadata smd = deploymentMetadata.getServiceMetadata(beanName); + doScaInjection(bean, smd); + } catch (NoSuchServiceException ex) { + // + } + return true; + } + + public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, + String beanName) throws BeansException { + return pvs; + } + + public PropertyValues postProcessPropertyValues(PropertyValues propertyValues, Object object, String string) + throws BeansException { + return propertyValues; + } + + protected void doScaInjection(Object bean, ServiceMetadata smd) { + for (Injection injection : smd.getInjections()) { + injection.apply(applicationContext, bean); + } + } + + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + try { + ServiceMetadata smd = deploymentMetadata.getServiceMetadata(beanName); + return createScaProxy(bean, smd); + } catch (NoSuchServiceException ex) { + return bean; + } + + // TODO validate required injections here or earlier + + // TODO publish if necessary, using adapter + } + + protected Object createScaProxy(Object bean, ServiceMetadata smd) { + ProxyFactory pf = new ProxyFactory(bean); + for (Class intf : smd.getServiceInterfaces()) { + pf.addInterface(intf); + } + +//pf.addAdvisor(ExposeInvocationInterceptor.ADVISOR); +//pf.addAdvisor(new ExposeBeanNameAdvisor(smd.getServiceName())); + // TODO enforce call by value + + if (!smd.getOneWayMethods().isEmpty()) { + pf.addAdvisor(new OneWayAdvisor(smd, this.taskExecutor)); + } + + return pf.getProxy(); + } + + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaPropertyProxyFactoryBean.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaPropertyProxyFactoryBean.java new file mode 100644 index 0000000000..e89072466a --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaPropertyProxyFactoryBean.java @@ -0,0 +1,123 @@ +/* + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; + +/** + * Factory bean that returns a reference to an SCA property obtained by asking the SCA runtime for the property with the + * given name for the given component. + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaPropertyProxyFactoryBean implements InitializingBean, FactoryBean { + + /** + * the type of the property + */ + private Class propertyType; + + /** + * the name of the property to look up + */ + private String propertyName; + + /** + * the SCA component we should present ourselves as when asking for a service reference + */ + private ScaComposite scaComposite; + + private Object resolvedPropertyVal; + + public void setPropertyType(Class serviceType) { + this.propertyType = serviceType; + } + + public Class getPropertyType() { + return this.propertyType; + } + + public void setPropertyName(String name) { + this.propertyName = name; + } + + public String getPropertyName() { + return this.propertyName; + } + + public void setScaComposite(ScaComposite scaComposite) { + this.scaComposite = scaComposite; + } + + public ScaComposite getScaComposite() { + return this.scaComposite; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ + public void afterPropertiesSet() throws Exception { + if (this.propertyType == null) { + throw new IllegalArgumentException("Required property serviceType was not set"); + } + if (this.scaComposite == null) { + throw new IllegalArgumentException("Required property scaComposite was not set"); + } + if (this.propertyName == null) { + throw new IllegalArgumentException("Required property referenceName was not set"); + } + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObject() + */ + public Object getObject() throws Exception { + if (this.resolvedPropertyVal != null) { + return this.resolvedPropertyVal; + } + + String moduleName = this.scaComposite.getComponent(); + // TODO: AMC is there any merit in proxying this with a lazy target source? + Object propertyVal = + this.scaComposite.getScaAdapter().getPropertyReference(this.propertyName, this.propertyType, moduleName); + if (!this.propertyType.isAssignableFrom(propertyVal.getClass())) { + throw new IllegalStateException("Property value '" + propertyVal.toString() + "'" + + " of type '" + propertyVal.getClass().getName() + "' " + + " is not of expected type '" + this.propertyType.getName() + "'"); + } + this.resolvedPropertyVal = propertyVal; + return this.resolvedPropertyVal; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObjectType() + */ + public Class getObjectType() { + return this.propertyType; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#isSingleton() + */ + public boolean isSingleton() { + return true; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaServiceExporter.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaServiceExporter.java new file mode 100644 index 0000000000..0155dd9646 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaServiceExporter.java @@ -0,0 +1,105 @@ +/* + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.InitializingBean; + +/** + * Exposes a bean instance to SCA to using the given service name. + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaServiceExporter implements InitializingBean, BeanFactoryAware, ScaAdapterAware { + + /** + * the name of the service we want to advertise + */ + private String serviceName; + + /** + * the type the service should be published with + */ + private Class serviceType; + + /** + * the bean to be published + */ + private Object target; + + /** + * for resolving the bean name + */ + private BeanFactory beanFactory; + private ScaAdapter scaAdapter; + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getServiceName() { + return this.serviceName; + } + + public void setServiceType(Class serviceType) { + this.serviceType = serviceType; + } + + public Class getServiceType() { + return this.serviceType; + } + + public void setTarget(Object targetBean) { + this.target = targetBean; + } + + public Object getTarget() { + return this.target; + } + + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = beanFactory; + } + + public void afterPropertiesSet() throws Exception { + if (this.serviceType == null) { + throw new IllegalArgumentException("Required property serviceType was not set"); + } + if (this.target == null) { + throw new IllegalArgumentException("Required property target was not set"); + } + if (this.beanFactory == null) { + throw new IllegalArgumentException("Required property beanFactory was not set"); + } + if (this.serviceName == null) { + throw new IllegalArgumentException("Required property serviceName was not set"); + } + publishScaService(); + } + + private void publishScaService() { + scaAdapter.publishAsService(target, serviceType, serviceName, null); + } + + public void setScaAdapter(ScaAdapter adapter) { + this.scaAdapter = adapter; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaServiceProxyFactoryBean.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaServiceProxyFactoryBean.java new file mode 100644 index 0000000000..01ca5671d4 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/ScaServiceProxyFactoryBean.java @@ -0,0 +1,144 @@ +/* + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * Factory bean that returns a reference to an SCA service obtained by asking the SCA runtime for the service with the + * given name for the given component. + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaServiceProxyFactoryBean + implements InitializingBean, FactoryBean, ApplicationContextAware, ScaAdapterAware { + + /** + * the public interface type of the service (may be a class...) + */ + private Class serviceType; + + /** + * the name of the reference to look up + */ + private String referenceName; + + /** + * the default service name to resolve the reference too + */ + private String defaultServiceName; + + private Object resolvedServiceReference; + private ApplicationContext applicationContext; + //private ScaAdapter scaAdapter; + + public void setServiceType(Class serviceType) { + this.serviceType = serviceType; + } + + public Class getServiceType() { + return this.serviceType; + } + + public void setReferenceName(String name) { + this.referenceName = name; + } + + public String getReferenceName() { + return this.referenceName; + } + + public void setDefaultServiceName(String defaultService) { + this.defaultServiceName = defaultService; + } + + public String getDefaultServiceName() { + return this.defaultServiceName; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ + public void afterPropertiesSet() throws Exception { + if (this.serviceType == null) { + throw new IllegalArgumentException("Required property serviceType was not set"); + } + if (this.referenceName == null) { + throw new IllegalArgumentException("Required property referenceName was not set"); + } + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObject() + */ + public Object getObject() throws Exception { + if (this.resolvedServiceReference != null) { + return this.resolvedServiceReference; + } + + // TODO: AMC is there any merit in proxying this with a lazy target source? + // should the returned service ref be proxied? Only seems to add value + // if SCA gives us any lifecycle events we can subscribe to and take + // meaningful action on... + // See OsgiServiceProxyFactoryBean for an example of how to do the + // proxying if needed. + Object scaServiceRef; + if (this.applicationContext.getParent() == null) { + return null; + } + + if (!this.applicationContext.getParent().containsBean(this.referenceName)) { + return new Object(); + //scaServiceRef = this.applicationContext.getParent().getBean(this.defaultServiceName); + } else { + scaServiceRef = this.applicationContext.getParent().getBean(this.referenceName); + } + if (!this.serviceType.isAssignableFrom(scaServiceRef.getClass())) { + throw new IllegalStateException("..."); + } + this.resolvedServiceReference = scaServiceRef; + return this.resolvedServiceReference; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObjectType() + */ + public Class getObjectType() { + return this.serviceType; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#isSingleton() + */ + public boolean isSingleton() { + return false; + } + + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + public void setScaAdapter(ScaAdapter adapter) { + // this.scaAdapter = adapter; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaCompositeBeanDefinitionParser.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaCompositeBeanDefinitionParser.java new file mode 100644 index 0000000000..9c6ac633f7 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaCompositeBeanDefinitionParser.java @@ -0,0 +1,67 @@ +/* + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca.config; + +import org.w3c.dom.Element; + +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.sca.ScaComposite; + +/** + * Parser for <sca:composite> elements + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaCompositeBeanDefinitionParser implements BeanDefinitionParser { + + static final String SCA_COMPOSITE_BEAN_NAME = "scaComposite"; + private static final String MODULE_ATTRIBUTE_NAME = "component"; + private static final String MODULE_ID = "component"; + private static final String ADAPTER_ATTRIBUTE = "sca-adapter-class"; + private static final String ADAPTER_CLASS_PROPERTY = "scaAdapterClass"; + + public BeanDefinition parse(Element element, ParserContext parserContext) { + BeanDefinitionRegistry registry = parserContext.getRegistry(); + if (registry.containsBeanDefinition(SCA_COMPOSITE_BEAN_NAME)) { + throw new IllegalArgumentException( + "At most one <sca:composite> element can be declared in a bean factory"); + } + BeanDefinition beanDef = createScaCompositeBeanDefinition(element); + registry.registerBeanDefinition(SCA_COMPOSITE_BEAN_NAME, beanDef); + return beanDef; + } + + private BeanDefinition createScaCompositeBeanDefinition(Element element) { + RootBeanDefinition beanDefinition = new RootBeanDefinition(); + beanDefinition.setBeanClass(ScaComposite.class); + MutablePropertyValues props = new MutablePropertyValues(); + props.addPropertyValue(MODULE_ID, element.getAttribute(MODULE_ATTRIBUTE_NAME)); + if (element.hasAttribute(ADAPTER_ATTRIBUTE)) { + props.addPropertyValue(ADAPTER_CLASS_PROPERTY, element.getAttribute(ADAPTER_ATTRIBUTE)); + } + beanDefinition.setPropertyValues(props); + return beanDefinition; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaContextBuilder.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaContextBuilder.java new file mode 100644 index 0000000000..3446aaf462 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaContextBuilder.java @@ -0,0 +1,68 @@ +/* + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca.config; + +import org.springframework.beans.PropertyValue; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.sca.ScaAdapter; +import org.springframework.sca.ScaComposite; + +/** + * @author Hal Hildebrand Date: Apr 11, 2006 Time: 4:33:33 PM + */ +public class ScaContextBuilder { + private static final String MODULE_ID = "moduleId"; + + private static final String SCA_ADAPTER = "scaAdapter"; + + private static final String SCA_COMPOSITE_BEAN_NAME = "scaComposite"; + + private String moduleId; + + private ScaAdapter scaAdapter; + + public String getModuleId() { + return this.moduleId; + } + + public void setModuleId(String moduleId) { + this.moduleId = moduleId; + } + + public void setScaAdapter(ScaAdapter scaAdapter) { + this.scaAdapter = scaAdapter; + } + + public ScaAdapter getScaAdapter() { + return this.scaAdapter; + } + + public ApplicationContext construct() { + GenericApplicationContext parent = new GenericApplicationContext(); + BeanDefinition bd = new RootBeanDefinition(ScaComposite.class, true); + + bd.getPropertyValues().addPropertyValue(new PropertyValue(MODULE_ID, moduleId)); + bd.getPropertyValues().addPropertyValue(new PropertyValue(SCA_ADAPTER, scaAdapter)); + parent.registerBeanDefinition(SCA_COMPOSITE_BEAN_NAME, bd); + parent.refresh(); + return parent; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaNamespaceHandler.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaNamespaceHandler.java new file mode 100644 index 0000000000..878267813a --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaNamespaceHandler.java @@ -0,0 +1,44 @@ +/* + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca.config; + +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + +/** + * Handler for the <sca:> namespace. Handles: <ul> <li><sca:composite module="xxxxx"/></li> + * <li><sca:reference name="xxx" type="yyy" default-service="zzz"/></li> <li><sca:property name="xxx" + * type="yyy"/></li> <li><sca:service name="xxx" type="yyyy" target="zzz"/> </ul> + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaNamespaceHandler extends NamespaceHandlerSupport { + + public ScaNamespaceHandler() { + // FIXME JFM + init(); + } + + public final void init() { + registerBeanDefinitionParser("composite", new ScaCompositeBeanDefinitionParser()); + registerBeanDefinitionParser("reference", new ScaReferenceBeanDefinitionParser()); + registerBeanDefinitionParser("property", new ScaPropertyBeanDefinitionParser()); + registerBeanDefinitionParser("service", new ScaServiceBeanDefinitionParser()); + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaPropertyBeanDefinitionParser.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaPropertyBeanDefinitionParser.java new file mode 100644 index 0000000000..55413b69da --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaPropertyBeanDefinitionParser.java @@ -0,0 +1,63 @@ +/* + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca.config; + +import org.w3c.dom.Element; + +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.sca.ScaPropertyProxyFactoryBean; + +/** + * Parser for the <sca:property/> element + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaPropertyBeanDefinitionParser implements BeanDefinitionParser { + + private static final String PROPERTY_NAME_ATTRIBUTE = "name"; + private static final String PROPERTY_NAME_PROPERTY = "propertyName"; + private static final String PROPERTY_TYPE_PROPERTY = "propertyType"; + private static final String TYPE_ATTRIBUTE = "type"; + private static final String ID_ATTRIBUTE = "id"; + + public BeanDefinition parse(Element element, ParserContext parserContext) { + // needs service type, reference name, sca component, and optionally default service name + BeanDefinitionRegistry registry = parserContext.getRegistry(); + String beanName = element.getAttribute(ID_ATTRIBUTE); + BeanDefinition beanDef = createBeanDefinition(element); + registry.registerBeanDefinition(beanName, beanDef); + return beanDef; + } + + private BeanDefinition createBeanDefinition(Element element) { + RootBeanDefinition beanDefinition = new RootBeanDefinition(); + beanDefinition.setBeanClass(ScaPropertyProxyFactoryBean.class); + MutablePropertyValues props = new MutablePropertyValues(); + props.addPropertyValue(PROPERTY_NAME_PROPERTY, element.getAttribute(PROPERTY_NAME_ATTRIBUTE)); + props.addPropertyValue(PROPERTY_TYPE_PROPERTY, element.getAttribute(TYPE_ATTRIBUTE)); + beanDefinition.setPropertyValues(props); + return beanDefinition; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaReferenceBeanDefinitionParser.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaReferenceBeanDefinitionParser.java new file mode 100644 index 0000000000..4f4d196571 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaReferenceBeanDefinitionParser.java @@ -0,0 +1,66 @@ +/* + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca.config; + +import org.w3c.dom.Element; + +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.sca.ScaServiceProxyFactoryBean; + +/** + * Parser for the <sca:reference> element + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaReferenceBeanDefinitionParser implements BeanDefinitionParser { + + private static final String REFERENCE_NAME_ATTRIBUTE = "name"; + private static final String REFERENCE_NAME_PROPERTY = "referenceName"; + private static final String TYPE_ATTRIBUTE = "type"; + private static final String SERVICE_TYPE_PROPERTY = "serviceType"; + private static final String DEFAULT_SERVICE_ATTRIBUTE = "default"; + private static final String DEFAULT_SERVICE_PROPERTY = "defaultServiceName"; + + public BeanDefinition parse(Element element, ParserContext parserContext) { + // needs service type, reference name, sca component, and optionally default service name + BeanDefinitionRegistry registry = parserContext.getRegistry(); + String referenceName = element.getAttribute(REFERENCE_NAME_ATTRIBUTE); + BeanDefinition beanDef = createBeanDefinition(element); + registry.registerBeanDefinition(referenceName, beanDef); + return beanDef; + } + + private BeanDefinition createBeanDefinition(Element element) { + RootBeanDefinition beanDefinition = new RootBeanDefinition(); + beanDefinition.setBeanClass(ScaServiceProxyFactoryBean.class); + MutablePropertyValues props = new MutablePropertyValues(); + props.addPropertyValue(REFERENCE_NAME_PROPERTY, element.getAttribute(REFERENCE_NAME_ATTRIBUTE)); + props.addPropertyValue(SERVICE_TYPE_PROPERTY, element.getAttribute(TYPE_ATTRIBUTE)); + if (element.hasAttribute(DEFAULT_SERVICE_ATTRIBUTE)) { + props.addPropertyValue(DEFAULT_SERVICE_PROPERTY, element.getAttribute(DEFAULT_SERVICE_ATTRIBUTE)); + } + beanDefinition.setPropertyValues(props); + return beanDefinition; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaServiceBeanDefinitionParser.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaServiceBeanDefinitionParser.java new file mode 100644 index 0000000000..5867236faa --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaServiceBeanDefinitionParser.java @@ -0,0 +1,65 @@ +/* + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca.config; + +import org.w3c.dom.Element; + +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.sca.ScaServiceExporter; + +/** + * Parser for the <sca:service/> element + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaServiceBeanDefinitionParser implements BeanDefinitionParser { + + private static final String SERVICE_NAME_ATTRIBUTE = "name"; + private static final String TYPE_ATTRIBUTE = "type"; + private static final String TARGET_ATTRIBUTE = "target"; + private static final String SERVICE_NAME_PROPERTY = "serviceName"; + private static final String SERVICE_TYPE_PROPERTY = "serviceType"; + private static final String TARGET_PROPERTY = "target"; + + public BeanDefinition parse(Element element, ParserContext parserContext) { + BeanDefinitionRegistry registry = parserContext.getRegistry(); + String serviceName = element.getAttribute(SERVICE_NAME_ATTRIBUTE); + BeanDefinition beanDef = createBeanDefinition(element); + registry.registerBeanDefinition(serviceName, beanDef); + return beanDef; + } + + private BeanDefinition createBeanDefinition(Element element) { + RootBeanDefinition beanDefinition = new RootBeanDefinition(); + beanDefinition.setBeanClass(ScaServiceExporter.class); + MutablePropertyValues props = new MutablePropertyValues(); + props.addPropertyValue(SERVICE_TYPE_PROPERTY, element.getAttribute(TYPE_ATTRIBUTE)); + props.addPropertyValue(TARGET_PROPERTY, new RuntimeBeanReference(element.getAttribute(TARGET_ATTRIBUTE))); + props.addPropertyValue(SERVICE_NAME_PROPERTY, element.getAttribute(SERVICE_NAME_ATTRIBUTE)); + beanDefinition.setPropertyValues(props); + return beanDefinition; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/intercept/OneWayAdvisor.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/intercept/OneWayAdvisor.java new file mode 100644 index 0000000000..60bf2a344d --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/intercept/OneWayAdvisor.java @@ -0,0 +1,82 @@ +/* + * 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.springframework.sca.intercept; + +import java.lang.reflect.Method; + +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; +import org.springframework.aop.framework.ReflectiveMethodInvocation; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.aop.support.StaticMethodMatcherPointcut; +import org.springframework.core.task.TaskExecutor; +import org.springframework.sca.metadata.ServiceMetadata; + +/** + * An AOP Alliance MethodInterceptor, rather than AspectJ aspect, as there's no value in typed pointcuts. Oh, if it were + * only annotations... + * + * @author Rod Johnson + */ + +public class OneWayAdvisor extends DefaultPointcutAdvisor { + + private TaskExecutor taskExecutor; + + private final ServiceMetadata smd; + + public OneWayAdvisor(final ServiceMetadata aSmd, TaskExecutor taskExecutor) { + this.smd = aSmd; + setPointcut(new StaticMethodMatcherPointcut() { + public boolean matches(Method method, Class targetClass) { + for (Method m : smd.getOneWayMethods()) { + if (m.getName().equals(method.getName())) { + return true; + } + } + return false; + } + }); + setAdvice(new OneWayInterceptor()); + this.taskExecutor = taskExecutor; + } + + + private class OneWayInterceptor implements MethodInterceptor { + public Object invoke(MethodInvocation mi) throws Throwable { + try { + // TODO this is not right + ReflectiveMethodInvocation rmi = (ReflectiveMethodInvocation) mi; + final MethodInvocation clone = rmi.invocableClone(); + System.out.println("EXECUTE DEFERRED"); + taskExecutor.execute(new Runnable() { + public void run() { + try { + clone.proceed(); + } catch (Throwable ex) { + // TODO + throw new UnsupportedOperationException(); + } + } + }); + } catch (Throwable t) { + t.printStackTrace(); + } + return null; + } + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/AnnotationServiceMetadata.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/AnnotationServiceMetadata.java new file mode 100644 index 0000000000..9a04831ab8 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/AnnotationServiceMetadata.java @@ -0,0 +1,95 @@ +/* + * 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.springframework.sca.metadata; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.List; + +import org.osoa.sca.annotations.ComponentName; +import org.osoa.sca.annotations.OneWay; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Service; + +import org.springframework.util.ReflectionUtils; + +/** + * TODO not the way to get this + * + * @author Rod Johnson + */ +public class AnnotationServiceMetadata implements ServiceMetadata { + + private final String name; + + private final Class<?> serviceClass; + + public AnnotationServiceMetadata(String name, Class<?> serviceClass) throws NoSuchServiceException { + if (!serviceClass.isAnnotationPresent(Service.class)) { + throw new NoSuchServiceException(); + } + this.name = name; + this.serviceClass = serviceClass; + } + + public String getServiceName() { + return name; + } + + public Class<?>[] getServiceInterfaces() { + return serviceClass.getAnnotation(Service.class).interfaces(); + } + + public List<Method> getOneWayMethods() { + List<Method> oneWayMethods = new LinkedList<Method>(); + for (Method m : serviceClass.getMethods()) { + if (m.isAnnotationPresent(OneWay.class)) { + oneWayMethods.add(m); + } + } + + // TODO fields + + return oneWayMethods; + } + + public List<Injection> getInjections() { + final List<Injection> injections = new LinkedList<Injection>(); + for (Method m : serviceClass.getMethods()) { + if (m.isAnnotationPresent(Property.class)) { + injections.add(new MethodInjection(m)); + } + } + + // TODO fields propertly + + ReflectionUtils.doWithFields(serviceClass, new ReflectionUtils.FieldCallback() { + public void doWith(Field f) throws IllegalArgumentException { + if (f.isAnnotationPresent(ComponentName.class)) { + Injection componentNameInjection = new FieldInjection(f); + componentNameInjection.setLiteralValue(name); + injections.add(componentNameInjection); + } + } + }); + + return injections; + } + + // TODO reference + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/BeanFactoryDeploymentMetadata.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/BeanFactoryDeploymentMetadata.java new file mode 100644 index 0000000000..b819ad8f8d --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/BeanFactoryDeploymentMetadata.java @@ -0,0 +1,55 @@ +/* + * 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.springframework.sca.metadata; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; + +/** + * DeploymentMetadata implementation backed by Spring BeanFactory metadata + * + * @author Rod Johnson + */ +public class BeanFactoryDeploymentMetadata implements BeanFactoryAware, DeploymentMetadata { + + private BeanFactory beanFactory; + + private Map<String, ServiceMetadata> serviceNameToMetadataMap = new HashMap<String, ServiceMetadata>(); + + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = beanFactory; + } + + + /* (non-Javadoc) + * @see org.springframework.sca.metadata.DeploymentMetadata#getServiceMetadata(java.lang.String) + */ + public synchronized ServiceMetadata getServiceMetadata(String serviceName) throws NoSuchServiceException { + ServiceMetadata sm = serviceNameToMetadataMap.get(serviceName); + if (sm == null) { + Class clazz = beanFactory.getType(serviceName); + sm = new AnnotationServiceMetadata(serviceName, clazz); + serviceNameToMetadataMap.put(serviceName, sm); + } + return sm; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/DeploymentMetadata.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/DeploymentMetadata.java new file mode 100644 index 0000000000..950e5e3786 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/DeploymentMetadata.java @@ -0,0 +1,28 @@ +/* + * 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.springframework.sca.metadata; + +/** + * Source of ServiceMetadata by name + * + * @author Rod Johnson + */ +public interface DeploymentMetadata { + + ServiceMetadata getServiceMetadata(String serviceName) throws NoSuchServiceException; + +}
\ No newline at end of file diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/FieldInjection.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/FieldInjection.java new file mode 100644 index 0000000000..3d9f1b6e79 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/FieldInjection.java @@ -0,0 +1,68 @@ +/* + * 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.springframework.sca.metadata; + +import java.lang.reflect.Field; + +import org.osoa.sca.annotations.Reference; + +/** + * @author Rod Johnson + */ +public class FieldInjection extends Injection { + + private final Field field; + + public FieldInjection(Field field, String lookupName) { + super(lookupName); + this.field = field; + } + + public FieldInjection(Field field) { + Reference annotation = field.getAnnotation(Reference.class); + + this.field = field; + + if (annotation == null) { + //throw new IllegalArgumentException("Field " + field + " not annotated"); + return; + } + + if ("".equals(annotation.name())) { + setLookupName(field.getName()); + } else { + setLookupName(annotation.name()); + } + } + + @Override + protected void injectValue(Object target, Object value) { + try { + if (!field.isAccessible()) { + field.setAccessible(true); + } + field.set(target, value); + } catch (IllegalArgumentException ex) { + // TODO + throw new UnsupportedOperationException(); + } catch (IllegalAccessException ex) { + // TODO + ex.printStackTrace(); + throw new UnsupportedOperationException(); + } + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/Injection.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/Injection.java new file mode 100644 index 0000000000..2e81516d56 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/Injection.java @@ -0,0 +1,76 @@ +/* + * 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.springframework.sca.metadata; + +import org.springframework.beans.factory.BeanFactory; + +/** + * @author Rod Johnson + */ +public abstract class Injection { + + private String lookupName; + + /** + * Is it a literal value? + */ + private boolean literal; + + /** + * Literal value if it's a literal + */ + private Object literalValue; + + protected Injection() { + + } + + protected Injection(String lookupName) { + this.lookupName = lookupName; + } + + public Object getLiteralValue() { + return literalValue; + } + + public void setLiteralValue(Object literalValue) { + this.literal = true; + this.literalValue = literalValue; + } + + public boolean isLiteral() { + return literal; + } + + protected void setLookupName(String lookupName) { + this.lookupName = lookupName; + } + + public String getLookupName() { + return lookupName; + } + + public void apply(BeanFactory owner, Object target) { + Object value = literalValue; + if (!isLiteral()) { + value = owner.getBean(lookupName); + } + injectValue(target, value); + } + + protected abstract void injectValue(Object target, Object value); + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/MethodInjection.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/MethodInjection.java new file mode 100644 index 0000000000..df01d1428d --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/MethodInjection.java @@ -0,0 +1,65 @@ +/* + * 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.springframework.sca.metadata; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.osoa.sca.annotations.Property; + +/** + * @author Rod Johnson + */ +public class MethodInjection extends Injection { + + private final Method method; + + public MethodInjection(Method method, String lookupName) { + super(lookupName); + this.method = method; + } + + public MethodInjection(Method method) { + // TODO reference also + Property annotation = method.getAnnotation(Property.class); + if (annotation == null) { + throw new IllegalArgumentException("Method " + method + " not annotated"); + } + this.method = method; + if ("".equals(annotation.name())) { + setLookupName(method.getName()); + } else { + setLookupName(annotation.name()); + } + } + + @Override + protected void injectValue(Object target, Object value) { + try { + method.invoke(target, value); + } catch (IllegalArgumentException ex) { + // TODO + throw new UnsupportedOperationException(); + } catch (IllegalAccessException ex) { + // TODO + throw new UnsupportedOperationException(); + } catch (InvocationTargetException ex) { + // TODO + throw new UnsupportedOperationException(); + } + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/NoSuchServiceException.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/NoSuchServiceException.java new file mode 100644 index 0000000000..b7ffdfeee6 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/NoSuchServiceException.java @@ -0,0 +1,24 @@ +/* + * 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.springframework.sca.metadata; + +/** + * @author Rod Johnson + */ +public class NoSuchServiceException extends Exception { + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/ServiceMetadata.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/ServiceMetadata.java new file mode 100644 index 0000000000..5d23c499e4 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/ServiceMetadata.java @@ -0,0 +1,56 @@ +/* + * 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.springframework.sca.metadata; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * Metadata for an SCA component. + * + * @author Rod Johnson + */ +public interface ServiceMetadata { + + /** + * Return the service name + * + * @return the service name of the component + */ + String getServiceName(); + + /** + * Return the service interfaces implemented by the component + * + * @return interfaces implemented by the component + */ + Class<?>[] getServiceInterfaces(); + + /** + * Return a list of OneWay methods + * + * @return never returns null + */ + List<Method> getOneWayMethods(); + + /** + * Return a list of SCA injections + * @return a list of SCA injections. Never returns null. + */ + List<Injection> getInjections(); + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/resources/META-INF/sca/spring.system.scdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/resources/META-INF/sca/spring.system.scdl new file mode 100644 index 0000000000..cbd7138f0d --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/resources/META-INF/sca/spring.system.scdl @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. + --> +<!-- + Spring implementation extension configuration for the launcher environment. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://incubator.apache.org/tuscany/xmlns/system/1.0-incubator-M2" + + name="org.apache.tuscany.launcher.SpringImplementation"> + + <component name="spring.implementationLoader"> + <system:implementation.system class="org.apache.tuscany.container.spring.impl.SpringImplementationLoader"/> + </component> + + <component name="spring.componentTypeLoader"> + <system:implementation.system class="org.apache.tuscany.container.spring.impl.SpringComponentTypeLoader"/> + </component> + + <component name="spring.componentBuilder"> + <system:implementation.system class="org.apache.tuscany.container.spring.impl.SpringCompositeBuilder"/> + </component> + +</composite>
\ No newline at end of file diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/resources/META-INF/spring.handlers b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/resources/META-INF/spring.handlers new file mode 100644 index 0000000000..689b49e2ae --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/resources/META-INF/spring.handlers @@ -0,0 +1,3 @@ +http\://www.springframework.org/schema/sca=org.springframework.sca.config.ScaNamespaceHandler + + diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/resources/META-INF/spring.schemas b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/resources/META-INF/spring.schemas new file mode 100644 index 0000000000..33f7004be9 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/resources/META-INF/spring.schemas @@ -0,0 +1 @@ +http\://www.springframework.org/schema/sca/spring-sca.xsd=org/springframework/sca/xml/spring-sca.xsd diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/resources/org/springframework/sca/xml/spring-sca.xsd b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/resources/org/springframework/sca/xml/spring-sca.xsd new file mode 100644 index 0000000000..b4eeadbb74 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/main/resources/org/springframework/sca/xml/spring-sca.xsd @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<xsd:schema xmlns="http://www.springframework.org/schema/sca" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + attributeFormDefault="unqualified" + elementFormDefault="qualified" + targetNamespace="http://www.springframework.org/schema/sca"> + + <xsd:element name="composite"> + <xsd:complexType> + <xsd:attribute name="component" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="sca-adapter-class" use="optional"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + </xsd:attribute> + </xsd:complexType> + </xsd:element> + + <xsd:element name="reference"> + <xsd:complexType> + <xsd:attribute name="name" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="type" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="default" use="optional"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + </xsd:attribute> + </xsd:complexType> + </xsd:element> + + <xsd:element name="property"> + <xsd:complexType> + <xsd:attribute name="id" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="name" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="type" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + </xsd:attribute> + </xsd:complexType> + </xsd:element> + + <xsd:element name="service"> + <xsd:complexType> + <xsd:attribute name="name" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="type" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="target" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"/> + </xsd:simpleType> + </xsd:attribute> + </xsd:complexType> + </xsd:element> + +</xsd:schema> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/SpringConfigSchemaTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/SpringConfigSchemaTestCase.java new file mode 100644 index 0000000000..80b22d6784 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/SpringConfigSchemaTestCase.java @@ -0,0 +1,58 @@ +/* + * 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.container.spring; + +import junit.framework.TestCase; +import org.apache.tuscany.container.spring.config.ScaApplicationContext; +import org.apache.tuscany.container.spring.mock.TestReference; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.io.ClassPathResource; +import org.springframework.sca.ScaServiceExporter; +import org.springframework.sca.ScaServiceProxyFactoryBean; + +/** + * Tests the SCA extensible schema elements for Spring's XML configuration files + * + * @version $$Rev$$ $$Date$$ + */ + +public class SpringConfigSchemaTestCase extends TestCase { + + private ConfigurableApplicationContext applicationContext; + + public void setUp() { + applicationContext = + new ScaApplicationContext(null, + new ClassPathResource("org/apache/tuscany/container/spring/SpringConfigSchemaTest.xml"), null); + } + + public void testSCAService() { + ScaServiceExporter service = (ScaServiceExporter) applicationContext.getBean("fooService"); + // FIXME andyp -- this is not really right. +// TestBean service = (TestBean) applicationContext.getBean("fooService"); +// assertEquals("call me", service.echo("call me")); + } + + public void testSCAReference() { + ScaServiceProxyFactoryBean pf = (ScaServiceProxyFactoryBean) applicationContext.getBean("&fooReference"); + assertEquals("fooReference", pf.getReferenceName()); + TestReference ref = (TestReference) applicationContext.getBean("fooReference"); +// assertNotNull(ref); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/SpringTestUtils.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/SpringTestUtils.java new file mode 100644 index 0000000000..3d07c753de --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/SpringTestUtils.java @@ -0,0 +1,70 @@ +/* + * 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.container.spring; + +import org.apache.tuscany.spi.QualifiedName; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.extension.ServiceExtension; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.WireService; + +import org.apache.tuscany.container.spring.mock.TestBeanImpl; +import org.apache.tuscany.test.ArtifactFactory; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.context.support.GenericApplicationContext; + +/** + * @version $$Rev$$ $$Date$$ + */ + +public final class SpringTestUtils { + private SpringTestUtils() { + } + + public static <T> Service createService(String name, + Class<T> serviceInterface, + CompositeComponent parent, + WireService wireService) throws InvalidServiceContractException { + Service service = new ServiceExtension(name, serviceInterface, parent, wireService); + InboundWire inboundWire = ArtifactFactory.createInboundWire(name, serviceInterface); + OutboundWire outboundWire = ArtifactFactory.createOutboundWire(name, serviceInterface); + ArtifactFactory.terminateWire(outboundWire); + service.setInboundWire(inboundWire); + service.setOutboundWire(outboundWire); + outboundWire.setTargetName(new QualifiedName("foo")); + Connector connector = ArtifactFactory.createConnector(); + connector.connect(service); + ArtifactFactory.terminateWire(inboundWire); + return service; + } + + + public static GenericApplicationContext createContext() { + GenericApplicationContext ctx = new GenericApplicationContext(); + BeanDefinition definition = new RootBeanDefinition(TestBeanImpl.class); + ctx.registerBeanDefinition("foo", definition); + return ctx; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/ReferenceInvocationTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/ReferenceInvocationTestCase.java new file mode 100644 index 0000000000..ff5a564ee8 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/ReferenceInvocationTestCase.java @@ -0,0 +1,68 @@ +/* + * 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.container.spring.impl; + +import org.apache.tuscany.spi.component.Reference; + +import junit.framework.TestCase; +import org.apache.tuscany.container.spring.mock.TestBean; +import org.apache.tuscany.container.spring.mock.TestBeanImpl; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import org.springframework.beans.PropertyValue; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.StaticApplicationContext; + +/** + * Verifies wiring from a Spring bean to an SCA composite reference + * + * @version $$Rev$$ $$Date$$ + */ +public class ReferenceInvocationTestCase extends TestCase { + + public void testInvocation() throws Exception { + AbstractApplicationContext ctx = createSpringContext(); + SpringCompositeComponent parent = new SpringCompositeComponent("spring", ctx, null, null, null); + parent.start(); + TestBean referenceTarget = new TestBeanImpl(); + Reference reference = createMock(Reference.class); + expect(reference.getName()).andReturn("bar").anyTimes(); + expect(reference.isSystem()).andReturn(false).atLeastOnce(); + expect(reference.getInterface()).andStubReturn(TestBean.class); + expect(reference.getServiceInstance()).andStubReturn(referenceTarget); + replay(reference); + parent.register(reference); + ctx.getBean("foo"); + } + + private AbstractApplicationContext createSpringContext() { + StaticApplicationContext beanFactory = new StaticApplicationContext(); + RootBeanDefinition definition = new RootBeanDefinition(TestBeanImpl.class); + //REVIEW we need to figure out how to handle eager init components + definition.setLazyInit(true); + RuntimeBeanReference ref = new RuntimeBeanReference("bar"); + PropertyValue val = new PropertyValue("bean", ref); + definition.getPropertyValues().addPropertyValue(val); + beanFactory.registerBeanDefinition("foo", definition); + return beanFactory; + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/ServiceInvocationTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/ServiceInvocationTestCase.java new file mode 100644 index 0000000000..596d9f1181 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/ServiceInvocationTestCase.java @@ -0,0 +1,76 @@ +/* + * 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.container.spring.impl; + +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.extension.ServiceExtension; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.wire.InboundInvocationChain; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.QualifiedName; + +import junit.framework.TestCase; +import org.apache.tuscany.container.spring.mock.TestBean; +import org.apache.tuscany.container.spring.mock.TestBeanImpl; +import org.apache.tuscany.test.ArtifactFactory; +import static org.apache.tuscany.test.ArtifactFactory.createWireService; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.StaticApplicationContext; + +/** + * Tests a simple invocation through a service to a Spring bean + * + * @version $$Rev$$ $$Date$$ + */ +public class ServiceInvocationTestCase extends TestCase { + + public void testInvocation() throws InvalidServiceContractException { + AbstractApplicationContext springContext = createSpringContext(); + SpringCompositeComponent composite = new SpringCompositeComponent("parent", springContext, null, null, null); + InboundWire inboundWire = ArtifactFactory.createInboundWire("fooService", TestBean.class); + OutboundWire outboundWire = ArtifactFactory.createOutboundWire("fooService", TestBean.class); + outboundWire.setTargetName(new QualifiedName("foo")); + ArtifactFactory.terminateWire(outboundWire); + Service service = + new ServiceExtension("fooService", TestBean.class, composite, createWireService()); + service.setInboundWire(inboundWire); + service.setOutboundWire(outboundWire); + Connector connector = ArtifactFactory.createConnector(); + connector.connect(inboundWire, outboundWire, true); + for (InboundInvocationChain chain : inboundWire.getInvocationChains().values()) { + chain.setTargetInvoker(composite.createTargetInvoker("foo", chain.getOperation())); + } + composite.register(service); + TestBean serviceInstance = (TestBean) composite.getService("fooService").getServiceInstance(); + assertEquals("bar", serviceInstance.echo("bar")); + } + + + private AbstractApplicationContext createSpringContext() { + StaticApplicationContext beanFactory = new StaticApplicationContext(); + RootBeanDefinition definition = new RootBeanDefinition(TestBeanImpl.class); + definition.setLazyInit(true); + beanFactory.registerBeanDefinition("foo", definition); + return beanFactory; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/SpringCompositeBuilderTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/SpringCompositeBuilderTestCase.java new file mode 100644 index 0000000000..50ce9a7b75 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/SpringCompositeBuilderTestCase.java @@ -0,0 +1,137 @@ +/* + * 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.container.spring.impl; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.tuscany.spi.builder.BuilderRegistry; +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ServiceExtension; +import org.apache.tuscany.spi.model.BoundServiceDefinition; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.WireService; + +import junit.framework.TestCase; +import static org.apache.tuscany.container.spring.SpringTestUtils.createContext; +import org.apache.tuscany.container.spring.mock.TestBean; +import org.apache.tuscany.container.spring.model.SpringComponentType; +import org.apache.tuscany.container.spring.model.SpringImplementation; +import org.apache.tuscany.test.ArtifactFactory; +import org.apache.tuscany.test.binding.TestBinding; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createNiceMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class SpringCompositeBuilderTestCase extends TestCase { + + /** + * Verfies basic build of a spring context + */ + @SuppressWarnings("unchecked") + public void testBuild() throws Exception { + // Create an assembly model consisting of a component implemented by Spring + SpringImplementation impl = new SpringImplementation(new SpringComponentType(createContext())); + ComponentDefinition<SpringImplementation> componentDefinition = + new ComponentDefinition<SpringImplementation>("spring", impl); + + // Configure the mock builder registry + BuilderRegistry registry = createNiceMock(BuilderRegistry.class); + + // Test the SpringCompositeBuilder + SpringCompositeBuilder builder = new SpringCompositeBuilder(); + builder.setBuilderRegistry(registry); + CompositeComponent parent = createNiceMock(CompositeComponent.class); + DeploymentContext context = createNiceMock(DeploymentContext.class); + SpringCompositeComponent component = + (SpringCompositeComponent) builder.build(parent, componentDefinition, context); + TestBean bean = (TestBean) component.getApplicationContext().getBean("foo"); + assertEquals("call foo", bean.echo("call foo")); + } + + /** + * Verifies that the builder calls back into the registry to load services and wires them to bean targets when no + * <code>sca:service</code> tag is specified in the Spring application.xml + */ + @SuppressWarnings("unchecked") + public void testImplicitServiceWiring() throws Exception { + // Create an assembly model consisting of a component implemented by Spring + SpringImplementation impl = new SpringImplementation(createComponentType()); + ComponentDefinition<SpringImplementation> componentDefinition = + new ComponentDefinition<SpringImplementation>("spring", impl); + + // Create a service instance that the mock builder registry will return + WireService wireService = ArtifactFactory.createWireService(); + ServiceExtension serviceContext = + new ServiceExtension("fooService", TestBean.class, null, wireService); + InboundWire inboundWire = ArtifactFactory.createInboundWire("fooService", TestBean.class); + OutboundWire outboundWire = ArtifactFactory.createOutboundWire("fooService", TestBean.class); + ArtifactFactory.terminateWire(outboundWire); + serviceContext.setInboundWire(inboundWire); + serviceContext.setOutboundWire(outboundWire); + Connector connector = ArtifactFactory.createConnector(); + connector.connect(inboundWire, outboundWire, true); + + // Configure the mock builder registry + BuilderRegistry registry = createMock(BuilderRegistry.class); + expect(registry.build(isA(CompositeComponent.class), + isA(BoundServiceDefinition.class), + isA(DeploymentContext.class))).andStubReturn(serviceContext); + replay(registry); + + // Test the SpringCompositeBuilder + SpringCompositeBuilder builder = new SpringCompositeBuilder(); + builder.setWireService(wireService); + builder.setBuilderRegistry(registry); + CompositeComponent parent = createNiceMock(CompositeComponent.class); + DeploymentContext context = createNiceMock(DeploymentContext.class); + CompositeComponent component = (CompositeComponent) builder.build(parent, componentDefinition, context); + Service service = component.getService("fooService"); + TestBean bean = (TestBean) service.getServiceInstance(); + assertEquals("call foo", bean.echo("call foo")); + verify(registry); + } + + @SuppressWarnings("unchecked") + private SpringComponentType createComponentType() { + SpringComponentType componentType = new SpringComponentType(createContext()); + BoundServiceDefinition<TestBinding> serviceDefinition = new BoundServiceDefinition<TestBinding>(); + serviceDefinition.setName("fooService"); + serviceDefinition.setBinding(new TestBinding()); + try { + serviceDefinition.setTarget(new URI("foo")); + } catch (URISyntaxException e) { + throw new AssertionError(); + } + componentType.add(serviceDefinition); + return componentType; + } + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/SpringCompositeComponentTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/SpringCompositeComponentTestCase.java new file mode 100644 index 0000000000..f3ac13d030 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/SpringCompositeComponentTestCase.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.container.spring.impl; + +import org.apache.tuscany.spi.component.Service; + +import junit.framework.TestCase; +import static org.easymock.EasyMock.expect; +import org.easymock.classextension.EasyMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.AbstractApplicationContext; + +/** + * @version $Rev$ $Date$ + */ +public class SpringCompositeComponentTestCase extends TestCase { + + public void testAppContextStart() { + AbstractApplicationContext appContext = EasyMock.createMock(AbstractApplicationContext.class); + appContext.refresh(); + appContext.setParent(EasyMock.isA(ApplicationContext.class)); + appContext.start(); + replay(appContext); + SpringCompositeComponent component = new SpringCompositeComponent("spring", appContext, null, null, null); + component.start(); + verify(appContext); + } + + public void testChildStart() { + AbstractApplicationContext appContext = EasyMock.createNiceMock(AbstractApplicationContext.class); + replay(appContext); + Service service = EasyMock.createMock(Service.class); + EasyMock.expect(service.getName()).andReturn("foo").anyTimes(); + service.start(); + service.getInterface(); + EasyMock.expectLastCall().andReturn(Object.class); + expect(service.isSystem()).andReturn(false).atLeastOnce(); + replay(service); + SpringCompositeComponent component = new SpringCompositeComponent("spring", appContext, null, null, null); + component.register(service); + component.start(); + verify(service); + } + + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/SpringInvocationTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/SpringInvocationTestCase.java new file mode 100644 index 0000000000..b110852a54 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/impl/SpringInvocationTestCase.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.container.spring.impl; + +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; + +import junit.framework.TestCase; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import org.springframework.context.ApplicationContext; + +/** + * Verifies a simple invocation on a Spring bean + * + * @version $$Rev$$ $$Date$$ + */ +public class SpringInvocationTestCase extends TestCase { + + /** + * Verifies the invoker can resolve a bean in an application context and call a method l + */ + public void testInvocation() throws Exception { + TestBean bean = createMock(TestBean.class); + bean.test("bar"); + expectLastCall(); + replay(bean); + ApplicationContext context = createMock(ApplicationContext.class); + expect(context.getBean("foo")).andReturn(bean); + replay(context); + SpringInvoker invoker = new SpringInvoker("foo", TestBean.class.getMethod("test", String.class), context); + Message msg = new MessageImpl(); + msg.setBody(new String[]{"bar"}); + invoker.invoke(msg); + verify(context); + verify(bean); + } + + + private interface TestBean { + void test(String msg); + } +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/integration/BootstrapTestCase.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/integration/BootstrapTestCase.java new file mode 100644 index 0000000000..c5758cb2ac --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/integration/BootstrapTestCase.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.container.spring.integration; + +import org.osoa.sca.CompositeContext; +import org.osoa.sca.CurrentCompositeContext; + +import org.apache.tuscany.spi.component.Service; + +import org.apache.tuscany.container.spring.impl.SpringCompositeComponent; +import org.apache.tuscany.container.spring.mock.TestBean; +import org.apache.tuscany.test.Bootstrapper; + +/** + * Bootstraps a simple scenario where a service can invoke a Spring bean. This test case is intended to be temporary and + * replaced when the SPI test harness is finished. + * <p/> + * <bold>PLEASE DO NOT EMULATE</bold> + * + * @version $Rev$ $Date$ + */ +public class BootstrapTestCase extends Bootstrapper { + + private CompositeContext context; + + public void testDemoBoot() { + SpringCompositeComponent comp = (SpringCompositeComponent) component.getChild("Spring"); + Service service = (Service) comp.getChild("fooService"); + TestBean bean = (TestBean) service.getServiceInstance(); + bean.echo("foo"); + bean.getBean().echo("foo"); + } + + protected void setUp() throws Exception { + addExtension("spring.extension", getClass().getClassLoader().getResource("META-INF/sca/spring.system.scdl")); + super.setUp(); + context = CurrentCompositeContext.getContext(); + } + + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/mock/TestBean.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/mock/TestBean.java new file mode 100644 index 0000000000..1c768e53cc --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/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.container.spring.mock; + +/** + * @version $$Rev$$ $$Date$$ + */ +public interface TestBean { + String echo(String msg); + + TestBean getBean(); + + void setBean(TestBean bean); + +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/mock/TestBeanImpl.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/mock/TestBeanImpl.java new file mode 100644 index 0000000000..db04d8bcad --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/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.container.spring.mock; + +/** + * @version $$Rev$$ $$Date$$ + */ +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/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/mock/TestReference.java b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/mock/TestReference.java new file mode 100644 index 0000000000..7d1a519be6 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/java/org/apache/tuscany/container/spring/mock/TestReference.java @@ -0,0 +1,26 @@ +/* + * 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.container.spring.mock; + +/** + * @version $$Rev$$ $$Date$$ + */ +public interface TestReference { + String echo(String msg); +} diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/META-INF/sca/application-context.xml b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/META-INF/sca/application-context.xml new file mode 100644 index 0000000000..6ccd3963a9 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/META-INF/sca/application-context.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:sca="http://www.springframework.org/schema/sca" + xsi:schemaLocation=" +http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd +http://www.springframework.org/schema/sca http://www.springframework.org/schema/sca/spring-sca.xsd"> + + <bean id="testBean" class="org.apache.tuscany.container.spring.mock.TestBeanImpl" lazy-init="true"> + <property name="bean" ref="testReference"/> + </bean> + <!-- <sca:reference name="testReference" type="org.apache.tuscany.container.spring.mock.TestReference"/> --> + +</beans> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/META-INF/sca/default.scdl b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/META-INF/sca/default.scdl new file mode 100644 index 0000000000..0b2c92c667 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/META-INF/sca/default.scdl @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. + --> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + name="spring.test"> + + <component name="Spring"> + <implementation.spring location="META-INF/sca/application-context.xml"> + <service name="fooService"> + <binding.test/> + <interface.java class="org.apache.tuscany.container.spring.mock.TestBean"/> + <reference>testBean</reference> + </service> + <reference name="testReference"> + <interface.java class="org.apache.tuscany.container.spring.mock.TestBean"/> + <binding.test/> + </reference> + </implementation.spring> + </component> + +</composite> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/org/apache/tuscany/container/spring/ExplicitSpring.xml b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/org/apache/tuscany/container/spring/ExplicitSpring.xml new file mode 100644 index 0000000000..211211511b --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/org/apache/tuscany/container/spring/ExplicitSpring.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:sca="http://www.springframework.org/schema/sca" + xsi:schemaLocation=" +http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd +http://www.springframework.org/schema/sca http://www.springframework.org/schema/sca/spring-sca.xsd"> + + <sca:service name="fooBean" type="org.apache.tuscany.container.spring.mock.TestBeanImpl" target="testBean"/> + + <bean id="testBean" class="org.apache.tuscany.container.spring.mock.TestBeanImpl"> + </bean> + +</beans> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/org/apache/tuscany/container/spring/SpringConfigSchemaTest.xml b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/org/apache/tuscany/container/spring/SpringConfigSchemaTest.xml new file mode 100644 index 0000000000..96a3e1ed46 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/org/apache/tuscany/container/spring/SpringConfigSchemaTest.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:sca="http://www.springframework.org/schema/sca" + xsi:schemaLocation=" +http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd +http://www.springframework.org/schema/sca http://www.springframework.org/schema/sca/spring-sca.xsd"> + + <bean id="testBean" class="org.apache.tuscany.container.spring.mock.TestBeanImpl"> + </bean> + + <sca:service name="fooService" type="org.apache.tuscany.container.spring.mock.TestBean" target="testBean"/> + + <sca:reference name="fooReference" type="org.apache.tuscany.container.spring.mock.TestReference"/> + + +</beans> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/test.xml b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/test.xml new file mode 100644 index 0000000000..d438b88577 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/container.spring/src/test/resources/test.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:sca="http://www.springframework.org/schema/sca" + xsi:schemaLocation=" +http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd +http://www.springframework.org/schema/sca http://www.springframework.org/schema/sca/spring-sca.xsd"> + + <bean id="testBean" class="org.apache.tuscany.container.spring.mock.TestBeanImpl"/> + +</beans> diff --git a/tags/java/sca/1.0-incubator-M2/services/containers/pom.xml b/tags/java/sca/1.0-incubator-M2/services/containers/pom.xml new file mode 100644 index 0000000000..3a598bc018 --- /dev/null +++ b/tags/java/sca/1.0-incubator-M2/services/containers/pom.xml @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<project> + <parent> + <groupId>org.apache.tuscany.sca.services</groupId> + <artifactId>parent</artifactId> + <version>1.0-incubator-M2</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <groupId>org.apache.tuscany.sca.services.containers</groupId> + <artifactId>parent</artifactId> + <packaging>pom</packaging> + <name>Tuscany SCA Containers</name> + + <!-- definition of repositories where the parent pom can be found --> + <repositories> + <repository> + <id>apache.snapshots</id> + <name>Apache Snapshot Repository</name> + <url>http://people.apache.org/repo/m2-snapshot-repository</url> + <releases> + <enabled>false</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </repository> + <repository> + <id>apache.incubator</id> + <name>Apache Incubator Repository</name> + <url>http://people.apache.org/repo/m2-incubating-repository/</url> + <releases> + <enabled>true</enabled> + </releases> + <snapshots> + <enabled>false</enabled> + </snapshots> + </repository> + </repositories> + + <profiles> + <profile> + <id>full</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <modules> + <module>container.groovy</module> + <module>container.javascript</module> + <module>container.ruby</module> + <module>container.spring</module> + </modules> + </profile> + <profile> + <id>release</id> + <activation> + <activeByDefault>false</activeByDefault> + </activation> + <modules> + <module>container.javascript</module> + <module>container.ruby</module> + <module>container.spring</module> + </modules> + </profile> + </profiles> + +</project> |